Merge pull request 'feat(chatcoop): комнаты секретаря + синхронизация непроектных комнат в blago' (#34) from feat/chatcoop-secretary-rooms into dev
Reviewed-on: #34 Reviewed-by: Алексей Муравьев <chairman.voskhod@gmail.com>
This commit was merged in pull request #34.
This commit is contained in:
@@ -9,12 +9,15 @@ export interface CommunicationCursorsFile {
|
||||
messageLastTsByRoom: Record<string, number>
|
||||
/** project_hash → ISO instant: транскрипции с endedAt ≤ этого момента уже выгружены */
|
||||
transcriptionLastEndedExclusiveByProject: Record<string, string>
|
||||
/** matrixRoomId → ISO instant: транскрипции непроектной комнаты с endedAt ≤ этого момента уже выгружены */
|
||||
transcriptionLastEndedExclusiveByRoom: Record<string, string>
|
||||
}
|
||||
|
||||
function empty(): CommunicationCursorsFile {
|
||||
return {
|
||||
messageLastTsByRoom: {},
|
||||
transcriptionLastEndedExclusiveByProject: {},
|
||||
transcriptionLastEndedExclusiveByRoom: {},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +35,11 @@ export async function loadCommunicationCursors(root: string): Promise<Communicat
|
||||
&& typeof parsed.transcriptionLastEndedExclusiveByProject === 'object'
|
||||
? { ...parsed.transcriptionLastEndedExclusiveByProject }
|
||||
: {},
|
||||
transcriptionLastEndedExclusiveByRoom:
|
||||
parsed.transcriptionLastEndedExclusiveByRoom !== undefined
|
||||
&& typeof parsed.transcriptionLastEndedExclusiveByRoom === 'object'
|
||||
? { ...parsed.transcriptionLastEndedExclusiveByRoom }
|
||||
: {},
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
transcriptionMeetingFileStemUtc,
|
||||
type CommunicationDayLine,
|
||||
} from './communication-markdown.js'
|
||||
import { workspaceBasePath, type ProjectPathModel } from './layout.js'
|
||||
import { generateSlug, workspaceBasePath, type ProjectPathModel } from './layout.js'
|
||||
import { syncEntityFile } from './sync-entity-file.js'
|
||||
|
||||
interface ProjectRowLite {
|
||||
@@ -183,6 +183,19 @@ async function listRooms(ctx: AuthenticatedContext, projectHash: string) {
|
||||
return q[Queries.ChatCoop.ListProjectCommunicationRooms.name] ?? []
|
||||
}
|
||||
|
||||
/** Стабильная папка непроектной комнаты в `rooms/`. Системные — фиксированные, комнаты секретаря — slug + хвост id (уникальность). */
|
||||
function nonProjectRoomFolder(kind: string, matrixRoomId: string, displayLabel: string): string {
|
||||
if (kind === 'MEMBERS') {
|
||||
return 'komnata-paishchikov'
|
||||
}
|
||||
if (kind === 'COUNCIL') {
|
||||
return 'komnata-soveta'
|
||||
}
|
||||
const slug = generateSlug(displayLabel) || 'komnata'
|
||||
const shortId = createHash('sha256').update(matrixRoomId, 'utf8').digest('hex').slice(0, 6)
|
||||
return `${slug}-${shortId}`
|
||||
}
|
||||
|
||||
export async function pullProjectCommunicationArtifacts(
|
||||
ctx: AuthenticatedContext,
|
||||
index: IndexFile,
|
||||
@@ -422,3 +435,208 @@ export async function pullProjectCommunicationArtifacts(
|
||||
warn(`Не удалось сохранить курсоры переписки: ${formatThrownValue(e)}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull переписки и транскрипций из комнат ВНЕ проектов Capital (пайщики, совет, комнаты секретаря).
|
||||
* Раскладка — отдельная верхняя папка `rooms/<folder>/{messages,meetings}/`, чтобы не смешивать с
|
||||
* проектными `meetings/`. Логика идентична проектной, но bucket = одна комната, курсор транскрипций — по matrixRoomId.
|
||||
*/
|
||||
export async function pullNonProjectCommunicationArtifacts(
|
||||
ctx: AuthenticatedContext,
|
||||
index: IndexFile,
|
||||
): Promise<void> {
|
||||
let rooms: { matrixRoomId: string, displayLabel: string, kind: string }[]
|
||||
try {
|
||||
const q = await ctx.client.Query(Queries.ChatCoop.ListNonProjectCommunicationRooms.query, {})
|
||||
rooms = (q[Queries.ChatCoop.ListNonProjectCommunicationRooms.name] ?? []) as typeof rooms
|
||||
}
|
||||
catch (e) {
|
||||
warn(`Список непроектных комнат (chatcoopListNonProjectCommunicationRooms): ${formatThrownValue(e)}`)
|
||||
return
|
||||
}
|
||||
if (rooms.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
let cursors: CommunicationCursorsFile
|
||||
try {
|
||||
cursors = await loadCommunicationCursors(ctx.root)
|
||||
}
|
||||
catch (e) {
|
||||
warn(`Курсоры переписки (комнаты): не удалось прочитать, начинаем с пустых: ${formatThrownValue(e)}`)
|
||||
cursors = {
|
||||
messageLastTsByRoom: {},
|
||||
transcriptionLastEndedExclusiveByProject: {},
|
||||
transcriptionLastEndedExclusiveByRoom: {},
|
||||
}
|
||||
}
|
||||
|
||||
for (const room of rooms) {
|
||||
const folder = nonProjectRoomFolder(room.kind, room.matrixRoomId, room.displayLabel)
|
||||
const basePath = `rooms/${folder}`
|
||||
const roomTitle = room.displayLabel || room.matrixRoomId
|
||||
|
||||
// Сообщения комнаты — по календарным суткам UTC новее курсора.
|
||||
try {
|
||||
const last = cursors.messageLastTsByRoom[room.matrixRoomId]
|
||||
const afterTs = last ?? 0
|
||||
const datesQ = await ctx.client.Query(Queries.ChatCoop.ListUtcDatesWithNewRoomMessages.query, {
|
||||
variables: { data: { matrixRoomId: room.matrixRoomId, afterOriginServerTsExclusive: afterTs } },
|
||||
})
|
||||
const dates = (datesQ[Queries.ChatCoop.ListUtcDatesWithNewRoomMessages.name] ?? []).sort()
|
||||
for (const utcDate of dates) {
|
||||
const mq = await ctx.client.Query(Queries.ChatCoop.GetRoomMessagesForUtcDate.query, {
|
||||
variables: { data: { matrixRoomId: room.matrixRoomId, utcDate } },
|
||||
})
|
||||
const linesRaw = mq[Queries.ChatCoop.GetRoomMessagesForUtcDate.name] ?? []
|
||||
const lines: CommunicationDayLine[] = linesRaw.map(m => ({
|
||||
originServerTs: m.originServerTs,
|
||||
authorLabel: m.authorLabel,
|
||||
coopUsername: m.coopUsername,
|
||||
kind: String(m.kind),
|
||||
bodyText: m.bodyText,
|
||||
}))
|
||||
if (lines.length === 0) {
|
||||
continue
|
||||
}
|
||||
const content = projectCommunicationDayToMarkdown(roomTitle, room.matrixRoomId, utcDate, [
|
||||
{ displayLabel: room.displayLabel, matrixRoomId: room.matrixRoomId, lines },
|
||||
])
|
||||
const rel = `${basePath}/messages/${utcDate}.md`
|
||||
const entityHash = messageDayEntityHash(room.matrixRoomId, utcDate)
|
||||
await syncEntityFile({
|
||||
root: ctx.root,
|
||||
index,
|
||||
entityType: 'room_message_day',
|
||||
entityHash,
|
||||
relativePath: rel,
|
||||
content,
|
||||
remoteUpdatedAt: `${utcDate}T23:59:59.999Z`,
|
||||
label: `переписка ${utcDate} (${room.matrixRoomId})`,
|
||||
})
|
||||
}
|
||||
|
||||
const maxQ = await ctx.client.Query(Queries.ChatCoop.GetMaxOriginServerTsForRoom.query, {
|
||||
variables: { data: { matrixRoomId: room.matrixRoomId } },
|
||||
})
|
||||
const maxTs = maxQ[Queries.ChatCoop.GetMaxOriginServerTsForRoom.name] as number | null | undefined
|
||||
if (maxTs !== undefined && maxTs !== null && Number.isFinite(maxTs)) {
|
||||
cursors.messageLastTsByRoom[room.matrixRoomId] = maxTs
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
warn(`Переписка Matrix, комната ${room.matrixRoomId} (${roomTitle}): ${formatThrownValue(e)}`)
|
||||
}
|
||||
|
||||
// Транскрипции звонков комнаты + sibling memo.
|
||||
try {
|
||||
const tExIso = cursors.transcriptionLastEndedExclusiveByRoom[room.matrixRoomId]
|
||||
const lowerBoundExclusive = tExIso === undefined ? new Date(0) : new Date(tExIso)
|
||||
|
||||
interface TranscriptionCandidate {
|
||||
id: string
|
||||
endedAt: Date
|
||||
memo: string
|
||||
updatedAt: Date | undefined
|
||||
}
|
||||
const byId = new Map<string, TranscriptionCandidate>()
|
||||
const tq = await ctx.client.Query(Queries.ChatCoop.GetTranscriptions.query, {
|
||||
variables: { data: { matrixRoomId: room.matrixRoomId, limit: CHATCOOP_TRANSCRIPTIONS_QUERY_LIMIT, offset: 0 } },
|
||||
})
|
||||
const list = tq[Queries.ChatCoop.GetTranscriptions.name] ?? []
|
||||
for (const t of list) {
|
||||
const end = dateFromUnknown(t.endedAt)
|
||||
if (t.status !== Zeus.TranscriptionStatus.COMPLETED || !end) {
|
||||
continue
|
||||
}
|
||||
const prev = byId.get(t.id)
|
||||
if (!prev || end > prev.endedAt) {
|
||||
byId.set(t.id, {
|
||||
id: t.id,
|
||||
endedAt: end,
|
||||
memo: typeof t.memo === 'string' ? t.memo : '',
|
||||
updatedAt: dateFromUnknown(t.updatedAt),
|
||||
})
|
||||
}
|
||||
}
|
||||
const allCompleted = [...byId.values()].sort((a, b) => a.endedAt.getTime() - b.endedAt.getTime())
|
||||
|
||||
const newMeetings = allCompleted.filter(c => c.endedAt.getTime() > lowerBoundExclusive.getTime())
|
||||
let maxEnded: Date | null = null
|
||||
for (const c of newMeetings) {
|
||||
const packQ = await ctx.client.Query(Queries.ChatCoop.GetTranscription.query, {
|
||||
variables: { data: { id: c.id } },
|
||||
})
|
||||
const pack = packQ[Queries.ChatCoop.GetTranscription.name]
|
||||
if (!pack?.transcription || pack.transcription.status !== Zeus.TranscriptionStatus.COMPLETED) {
|
||||
continue
|
||||
}
|
||||
const tr = pack.transcription
|
||||
const startedAt: Date | string = dateFromUnknown(tr.startedAt) ?? (tr.startedAt as Date | string)
|
||||
const endedAtTr: Date | string | null | undefined
|
||||
= dateFromUnknown(tr.endedAt) ?? (tr.endedAt as Date | string | null | undefined)
|
||||
const md = renderCallTranscriptionMarkdown(
|
||||
{
|
||||
matrixRoomId: String(tr.matrixRoomId),
|
||||
roomId: String(tr.roomId),
|
||||
startedAt,
|
||||
endedAt: endedAtTr,
|
||||
},
|
||||
pack.segments.map(s => ({
|
||||
speakerName: s.speakerName,
|
||||
text: s.text,
|
||||
startOffset: s.startOffset,
|
||||
endOffset: s.endOffset,
|
||||
})),
|
||||
)
|
||||
const stem = transcriptionMeetingFileStemUtc(c.endedAt)
|
||||
const rel = `${basePath}/meetings/${stem}.md`
|
||||
const entityHash = c.id.toLowerCase()
|
||||
await syncEntityFile({
|
||||
root: ctx.root,
|
||||
index,
|
||||
entityType: 'call_transcription',
|
||||
entityHash,
|
||||
relativePath: rel,
|
||||
content: md,
|
||||
remoteUpdatedAt: toUpdatedIso(c.endedAt),
|
||||
label: `транскрипция ${c.id}`,
|
||||
})
|
||||
if (!maxEnded || c.endedAt > maxEnded) {
|
||||
maxEnded = c.endedAt
|
||||
}
|
||||
}
|
||||
|
||||
for (const c of allCompleted) {
|
||||
const stem = transcriptionMeetingFileStemUtc(c.endedAt)
|
||||
const memoRel = `${basePath}/meetings/${stem}.memo.md`
|
||||
const memoRemoteUpdatedAt = toUpdatedIso(c.updatedAt ?? c.endedAt)
|
||||
await syncTranscriptionMemoFile({
|
||||
root: ctx.root,
|
||||
index,
|
||||
transcriptionId: c.id,
|
||||
relativePath: memoRel,
|
||||
serverMemo: c.memo,
|
||||
remoteUpdatedAtIso: memoRemoteUpdatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
if (maxEnded) {
|
||||
cursors.transcriptionLastEndedExclusiveByRoom[room.matrixRoomId] = maxEnded.toISOString()
|
||||
}
|
||||
else if (tExIso === undefined) {
|
||||
cursors.transcriptionLastEndedExclusiveByRoom[room.matrixRoomId] = new Date().toISOString()
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
warn(`Транскрипции звонков, комната ${room.matrixRoomId}: ${formatThrownValue(e)}`)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await saveCommunicationCursors(ctx.root, cursors)
|
||||
}
|
||||
catch (e) {
|
||||
warn(`Не удалось сохранить курсоры переписки (комнаты): ${formatThrownValue(e)}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
storyFileRelativePath,
|
||||
workspaceBasePath,
|
||||
} from './layout.js'
|
||||
import { pullProjectCommunicationArtifacts } from './pull-communication.js'
|
||||
import { pullNonProjectCommunicationArtifacts, pullProjectCommunicationArtifacts } from './pull-communication.js'
|
||||
import { scaffoldBmadWorkspacesAfterPull } from './scaffold-bmad-workspace.js'
|
||||
import { syncEntityFile } from './sync-entity-file.js'
|
||||
import { writeWorkspaceIndexMarkdown } from './workspace-index.js'
|
||||
@@ -329,6 +329,8 @@ export async function runPull(ctx: AuthenticatedContext, options: RunPullOptions
|
||||
|
||||
await pullProjectCommunicationArtifacts(ctx, index, allProjects, projectByHash)
|
||||
|
||||
await pullNonProjectCommunicationArtifacts(ctx, index)
|
||||
|
||||
await scaffoldBmadWorkspacesAfterPull(ctx, allProjects, projectByHash)
|
||||
|
||||
await saveIndex(ctx.root, index)
|
||||
|
||||
@@ -3798,6 +3798,17 @@ type ChatCoopCalendarRoomOption {
|
||||
matrixRoomId: String!
|
||||
}
|
||||
|
||||
type ChatcoopNonProjectCommunicationRoom {
|
||||
"""Подпись для отображения комнаты"""
|
||||
displayLabel: String!
|
||||
|
||||
"""Тип комнаты (пайщики / совет / секретарь)"""
|
||||
kind: NonProjectRoomKind!
|
||||
|
||||
"""Идентификатор комнаты Matrix"""
|
||||
matrixRoomId: String!
|
||||
}
|
||||
|
||||
type ChatcoopProjectCommunicationRoom {
|
||||
"""Подпись для отображения (комната / проект Capital)"""
|
||||
displayLabel: String!
|
||||
@@ -3821,6 +3832,26 @@ type ChatcoopRoomMessageLine {
|
||||
originServerTs: Float!
|
||||
}
|
||||
|
||||
type ChatcoopSecretaryRoom {
|
||||
"""Название комнаты"""
|
||||
displayLabel: String!
|
||||
|
||||
"""Можно ли удалить комнату из интерфейса (только комнаты секретаря)"""
|
||||
editable: Boolean!
|
||||
|
||||
"""Комната зашифрована (E2EE) — секретарь не транскрибирует такие комнаты"""
|
||||
encrypted: Boolean!
|
||||
|
||||
"""Тип комнаты"""
|
||||
kind: ManagedRoomKind!
|
||||
|
||||
"""Идентификатор комнаты Matrix"""
|
||||
matrixRoomId: String!
|
||||
|
||||
"""Секретарь присутствует в комнате"""
|
||||
secretaryInRoom: Boolean!
|
||||
}
|
||||
|
||||
input CheckMatrixUsernameInput {
|
||||
username: String!
|
||||
}
|
||||
@@ -4888,6 +4919,16 @@ input CreateProjectPropertyInput {
|
||||
username: String!
|
||||
}
|
||||
|
||||
input CreateSecretaryRoomInput {
|
||||
"""Название комнаты"""
|
||||
displayName: String!
|
||||
|
||||
"""
|
||||
Публичная комната (любой может войти) либо приватная (вход по приглашению создателя)
|
||||
"""
|
||||
isPublic: Boolean!
|
||||
}
|
||||
|
||||
input CreateSovietIndividualDataInput {
|
||||
"""Дата рождения"""
|
||||
birthdate: String!
|
||||
@@ -7083,6 +7124,14 @@ input MakeClearanceInput {
|
||||
username: String!
|
||||
}
|
||||
|
||||
"""Тип комнаты: пайщики, совет, проект Capital, комната секретаря"""
|
||||
enum ManagedRoomKind {
|
||||
CAPITAL_PROJECT
|
||||
COUNCIL
|
||||
MEMBERS
|
||||
SECRETARY
|
||||
}
|
||||
|
||||
input MarkReportPeriodInput {
|
||||
mark: ReportSubmissionMark
|
||||
period: Int
|
||||
@@ -7962,6 +8011,13 @@ type Mutation {
|
||||
"""
|
||||
chatcoopCreateCalendarIcsSubscription: ChatCoopCalendarIcsUrlResponse!
|
||||
|
||||
"""
|
||||
Создать комнату с секретарём (публичную или приватную); секретарь подключается сразу
|
||||
|
||||
Требуемые роли: chairman, member.
|
||||
"""
|
||||
chatcoopCreateSecretaryRoom(data: CreateSecretaryRoomInput!): ChatcoopSecretaryRoom!
|
||||
|
||||
"""
|
||||
Удалить событие календаря
|
||||
|
||||
@@ -7969,6 +8025,13 @@ type Mutation {
|
||||
"""
|
||||
chatcoopDeleteCalendarEvent(id: String!): Boolean!
|
||||
|
||||
"""
|
||||
Удалить комнату секретаря: вывести секретаря и снять комнату с синхронизации (возвращает matrixRoomId)
|
||||
|
||||
Требуемые роли: chairman, member.
|
||||
"""
|
||||
chatcoopRemoveSecretaryRoom(data: RemoveSecretaryRoomInput!): String!
|
||||
|
||||
"""
|
||||
Обновить событие календаря
|
||||
|
||||
@@ -8540,6 +8603,13 @@ type Mutation {
|
||||
walmoveWallets(input: WalmoveInput!): Ledger2AdjustmentResult!
|
||||
}
|
||||
|
||||
"""Тип комнаты вне проекта: пайщики, совет, комната секретаря"""
|
||||
enum NonProjectRoomKind {
|
||||
COUNCIL
|
||||
MEMBERS
|
||||
SECRETARY
|
||||
}
|
||||
|
||||
input NotificationWorkflowRecipientInput {
|
||||
"""Username получателя"""
|
||||
username: String!
|
||||
@@ -10263,6 +10333,13 @@ type Query {
|
||||
"""
|
||||
chatcoopListCalendarRooms: [ChatCoopCalendarRoomOption!]!
|
||||
|
||||
"""
|
||||
Комнаты Matrix вне проектов Capital (пайщики/совет/секретарь) — для синхронизации в blago
|
||||
|
||||
Требуемые роли: chairman, member, user.
|
||||
"""
|
||||
chatcoopListNonProjectCommunicationRooms: [ChatcoopNonProjectCommunicationRoom!]!
|
||||
|
||||
"""
|
||||
Комнаты Matrix, привязанные к проекту Capital (реестр ChatCoop)
|
||||
|
||||
@@ -10270,6 +10347,13 @@ type Query {
|
||||
"""
|
||||
chatcoopListProjectCommunicationRooms(data: GetProjectCommunicationRoomsInput!): [ChatcoopProjectCommunicationRoom!]!
|
||||
|
||||
"""
|
||||
Все комнаты реестра ChatCoop (системные/проектные — read-only, комнаты секретаря — удаляемые)
|
||||
|
||||
Требуемые роли: chairman, member.
|
||||
"""
|
||||
chatcoopListSecretaryRooms: [ChatcoopSecretaryRoom!]!
|
||||
|
||||
"""
|
||||
UTC-даты (YYYY-MM-DD), в которых есть сообщения новее afterOriginServerTsExclusive, для комнаты Matrix
|
||||
|
||||
@@ -10882,6 +10966,11 @@ type RegistrationProgram {
|
||||
title: String!
|
||||
}
|
||||
|
||||
input RemoveSecretaryRoomInput {
|
||||
"""Идентификатор комнаты Matrix, которую нужно удалить"""
|
||||
matrixRoomId: String!
|
||||
}
|
||||
|
||||
type ReportCalendarPeriodEntry {
|
||||
dueDate: String!
|
||||
dueMonth: Int!
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Matrix: комната секретаря — создаётся вручную председателем/советом из desktop.
|
||||
* Всегда незашифрована (E2EE секретарь транскрибировать не может). Тип (public/private)
|
||||
* выбирается при создании, поэтому isPrivate здесь не фиксируем — задаёт сервис.
|
||||
*/
|
||||
|
||||
import type { MatrixChatRoomPreset } from './matrix-chat-room-preset.types';
|
||||
|
||||
/**
|
||||
* Те же права, что у комнаты проекта Capital: модераторы (50) почти по всем настройкам;
|
||||
* 100 только у Matrix-админа для критичных state.
|
||||
*/
|
||||
function buildPowerLevels(adminUserId: string): Record<string, unknown> {
|
||||
return {
|
||||
users_default: 0,
|
||||
invite: 50,
|
||||
kick: 50,
|
||||
ban: 50,
|
||||
redact: 50,
|
||||
state_default: 50,
|
||||
events_default: 0,
|
||||
users: {
|
||||
[adminUserId]: 100,
|
||||
},
|
||||
events: {
|
||||
'm.room.name': 50,
|
||||
'm.room.topic': 50,
|
||||
'm.room.avatar': 50,
|
||||
'm.room.pinned_events': 50,
|
||||
'm.room.canonical_alias': 50,
|
||||
'm.room.aliases': 50,
|
||||
'm.room.power_levels': 100,
|
||||
'm.room.history_visibility': 50,
|
||||
'm.room.encryption': 100,
|
||||
'm.room.tombstone': 100,
|
||||
'm.room.server_acl': 100,
|
||||
|
||||
'im.vector.modular.widgets': 50,
|
||||
'm.widget': 50,
|
||||
'org.matrix.msc2876.widgets': 50,
|
||||
'io.element.widgets.layout': 50,
|
||||
|
||||
'io.element.call': 50,
|
||||
'io.element.call.member': 0,
|
||||
'org.matrix.msc3401.call': 50,
|
||||
'org.matrix.msc3401.call.member': 0,
|
||||
'm.call': 50,
|
||||
'm.call.invite': 50,
|
||||
'm.call.answer': 0,
|
||||
'm.call.hangup': 0,
|
||||
'm.call.candidates': 0,
|
||||
'm.call.select_answer': 0,
|
||||
'm.call.reject': 0,
|
||||
'm.call.negotiate': 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Базовый пресет комнаты секретаря. `isPrivate` переопределяется сервисом по флагу публичности.
|
||||
* `encrypt` всегда false — иначе секретарь не сможет читать сообщения и транскрибировать.
|
||||
*/
|
||||
export const SECRETARY_ROOM_MATRIX: MatrixChatRoomPreset = {
|
||||
label: 'Комната секретаря',
|
||||
isPrivate: true,
|
||||
encrypt: false,
|
||||
roomType: undefined,
|
||||
initialState: [],
|
||||
buildPowerLevels,
|
||||
};
|
||||
+26
@@ -23,6 +23,32 @@ export class ChatcoopProjectCommunicationRoomDTO {
|
||||
displayLabel!: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Тип непроектной комнаты: пайщики, совет или комната секретаря.
|
||||
*/
|
||||
export enum NonProjectRoomKindGql {
|
||||
MEMBERS = 'MEMBERS',
|
||||
COUNCIL = 'COUNCIL',
|
||||
SECRETARY = 'SECRETARY',
|
||||
}
|
||||
|
||||
registerEnumType(NonProjectRoomKindGql, {
|
||||
name: 'NonProjectRoomKind',
|
||||
description: 'Тип комнаты вне проекта: пайщики, совет, комната секретаря',
|
||||
});
|
||||
|
||||
@ObjectType('ChatcoopNonProjectCommunicationRoom')
|
||||
export class ChatcoopNonProjectCommunicationRoomDTO {
|
||||
@Field({ description: 'Идентификатор комнаты Matrix' })
|
||||
matrixRoomId!: string;
|
||||
|
||||
@Field({ description: 'Подпись для отображения комнаты' })
|
||||
displayLabel!: string;
|
||||
|
||||
@Field(() => NonProjectRoomKindGql, { description: 'Тип комнаты (пайщики / совет / секретарь)' })
|
||||
kind!: NonProjectRoomKindGql;
|
||||
}
|
||||
|
||||
@ObjectType('ChatcoopRoomMessageLine')
|
||||
export class ChatcoopRoomMessageLineDTO {
|
||||
@Field(() => Float, { description: 'origin_server_ts из Matrix (мс)' })
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { Field, InputType, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||
import { IsBoolean, IsNotEmpty, IsString, MaxLength } from 'class-validator';
|
||||
|
||||
/**
|
||||
* Тип комнаты в реестре ChatCoop. Редактировать (удалять) можно только `SECRETARY`;
|
||||
* системные (`MEMBERS`/`COUNCIL`) и проектные (`CAPITAL_PROJECT`) защищены.
|
||||
*/
|
||||
export enum ManagedRoomKindGql {
|
||||
MEMBERS = 'MEMBERS',
|
||||
COUNCIL = 'COUNCIL',
|
||||
CAPITAL_PROJECT = 'CAPITAL_PROJECT',
|
||||
SECRETARY = 'SECRETARY',
|
||||
}
|
||||
|
||||
registerEnumType(ManagedRoomKindGql, {
|
||||
name: 'ManagedRoomKind',
|
||||
description: 'Тип комнаты: пайщики, совет, проект Capital, комната секретаря',
|
||||
});
|
||||
|
||||
@ObjectType('ChatcoopSecretaryRoom')
|
||||
export class ChatcoopSecretaryRoomDTO {
|
||||
@Field({ description: 'Идентификатор комнаты Matrix' })
|
||||
matrixRoomId!: string;
|
||||
|
||||
@Field({ description: 'Название комнаты' })
|
||||
displayLabel!: string;
|
||||
|
||||
@Field(() => ManagedRoomKindGql, { description: 'Тип комнаты' })
|
||||
kind!: ManagedRoomKindGql;
|
||||
|
||||
@Field({ description: 'Комната зашифрована (E2EE) — секретарь не транскрибирует такие комнаты' })
|
||||
encrypted!: boolean;
|
||||
|
||||
@Field({ description: 'Секретарь присутствует в комнате' })
|
||||
secretaryInRoom!: boolean;
|
||||
|
||||
@Field({ description: 'Можно ли удалить комнату из интерфейса (только комнаты секретаря)' })
|
||||
editable!: boolean;
|
||||
}
|
||||
|
||||
@InputType('CreateSecretaryRoomInput')
|
||||
export class CreateSecretaryRoomInputDTO {
|
||||
@Field({ description: 'Название комнаты' })
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@MaxLength(240)
|
||||
displayName!: string;
|
||||
|
||||
@Field({ description: 'Публичная комната (любой может войти) либо приватная (вход по приглашению создателя)' })
|
||||
@IsBoolean()
|
||||
isPublic!: boolean;
|
||||
}
|
||||
|
||||
@InputType('RemoveSecretaryRoomInput')
|
||||
export class RemoveSecretaryRoomInputDTO {
|
||||
@Field({ description: 'Идентификатор комнаты Matrix, которую нужно удалить' })
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
matrixRoomId!: string;
|
||||
}
|
||||
+32
@@ -11,19 +11,33 @@ import { AuthRoles } from '~/application/auth/decorators/auth.decorator';
|
||||
import { CurrentUser } from '~/application/auth/decorators/current-user.decorator';
|
||||
import type { MonoAccountDomainInterface } from '~/domain/account/interfaces/mono-account-domain.interface';
|
||||
import {
|
||||
ChatcoopNonProjectCommunicationRoomDTO,
|
||||
ChatcoopProjectCommunicationRoomDTO,
|
||||
ChatcoopRoomMessageLineDTO,
|
||||
GetMaxOriginServerTsForRoomInputDTO,
|
||||
GetProjectCommunicationRoomsInputDTO,
|
||||
GetRoomMessagesForUtcDateInputDTO,
|
||||
ListUtcDatesWithNewRoomMessagesInputDTO,
|
||||
NonProjectRoomKindGql,
|
||||
RoomMessageKindGql,
|
||||
} from '../dto/project-communication.dto';
|
||||
import type { InterNonProjectRoomKind } from '@coopenomics/inter';
|
||||
|
||||
function mapKind(kind: 'text' | 'audio'): RoomMessageKindGql {
|
||||
return kind === 'text' ? RoomMessageKindGql.TEXT : RoomMessageKindGql.AUDIO;
|
||||
}
|
||||
|
||||
function mapNonProjectKind(kind: InterNonProjectRoomKind): NonProjectRoomKindGql {
|
||||
switch (kind) {
|
||||
case 'members':
|
||||
return NonProjectRoomKindGql.MEMBERS;
|
||||
case 'council':
|
||||
return NonProjectRoomKindGql.COUNCIL;
|
||||
case 'secretary':
|
||||
return NonProjectRoomKindGql.SECRETARY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Доступ к данным переписки Capital↔Matrix для синхронизации (blago-cli, секретарь).
|
||||
* Источник — порт `INTER_PROJECT_COMMUNICATION_ARTIFACTS` (пакет inter).
|
||||
@@ -61,6 +75,24 @@ export class ProjectCommunicationResolver {
|
||||
}));
|
||||
}
|
||||
|
||||
@Query(() => [ChatcoopNonProjectCommunicationRoomDTO], {
|
||||
name: 'chatcoopListNonProjectCommunicationRooms',
|
||||
description: 'Комнаты Matrix вне проектов Capital (пайщики/совет/секретарь) — для синхронизации в blago',
|
||||
})
|
||||
@AuthRoles(['chairman', 'member', 'user'])
|
||||
async listNonProjectCommunicationRooms(
|
||||
@CurrentUser() user: MonoAccountDomainInterface
|
||||
): Promise<ChatcoopNonProjectCommunicationRoomDTO[]> {
|
||||
this.ensureComm();
|
||||
this.logger.debug(`chatcoopListNonProjectCommunicationRooms user=${user.username}`);
|
||||
const rooms = await this.comm!.listNonProjectCommunicationRooms();
|
||||
return rooms.map((r) => ({
|
||||
matrixRoomId: r.matrixRoomId,
|
||||
displayLabel: r.displayLabel,
|
||||
kind: mapNonProjectKind(r.kind),
|
||||
}));
|
||||
}
|
||||
|
||||
@Query(() => [String], {
|
||||
name: 'chatcoopListUtcDatesWithNewRoomMessages',
|
||||
description:
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
|
||||
import { Logger, UseGuards } from '@nestjs/common';
|
||||
import { ActiveUserStatusGuard } from '~/application/auth/guards/active-user-status.guard';
|
||||
import { GqlJwtAuthGuard } from '~/application/auth/guards/graphql-jwt-auth.guard';
|
||||
import { RolesGuard } from '~/application/auth/guards/roles.guard';
|
||||
import { AuthRoles } from '~/application/auth/decorators/auth.decorator';
|
||||
import { CurrentUser } from '~/application/auth/decorators/current-user.decorator';
|
||||
import type { MonoAccountDomainInterface } from '~/domain/account/interfaces/mono-account-domain.interface';
|
||||
import { SecretaryRoomManagementService } from '../services/secretary-room-management.service';
|
||||
import {
|
||||
ChatcoopSecretaryRoomDTO,
|
||||
CreateSecretaryRoomInputDTO,
|
||||
ManagedRoomKindGql,
|
||||
RemoveSecretaryRoomInputDTO,
|
||||
} from '../dto/secretary-room.dto';
|
||||
import type { ChatcoopManagedMatrixRoomKind } from '../../domain/entities/managed-matrix-room.entity';
|
||||
import type { ManagedMatrixRoomDomainEntity } from '../../domain/entities/managed-matrix-room.entity';
|
||||
|
||||
function mapManagedKind(kind: ChatcoopManagedMatrixRoomKind): ManagedRoomKindGql {
|
||||
switch (kind) {
|
||||
case 'members':
|
||||
return ManagedRoomKindGql.MEMBERS;
|
||||
case 'council':
|
||||
return ManagedRoomKindGql.COUNCIL;
|
||||
case 'capital_project':
|
||||
return ManagedRoomKindGql.CAPITAL_PROJECT;
|
||||
case 'secretary':
|
||||
return ManagedRoomKindGql.SECRETARY;
|
||||
}
|
||||
}
|
||||
|
||||
function toDto(room: ManagedMatrixRoomDomainEntity): ChatcoopSecretaryRoomDTO {
|
||||
return {
|
||||
matrixRoomId: room.matrixRoomId,
|
||||
displayLabel: room.displayLabel || room.matrixRoomId,
|
||||
kind: mapManagedKind(room.kind),
|
||||
encrypted: room.encrypted,
|
||||
secretaryInRoom: room.secretaryInRoom,
|
||||
editable: room.kind === 'secretary',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Управление комнатами секретаря (стол связи desktop).
|
||||
* Доступ — председатель и члены совета: они создают комнаты для звонков с секретарём и удаляют свои.
|
||||
*/
|
||||
@Resolver()
|
||||
@UseGuards(GqlJwtAuthGuard, RolesGuard, ActiveUserStatusGuard)
|
||||
export class SecretaryRoomsResolver {
|
||||
private readonly logger = new Logger(SecretaryRoomsResolver.name);
|
||||
|
||||
constructor(private readonly service: SecretaryRoomManagementService) {}
|
||||
|
||||
@Query(() => [ChatcoopSecretaryRoomDTO], {
|
||||
name: 'chatcoopListSecretaryRooms',
|
||||
description: 'Все комнаты реестра ChatCoop (системные/проектные — read-only, комнаты секретаря — удаляемые)',
|
||||
})
|
||||
@AuthRoles(['chairman', 'member'])
|
||||
async listSecretaryRooms(
|
||||
@CurrentUser() user: MonoAccountDomainInterface
|
||||
): Promise<ChatcoopSecretaryRoomDTO[]> {
|
||||
this.logger.debug(`chatcoopListSecretaryRooms user=${user.username}`);
|
||||
const rooms = await this.service.listRooms();
|
||||
return rooms.map(toDto);
|
||||
}
|
||||
|
||||
@Mutation(() => ChatcoopSecretaryRoomDTO, {
|
||||
name: 'chatcoopCreateSecretaryRoom',
|
||||
description: 'Создать комнату с секретарём (публичную или приватную); секретарь подключается сразу',
|
||||
})
|
||||
@AuthRoles(['chairman', 'member'])
|
||||
async createSecretaryRoom(
|
||||
@CurrentUser() user: MonoAccountDomainInterface,
|
||||
@Args('data', { type: () => CreateSecretaryRoomInputDTO }) data: CreateSecretaryRoomInputDTO
|
||||
): Promise<ChatcoopSecretaryRoomDTO> {
|
||||
this.logger.log(`chatcoopCreateSecretaryRoom user=${user.username} isPublic=${data.isPublic}`);
|
||||
const room = await this.service.createSecretaryRoom({
|
||||
creatorUsername: user.username,
|
||||
creatorRole: user.role,
|
||||
displayName: data.displayName,
|
||||
isPublic: data.isPublic,
|
||||
});
|
||||
return toDto(room);
|
||||
}
|
||||
|
||||
@Mutation(() => String, {
|
||||
name: 'chatcoopRemoveSecretaryRoom',
|
||||
description: 'Удалить комнату секретаря: вывести секретаря и снять комнату с синхронизации (возвращает matrixRoomId)',
|
||||
})
|
||||
@AuthRoles(['chairman', 'member'])
|
||||
async removeSecretaryRoom(
|
||||
@CurrentUser() user: MonoAccountDomainInterface,
|
||||
@Args('data', { type: () => RemoveSecretaryRoomInputDTO }) data: RemoveSecretaryRoomInputDTO
|
||||
): Promise<string> {
|
||||
this.logger.log(`chatcoopRemoveSecretaryRoom user=${user.username} room=${data.matrixRoomId}`);
|
||||
return this.service.removeSecretaryRoom(data.matrixRoomId);
|
||||
}
|
||||
}
|
||||
+42
@@ -818,6 +818,48 @@ export class MatrixApiService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Приглашает пользователя в комнату (от имени Matrix-админа, который состоит в комнате).
|
||||
* Пользователь увидит приглашение и войдёт сам — в отличие от {@link joinRoom} (force-join).
|
||||
*/
|
||||
async inviteUser(userId: string, roomId: string): Promise<void> {
|
||||
try {
|
||||
const adminToken = await this.loginAdmin();
|
||||
await this.httpClient.post(
|
||||
`/_matrix/client/v3/rooms/${encodeURIComponent(roomId)}/invite`,
|
||||
{ user_id: userId },
|
||||
{ headers: { Authorization: `Bearer ${adminToken}` } }
|
||||
);
|
||||
this.logger.log(`Пользователь ${userId} приглашён в комнату ${roomId}`);
|
||||
} catch (error: any) {
|
||||
this.logger.error(
|
||||
`Не удалось пригласить пользователя ${userId} в комнату ${roomId}: ${JSON.stringify(error?.response?.data)}`
|
||||
);
|
||||
throw new Error('Не удалось пригласить пользователя в комнату');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Исключает пользователя из комнаты (от имени Matrix-админа с power 100).
|
||||
* Используется для вывода секретаря из комнаты по требованию председателя/совета.
|
||||
*/
|
||||
async kickUser(userId: string, roomId: string, reason?: string): Promise<void> {
|
||||
try {
|
||||
const adminToken = await this.loginAdmin();
|
||||
await this.httpClient.post(
|
||||
`/_matrix/client/v3/rooms/${encodeURIComponent(roomId)}/kick`,
|
||||
reason ? { user_id: userId, reason } : { user_id: userId },
|
||||
{ headers: { Authorization: `Bearer ${adminToken}` } }
|
||||
);
|
||||
this.logger.log(`Пользователь ${userId} исключён из комнаты ${roomId}`);
|
||||
} catch (error: any) {
|
||||
this.logger.error(
|
||||
`Не удалось исключить пользователя ${userId} из комнаты ${roomId}: ${JSON.stringify(error?.response?.data)}`
|
||||
);
|
||||
throw new Error('Не удалось исключить пользователя из комнаты');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает текущие права пользователей в комнате
|
||||
*/
|
||||
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
import { BadRequestException, Inject, Injectable, Logger, NotFoundException } from '@nestjs/common';
|
||||
import { MatrixApiService } from './matrix-api.service';
|
||||
import { ChatCoopApplicationService } from './chatcoop-application.service';
|
||||
import { MatrixUserManagementService } from '../../domain/services/matrix-user-management.service';
|
||||
import { SECRETARY_ROOM_MATRIX } from '../config/matrix-secretary-room.config';
|
||||
import {
|
||||
CHATCOOP_MANAGED_MATRIX_ROOM_REPOSITORY,
|
||||
type ChatcoopManagedMatrixRoomRepository,
|
||||
} from '../../domain/repositories/managed-matrix-room.repository';
|
||||
import {
|
||||
CHATCOOP_STATE_REPOSITORY,
|
||||
type ChatcoopStateRepository,
|
||||
} from '../../domain/repositories/chatcoop-state.repository';
|
||||
import type { ManagedMatrixRoomDomainEntity } from '../../domain/entities/managed-matrix-room.entity';
|
||||
|
||||
export interface CreateSecretaryRoomInput {
|
||||
/** Логин пайщика-создателя (председатель или член совета) */
|
||||
creatorUsername: string;
|
||||
/** Роль создателя в кооперативе — для прав в комнате (chairman / member) */
|
||||
creatorRole: string;
|
||||
/** Название комнаты */
|
||||
displayName: string;
|
||||
/** true — публичная (любой может войти), false — приватная (вход по приглашению) */
|
||||
isPublic: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Управление комнатами секретаря: создание/удаление и список всех комнат реестра.
|
||||
*
|
||||
* Принцип безопасности: секретарь присутствует ТОЛЬКО в комнатах, созданных нашим бэкендом
|
||||
* (kind `secretary`, а также системные members/council и проектные capital_project). Произвольные
|
||||
* «чужие» Matrix-комнаты сюда не подключаются — Synapse общий на все кооперативы, и force-join в
|
||||
* чужую комнату был бы дырой.
|
||||
*/
|
||||
@Injectable()
|
||||
export class SecretaryRoomManagementService {
|
||||
private readonly logger = new Logger(SecretaryRoomManagementService.name);
|
||||
|
||||
constructor(
|
||||
private readonly matrixApi: MatrixApiService,
|
||||
private readonly chatCoopApplicationService: ChatCoopApplicationService,
|
||||
private readonly matrixUserManagement: MatrixUserManagementService,
|
||||
@Inject(CHATCOOP_MANAGED_MATRIX_ROOM_REPOSITORY)
|
||||
private readonly managedRooms: ChatcoopManagedMatrixRoomRepository,
|
||||
@Inject(CHATCOOP_STATE_REPOSITORY)
|
||||
private readonly chatcoopState: ChatcoopStateRepository
|
||||
) {}
|
||||
|
||||
async listRooms(): Promise<ManagedMatrixRoomDomainEntity[]> {
|
||||
return this.managedRooms.findAll();
|
||||
}
|
||||
|
||||
async createSecretaryRoom(input: CreateSecretaryRoomInput): Promise<ManagedMatrixRoomDomainEntity> {
|
||||
const st = await this.chatcoopState.getSingleton();
|
||||
if (!st.isInitialized || !st.spaceId || st.spaceId.trim().length === 0) {
|
||||
throw new BadRequestException('ChatCoop не инициализирован — нельзя создать комнату секретаря');
|
||||
}
|
||||
const secretaryId = st.secretaryMatrixUserId;
|
||||
if (typeof secretaryId !== 'string' || secretaryId.trim().length === 0) {
|
||||
throw new BadRequestException('Секретарь не инициализирован — нельзя создать комнату секретаря');
|
||||
}
|
||||
const displayName = input.displayName.trim();
|
||||
if (displayName.length === 0) {
|
||||
throw new BadRequestException('Название комнаты не может быть пустым');
|
||||
}
|
||||
|
||||
const adminUserId = this.matrixApi.getAdminUserId();
|
||||
const powerLevels = SECRETARY_ROOM_MATRIX.buildPowerLevels(adminUserId);
|
||||
const isPrivate = !input.isPublic;
|
||||
|
||||
const roomId = await this.matrixApi.createRoom(
|
||||
displayName.slice(0, 240),
|
||||
`Комната секретаря — создал ${input.creatorUsername}`,
|
||||
isPrivate,
|
||||
SECRETARY_ROOM_MATRIX.roomType,
|
||||
SECRETARY_ROOM_MATRIX.initialState.length > 0 ? SECRETARY_ROOM_MATRIX.initialState : undefined,
|
||||
// Комната секретаря всегда незашифрована — иначе секретарь не читает сообщения и не транскрибирует.
|
||||
false,
|
||||
powerLevels as Record<string, unknown>
|
||||
);
|
||||
|
||||
await this.matrixApi.addRoomToSpace(st.spaceId.trim(), roomId);
|
||||
|
||||
// Force-join только секретарь.
|
||||
await this.matrixApi.joinRoom(secretaryId.trim(), roomId);
|
||||
|
||||
// Создатель сразу входит в свою комнату с правами модератора.
|
||||
const creatorMatrix = await this.matrixUserManagement.getMatrixUserByCoopUsername(input.creatorUsername);
|
||||
if (creatorMatrix) {
|
||||
try {
|
||||
await this.matrixApi.joinRoom(creatorMatrix.matrixUserId, roomId);
|
||||
await this.chatCoopApplicationService.applyMembersRoomStylePowerForUser(
|
||||
creatorMatrix.matrixUserId,
|
||||
roomId,
|
||||
input.creatorRole
|
||||
);
|
||||
} catch (err) {
|
||||
this.logger.warn(`Не удалось ввести создателя ${input.creatorUsername} в комнату ${roomId}: ${String(err)}`);
|
||||
}
|
||||
} else {
|
||||
this.logger.warn(`Нет Matrix-аккаунта для создателя ${input.creatorUsername} — он войдёт позже сам`);
|
||||
}
|
||||
|
||||
const room = await this.managedRooms.upsertRoom({
|
||||
matrixRoomId: roomId,
|
||||
encrypted: false,
|
||||
kind: 'secretary',
|
||||
displayLabel: displayName,
|
||||
projectHash: null,
|
||||
secretaryInRoom: true,
|
||||
});
|
||||
|
||||
this.logger.log(
|
||||
`Создана комната секретаря ${roomId} (${isPrivate ? 'приватная' : 'публичная'}) создателем ${input.creatorUsername}`
|
||||
);
|
||||
return room;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаляет комнату секретаря: выводит секретаря из Matrix-комнаты и убирает запись из реестра ChatCoop.
|
||||
* Сама Matrix-комната не уничтожается — её участники сохраняют доступ и историю, но транскрипция/синхронизация прекращаются.
|
||||
* Разрешено только для kind `secretary` — системные и проектные комнаты так удалять нельзя.
|
||||
*/
|
||||
async removeSecretaryRoom(matrixRoomId: string): Promise<string> {
|
||||
const room = await this.managedRooms.findByMatrixRoomId(matrixRoomId);
|
||||
if (!room) {
|
||||
throw new NotFoundException('Комната не найдена в реестре ChatCoop');
|
||||
}
|
||||
if (room.kind !== 'secretary') {
|
||||
throw new BadRequestException('Удалять можно только комнаты секретаря (системные и проектные защищены)');
|
||||
}
|
||||
|
||||
const st = await this.chatcoopState.getSingleton();
|
||||
const secretaryId = st.secretaryMatrixUserId;
|
||||
if (typeof secretaryId === 'string' && secretaryId.trim().length > 0) {
|
||||
try {
|
||||
await this.matrixApi.kickUser(secretaryId.trim(), matrixRoomId, 'Комната секретаря удалена');
|
||||
} catch (err) {
|
||||
this.logger.warn(`Не удалось вывести секретаря из ${matrixRoomId}: ${String(err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
await this.managedRooms.setSecretaryInRoom(matrixRoomId, false);
|
||||
await this.managedRooms.deleteByMatrixRoomId(matrixRoomId);
|
||||
this.logger.log(`Комната секретаря ${matrixRoomId} удалена из реестра`);
|
||||
return matrixRoomId;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import { ChatCoopCalendarResolver } from './application/resolvers/chatcoop-calen
|
||||
import { ChatCoopCalendarFeedController } from './application/controllers/chatcoop-calendar-feed.controller';
|
||||
import { TranscriptionResolver } from './application/resolvers/transcription.resolver';
|
||||
import { ProjectCommunicationResolver } from './application/resolvers/project-communication.resolver';
|
||||
import { SecretaryRoomsResolver } from './application/resolvers/secretary-rooms.resolver';
|
||||
import { SecretaryRoomManagementService } from './application/services/secretary-room-management.service';
|
||||
import { WinstonLoggerService } from '~/application/logger/logger-app.service';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { z } from 'zod';
|
||||
@@ -527,6 +529,7 @@ export class ChatCoopPlugin extends BaseExtModule {
|
||||
// Application Services
|
||||
ChatCoopApplicationService,
|
||||
CapitalProjectMatrixSyncService,
|
||||
SecretaryRoomManagementService,
|
||||
MatrixApiService,
|
||||
ChatCoopSecretaryMatrixTokenService,
|
||||
SecretaryAgentService,
|
||||
@@ -604,6 +607,7 @@ export class ChatCoopPlugin extends BaseExtModule {
|
||||
TranscriptionResolver,
|
||||
ActiveUserStatusGuard,
|
||||
ProjectCommunicationResolver,
|
||||
SecretaryRoomsResolver,
|
||||
],
|
||||
exports: [
|
||||
ChatCoopPlugin,
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Тип комнаты Matrix, зарегистрированной в реестре ChatCoop (централизованное хранение).
|
||||
*/
|
||||
export type ChatcoopManagedMatrixRoomKind = 'members' | 'council' | 'capital_project';
|
||||
export type ChatcoopManagedMatrixRoomKind = 'members' | 'council' | 'capital_project' | 'secretary';
|
||||
|
||||
/**
|
||||
* Запись о Matrix-комнате кооператива: источник правды для LiveKit/секретаря; совет при миграции v3 из legacy-конфига.
|
||||
|
||||
+4
@@ -24,6 +24,10 @@ export interface ChatcoopManagedMatrixRoomRepository {
|
||||
findByKind(kind: ChatcoopManagedMatrixRoomKind): Promise<ManagedMatrixRoomDomainEntity[]>;
|
||||
/** Комнаты проекта Capital (kind capital_project, projectHash задан). */
|
||||
findByProjectHash(projectHash: string): Promise<ManagedMatrixRoomDomainEntity[]>;
|
||||
/** Все комнаты реестра (для интерфейса управления присутствием секретаря). */
|
||||
findAll(): Promise<ManagedMatrixRoomDomainEntity[]>;
|
||||
/** Комнаты, не привязанные к проекту Capital (members/council/secretary) — для синхронизации в blago. */
|
||||
findNonProjectCommunicationRooms(): Promise<ManagedMatrixRoomDomainEntity[]>;
|
||||
/** Комнаты, в которых секретарь может участвовать в звонке и писать plaintext в Matrix */
|
||||
findEligibleForSecretaryTranscription(): Promise<ManagedMatrixRoomDomainEntity[]>;
|
||||
/** Обновить флаг членства секретаря (после успешного join или проверки Matrix) */
|
||||
|
||||
+15
@@ -1,6 +1,8 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type {
|
||||
InterCompletedCallTranscriptionHead,
|
||||
InterNonProjectCommunicationRoomRef,
|
||||
InterNonProjectRoomKind,
|
||||
InterProjectCommunicationArtifactsPort,
|
||||
InterProjectCommunicationRoomRef,
|
||||
InterRoomMessageLine,
|
||||
@@ -48,6 +50,19 @@ export class ChatcoopInterProjectCommunicationArtifactsAdapter implements InterP
|
||||
}));
|
||||
}
|
||||
|
||||
async listNonProjectCommunicationRooms(): Promise<InterNonProjectCommunicationRoomRef[]> {
|
||||
const rooms = await this.managedRooms.findNonProjectCommunicationRooms();
|
||||
return rooms
|
||||
.filter((r): r is typeof r & { kind: InterNonProjectRoomKind } =>
|
||||
r.kind === 'members' || r.kind === 'council' || r.kind === 'secretary'
|
||||
)
|
||||
.map((r) => ({
|
||||
matrixRoomId: r.matrixRoomId,
|
||||
displayLabel: r.displayLabel || r.matrixRoomId,
|
||||
kind: r.kind,
|
||||
}));
|
||||
}
|
||||
|
||||
async listUtcDatesWithNewMessages(
|
||||
matrixRoomId: string,
|
||||
afterOriginServerTsExclusive: number
|
||||
|
||||
+11
-1
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Not, Repository } from 'typeorm';
|
||||
import type {
|
||||
ChatcoopManagedMatrixRoomRepository,
|
||||
UpsertManagedMatrixRoomInput,
|
||||
@@ -56,6 +56,16 @@ export class ManagedMatrixRoomTypeormRepository implements ChatcoopManagedMatrix
|
||||
return rows.map(ManagedMatrixRoomMapper.toDomain);
|
||||
}
|
||||
|
||||
async findAll(): Promise<ManagedMatrixRoomDomainEntity[]> {
|
||||
const rows = await this.repository.find();
|
||||
return rows.map(ManagedMatrixRoomMapper.toDomain);
|
||||
}
|
||||
|
||||
async findNonProjectCommunicationRooms(): Promise<ManagedMatrixRoomDomainEntity[]> {
|
||||
const rows = await this.repository.find({ where: { roomKind: Not('capital_project') } });
|
||||
return rows.map(ManagedMatrixRoomMapper.toDomain);
|
||||
}
|
||||
|
||||
async findEligibleForSecretaryTranscription(): Promise<ManagedMatrixRoomDomainEntity[]> {
|
||||
const rows = await this.repository.find({ where: { encrypted: false } });
|
||||
return rows.map(ManagedMatrixRoomMapper.toDomain);
|
||||
|
||||
@@ -341,6 +341,9 @@ export const AllTypesProps: Record<string,any> = {
|
||||
},
|
||||
CreateProjectPropertyInput:{
|
||||
|
||||
},
|
||||
CreateSecretaryRoomInput:{
|
||||
|
||||
},
|
||||
CreateSovietIndividualDataInput:{
|
||||
passport:"PassportInput"
|
||||
@@ -617,6 +620,7 @@ export const AllTypesProps: Record<string,any> = {
|
||||
MakeClearanceInput:{
|
||||
document:"SignedDigitalDocumentInput"
|
||||
},
|
||||
ManagedRoomKind: "enum" as const,
|
||||
MarkReportPeriodInput:{
|
||||
mark:"ReportSubmissionMark",
|
||||
reportType:"ReportType"
|
||||
@@ -899,8 +903,14 @@ export const AllTypesProps: Record<string,any> = {
|
||||
chatcoopCreateCalendarEvent:{
|
||||
data:"CreateChatCoopCalendarEventInput"
|
||||
},
|
||||
chatcoopCreateSecretaryRoom:{
|
||||
data:"CreateSecretaryRoomInput"
|
||||
},
|
||||
chatcoopDeleteCalendarEvent:{
|
||||
|
||||
},
|
||||
chatcoopRemoveSecretaryRoom:{
|
||||
data:"RemoveSecretaryRoomInput"
|
||||
},
|
||||
chatcoopUpdateCalendarEvent:{
|
||||
data:"UpdateChatCoopCalendarEventInput"
|
||||
@@ -1214,6 +1224,7 @@ export const AllTypesProps: Record<string,any> = {
|
||||
input:"WalmoveInput"
|
||||
}
|
||||
},
|
||||
NonProjectRoomKind: "enum" as const,
|
||||
NotificationWorkflowRecipientInput:{
|
||||
|
||||
},
|
||||
@@ -1643,6 +1654,9 @@ export const AllTypesProps: Record<string,any> = {
|
||||
statement:"ParticipantApplicationSignedDocumentInput",
|
||||
user_agreement:"SignedDigitalDocumentInput",
|
||||
wallet_agreement:"SignedDigitalDocumentInput"
|
||||
},
|
||||
RemoveSecretaryRoomInput:{
|
||||
|
||||
},
|
||||
ReportHistoryFilterInput:{
|
||||
reportType:"ReportType"
|
||||
@@ -2920,6 +2934,11 @@ export const ReturnTypes: Record<string,any> = {
|
||||
displayLabel:"String",
|
||||
matrixRoomId:"String"
|
||||
},
|
||||
ChatcoopNonProjectCommunicationRoom:{
|
||||
displayLabel:"String",
|
||||
kind:"NonProjectRoomKind",
|
||||
matrixRoomId:"String"
|
||||
},
|
||||
ChatcoopProjectCommunicationRoom:{
|
||||
displayLabel:"String",
|
||||
matrixRoomId:"String"
|
||||
@@ -2931,6 +2950,14 @@ export const ReturnTypes: Record<string,any> = {
|
||||
kind:"RoomMessageKind",
|
||||
originServerTs:"Float"
|
||||
},
|
||||
ChatcoopSecretaryRoom:{
|
||||
displayLabel:"String",
|
||||
editable:"Boolean",
|
||||
encrypted:"Boolean",
|
||||
kind:"ManagedRoomKind",
|
||||
matrixRoomId:"String",
|
||||
secretaryInRoom:"Boolean"
|
||||
},
|
||||
ContactsDTO:{
|
||||
chairman:"PublicChairman",
|
||||
details:"OrganizationDetails",
|
||||
@@ -3559,7 +3586,9 @@ export const ReturnTypes: Record<string,any> = {
|
||||
chatcoopCreateAccount:"Boolean",
|
||||
chatcoopCreateCalendarEvent:"ChatCoopCalendarEvent",
|
||||
chatcoopCreateCalendarIcsSubscription:"ChatCoopCalendarIcsUrlResponse",
|
||||
chatcoopCreateSecretaryRoom:"ChatcoopSecretaryRoom",
|
||||
chatcoopDeleteCalendarEvent:"Boolean",
|
||||
chatcoopRemoveSecretaryRoom:"String",
|
||||
chatcoopUpdateCalendarEvent:"ChatCoopCalendarEvent",
|
||||
chatcoopUpdateTranscriptionMemo:"CallTranscription",
|
||||
completeCapitalOnboardingStep:"CapitalOnboardingState",
|
||||
@@ -4128,7 +4157,9 @@ export const ReturnTypes: Record<string,any> = {
|
||||
chatcoopGetTranscriptions:"CallTranscription",
|
||||
chatcoopListCalendarEvents:"ChatCoopCalendarEvent",
|
||||
chatcoopListCalendarRooms:"ChatCoopCalendarRoomOption",
|
||||
chatcoopListNonProjectCommunicationRooms:"ChatcoopNonProjectCommunicationRoom",
|
||||
chatcoopListProjectCommunicationRooms:"ChatcoopProjectCommunicationRoom",
|
||||
chatcoopListSecretaryRooms:"ChatcoopSecretaryRoom",
|
||||
chatcoopListUtcDatesWithNewRoomMessages:"String",
|
||||
checkReportReadiness:"ReportReadinessView",
|
||||
cooperativeAgreements:"CoopAgreement",
|
||||
|
||||
@@ -3851,6 +3851,16 @@ export type ValueTypes = {
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on ChatCoopCalendarRoomOption']?: Omit<ValueTypes["ChatCoopCalendarRoomOption"], "...on ChatCoopCalendarRoomOption">
|
||||
}>;
|
||||
["ChatcoopNonProjectCommunicationRoom"]: AliasType<{
|
||||
/** Подпись для отображения комнаты */
|
||||
displayLabel?:boolean | `@${string}`,
|
||||
/** Тип комнаты (пайщики / совет / секретарь) */
|
||||
kind?:boolean | `@${string}`,
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on ChatcoopNonProjectCommunicationRoom']?: Omit<ValueTypes["ChatcoopNonProjectCommunicationRoom"], "...on ChatcoopNonProjectCommunicationRoom">
|
||||
}>;
|
||||
["ChatcoopProjectCommunicationRoom"]: AliasType<{
|
||||
/** Подпись для отображения (комната / проект Capital) */
|
||||
@@ -3872,6 +3882,22 @@ export type ValueTypes = {
|
||||
originServerTs?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on ChatcoopRoomMessageLine']?: Omit<ValueTypes["ChatcoopRoomMessageLine"], "...on ChatcoopRoomMessageLine">
|
||||
}>;
|
||||
["ChatcoopSecretaryRoom"]: AliasType<{
|
||||
/** Название комнаты */
|
||||
displayLabel?:boolean | `@${string}`,
|
||||
/** Можно ли удалить комнату из интерфейса (только комнаты секретаря) */
|
||||
editable?:boolean | `@${string}`,
|
||||
/** Комната зашифрована (E2EE) — секретарь не транскрибирует такие комнаты */
|
||||
encrypted?:boolean | `@${string}`,
|
||||
/** Тип комнаты */
|
||||
kind?:boolean | `@${string}`,
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
/** Секретарь присутствует в комнате */
|
||||
secretaryInRoom?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on ChatcoopSecretaryRoom']?: Omit<ValueTypes["ChatcoopSecretaryRoom"], "...on ChatcoopSecretaryRoom">
|
||||
}>;
|
||||
["CheckMatrixUsernameInput"]: {
|
||||
username: string | Variable<any, string>
|
||||
@@ -4604,6 +4630,12 @@ export type ValueTypes = {
|
||||
property_hash: string | Variable<any, string>,
|
||||
/** Имя пользователя */
|
||||
username: string | Variable<any, string>
|
||||
};
|
||||
["CreateSecretaryRoomInput"]: {
|
||||
/** Название комнаты */
|
||||
displayName: string | Variable<any, string>,
|
||||
/** Публичная комната (любой может войти) либо приватная (вход по приглашению создателя) */
|
||||
isPublic: boolean | Variable<any, string>
|
||||
};
|
||||
["CreateSovietIndividualDataInput"]: {
|
||||
/** Дата рождения */
|
||||
@@ -6143,6 +6175,8 @@ export type ValueTypes = {
|
||||
/** Имя пользователя */
|
||||
username: string | Variable<any, string>
|
||||
};
|
||||
/** Тип комнаты: пайщики, совет, проект Capital, комната секретаря */
|
||||
["ManagedRoomKind"]:ManagedRoomKind;
|
||||
["MarkReportPeriodInput"]: {
|
||||
mark?: ValueTypes["ReportSubmissionMark"] | undefined | null | Variable<any, string>,
|
||||
period?: number | undefined | null | Variable<any, string>,
|
||||
@@ -6466,7 +6500,9 @@ chatcoopCreateCalendarEvent?: [{ data: ValueTypes["CreateChatCoopCalendarEventIn
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopCreateCalendarIcsSubscription?:ValueTypes["ChatCoopCalendarIcsUrlResponse"],
|
||||
chatcoopCreateSecretaryRoom?: [{ data: ValueTypes["CreateSecretaryRoomInput"] | Variable<any, string>},ValueTypes["ChatcoopSecretaryRoom"]],
|
||||
chatcoopDeleteCalendarEvent?: [{ id: string | Variable<any, string>},boolean | `@${string}`],
|
||||
chatcoopRemoveSecretaryRoom?: [{ data: ValueTypes["RemoveSecretaryRoomInput"] | Variable<any, string>},boolean | `@${string}`],
|
||||
chatcoopUpdateCalendarEvent?: [{ data: ValueTypes["UpdateChatCoopCalendarEventInput"] | Variable<any, string>},ValueTypes["ChatCoopCalendarEvent"]],
|
||||
chatcoopUpdateTranscriptionMemo?: [{ data: ValueTypes["UpdateCallTranscriptionMemoInput"] | Variable<any, string>},ValueTypes["CallTranscription"]],
|
||||
completeCapitalOnboardingStep?: [{ data: ValueTypes["CapitalOnboardingStepInput"] | Variable<any, string>},ValueTypes["CapitalOnboardingState"]],
|
||||
@@ -6566,6 +6602,8 @@ walmoveWallets?: [{ input: ValueTypes["WalmoveInput"] | Variable<any, string>},V
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on Mutation']?: Omit<ValueTypes["Mutation"], "...on Mutation">
|
||||
}>;
|
||||
/** Тип комнаты вне проекта: пайщики, совет, комната секретаря */
|
||||
["NonProjectRoomKind"]:NonProjectRoomKind;
|
||||
["NotificationWorkflowRecipientInput"]: {
|
||||
/** Username получателя */
|
||||
username: string | Variable<any, string>
|
||||
@@ -7774,7 +7812,15 @@ chatcoopGetTranscriptions?: [{ data?: ValueTypes["GetTranscriptionsInput"] | und
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListCalendarRooms?:ValueTypes["ChatCoopCalendarRoomOption"],
|
||||
/** Комнаты Matrix вне проектов Capital (пайщики/совет/секретарь) — для синхронизации в blago
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListNonProjectCommunicationRooms?:ValueTypes["ChatcoopNonProjectCommunicationRoom"],
|
||||
chatcoopListProjectCommunicationRooms?: [{ data: ValueTypes["GetProjectCommunicationRoomsInput"] | Variable<any, string>},ValueTypes["ChatcoopProjectCommunicationRoom"]],
|
||||
/** Все комнаты реестра ChatCoop (системные/проектные — read-only, комнаты секретаря — удаляемые)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListSecretaryRooms?:ValueTypes["ChatcoopSecretaryRoom"],
|
||||
chatcoopListUtcDatesWithNewRoomMessages?: [{ data: ValueTypes["ListUtcDatesWithNewRoomMessagesInput"] | Variable<any, string>},boolean | `@${string}`],
|
||||
checkReportReadiness?: [{ reportType: ValueTypes["ReportType"] | Variable<any, string>},ValueTypes["ReportReadinessView"]],
|
||||
cooperativeAgreements?: [{ coopname: string | Variable<any, string>},ValueTypes["CoopAgreement"]],
|
||||
@@ -8047,6 +8093,10 @@ validateReportEdits?: [{ editsJson: string | Variable<any, string>, reportType:
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on RegistrationProgram']?: Omit<ValueTypes["RegistrationProgram"], "...on RegistrationProgram">
|
||||
}>;
|
||||
["RemoveSecretaryRoomInput"]: {
|
||||
/** Идентификатор комнаты Matrix, которую нужно удалить */
|
||||
matrixRoomId: string | Variable<any, string>
|
||||
};
|
||||
["ReportCalendarPeriodEntry"]: AliasType<{
|
||||
dueDate?:boolean | `@${string}`,
|
||||
dueMonth?:boolean | `@${string}`,
|
||||
@@ -12194,6 +12244,15 @@ export type ResolverInputTypes = {
|
||||
displayLabel?:boolean | `@${string}`,
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["ChatcoopNonProjectCommunicationRoom"]: AliasType<{
|
||||
/** Подпись для отображения комнаты */
|
||||
displayLabel?:boolean | `@${string}`,
|
||||
/** Тип комнаты (пайщики / совет / секретарь) */
|
||||
kind?:boolean | `@${string}`,
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["ChatcoopProjectCommunicationRoom"]: AliasType<{
|
||||
/** Подпись для отображения (комната / проект Capital) */
|
||||
@@ -12213,6 +12272,21 @@ export type ResolverInputTypes = {
|
||||
/** origin_server_ts из Matrix (мс) */
|
||||
originServerTs?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["ChatcoopSecretaryRoom"]: AliasType<{
|
||||
/** Название комнаты */
|
||||
displayLabel?:boolean | `@${string}`,
|
||||
/** Можно ли удалить комнату из интерфейса (только комнаты секретаря) */
|
||||
editable?:boolean | `@${string}`,
|
||||
/** Комната зашифрована (E2EE) — секретарь не транскрибирует такие комнаты */
|
||||
encrypted?:boolean | `@${string}`,
|
||||
/** Тип комнаты */
|
||||
kind?:boolean | `@${string}`,
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
/** Секретарь присутствует в комнате */
|
||||
secretaryInRoom?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["CheckMatrixUsernameInput"]: {
|
||||
username: string
|
||||
@@ -12940,6 +13014,12 @@ export type ResolverInputTypes = {
|
||||
property_hash: string,
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
["CreateSecretaryRoomInput"]: {
|
||||
/** Название комнаты */
|
||||
displayName: string,
|
||||
/** Публичная комната (любой может войти) либо приватная (вход по приглашению создателя) */
|
||||
isPublic: boolean
|
||||
};
|
||||
["CreateSovietIndividualDataInput"]: {
|
||||
/** Дата рождения */
|
||||
@@ -14435,6 +14515,8 @@ export type ResolverInputTypes = {
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
/** Тип комнаты: пайщики, совет, проект Capital, комната секретаря */
|
||||
["ManagedRoomKind"]:ManagedRoomKind;
|
||||
["MarkReportPeriodInput"]: {
|
||||
mark?: ResolverInputTypes["ReportSubmissionMark"] | undefined | null,
|
||||
period?: number | undefined | null,
|
||||
@@ -14749,7 +14831,9 @@ chatcoopCreateCalendarEvent?: [{ data: ResolverInputTypes["CreateChatCoopCalenda
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopCreateCalendarIcsSubscription?:ResolverInputTypes["ChatCoopCalendarIcsUrlResponse"],
|
||||
chatcoopCreateSecretaryRoom?: [{ data: ResolverInputTypes["CreateSecretaryRoomInput"]},ResolverInputTypes["ChatcoopSecretaryRoom"]],
|
||||
chatcoopDeleteCalendarEvent?: [{ id: string},boolean | `@${string}`],
|
||||
chatcoopRemoveSecretaryRoom?: [{ data: ResolverInputTypes["RemoveSecretaryRoomInput"]},boolean | `@${string}`],
|
||||
chatcoopUpdateCalendarEvent?: [{ data: ResolverInputTypes["UpdateChatCoopCalendarEventInput"]},ResolverInputTypes["ChatCoopCalendarEvent"]],
|
||||
chatcoopUpdateTranscriptionMemo?: [{ data: ResolverInputTypes["UpdateCallTranscriptionMemoInput"]},ResolverInputTypes["CallTranscription"]],
|
||||
completeCapitalOnboardingStep?: [{ data: ResolverInputTypes["CapitalOnboardingStepInput"]},ResolverInputTypes["CapitalOnboardingState"]],
|
||||
@@ -14848,6 +14932,8 @@ voteOnAnnualGeneralMeet?: [{ data: ResolverInputTypes["VoteOnAnnualGeneralMeetIn
|
||||
walmoveWallets?: [{ input: ResolverInputTypes["WalmoveInput"]},ResolverInputTypes["Ledger2AdjustmentResult"]],
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
/** Тип комнаты вне проекта: пайщики, совет, комната секретаря */
|
||||
["NonProjectRoomKind"]:NonProjectRoomKind;
|
||||
["NotificationWorkflowRecipientInput"]: {
|
||||
/** Username получателя */
|
||||
username: string
|
||||
@@ -16002,7 +16088,15 @@ chatcoopGetTranscriptions?: [{ data?: ResolverInputTypes["GetTranscriptionsInput
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListCalendarRooms?:ResolverInputTypes["ChatCoopCalendarRoomOption"],
|
||||
/** Комнаты Matrix вне проектов Capital (пайщики/совет/секретарь) — для синхронизации в blago
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListNonProjectCommunicationRooms?:ResolverInputTypes["ChatcoopNonProjectCommunicationRoom"],
|
||||
chatcoopListProjectCommunicationRooms?: [{ data: ResolverInputTypes["GetProjectCommunicationRoomsInput"]},ResolverInputTypes["ChatcoopProjectCommunicationRoom"]],
|
||||
/** Все комнаты реестра ChatCoop (системные/проектные — read-only, комнаты секретаря — удаляемые)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListSecretaryRooms?:ResolverInputTypes["ChatcoopSecretaryRoom"],
|
||||
chatcoopListUtcDatesWithNewRoomMessages?: [{ data: ResolverInputTypes["ListUtcDatesWithNewRoomMessagesInput"]},boolean | `@${string}`],
|
||||
checkReportReadiness?: [{ reportType: ResolverInputTypes["ReportType"]},ResolverInputTypes["ReportReadinessView"]],
|
||||
cooperativeAgreements?: [{ coopname: string},ResolverInputTypes["CoopAgreement"]],
|
||||
@@ -16268,6 +16362,10 @@ validateReportEdits?: [{ editsJson: string, reportType: ResolverInputTypes["Repo
|
||||
title?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["RemoveSecretaryRoomInput"]: {
|
||||
/** Идентификатор комнаты Matrix, которую нужно удалить */
|
||||
matrixRoomId: string
|
||||
};
|
||||
["ReportCalendarPeriodEntry"]: AliasType<{
|
||||
dueDate?:boolean | `@${string}`,
|
||||
dueMonth?:boolean | `@${string}`,
|
||||
@@ -20303,6 +20401,14 @@ export type ModelTypes = {
|
||||
["ChatCoopCalendarRoomOption"]: {
|
||||
displayLabel: string,
|
||||
matrixRoomId: string
|
||||
};
|
||||
["ChatcoopNonProjectCommunicationRoom"]: {
|
||||
/** Подпись для отображения комнаты */
|
||||
displayLabel: string,
|
||||
/** Тип комнаты (пайщики / совет / секретарь) */
|
||||
kind: ModelTypes["NonProjectRoomKind"],
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId: string
|
||||
};
|
||||
["ChatcoopProjectCommunicationRoom"]: {
|
||||
/** Подпись для отображения (комната / проект Capital) */
|
||||
@@ -20320,6 +20426,20 @@ export type ModelTypes = {
|
||||
kind: ModelTypes["RoomMessageKind"],
|
||||
/** origin_server_ts из Matrix (мс) */
|
||||
originServerTs: number
|
||||
};
|
||||
["ChatcoopSecretaryRoom"]: {
|
||||
/** Название комнаты */
|
||||
displayLabel: string,
|
||||
/** Можно ли удалить комнату из интерфейса (только комнаты секретаря) */
|
||||
editable: boolean,
|
||||
/** Комната зашифрована (E2EE) — секретарь не транскрибирует такие комнаты */
|
||||
encrypted: boolean,
|
||||
/** Тип комнаты */
|
||||
kind: ModelTypes["ManagedRoomKind"],
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId: string,
|
||||
/** Секретарь присутствует в комнате */
|
||||
secretaryInRoom: boolean
|
||||
};
|
||||
["CheckMatrixUsernameInput"]: {
|
||||
username: string
|
||||
@@ -21039,6 +21159,12 @@ export type ModelTypes = {
|
||||
property_hash: string,
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
["CreateSecretaryRoomInput"]: {
|
||||
/** Название комнаты */
|
||||
displayName: string,
|
||||
/** Публичная комната (любой может войти) либо приватная (вход по приглашению создателя) */
|
||||
isPublic: boolean
|
||||
};
|
||||
["CreateSovietIndividualDataInput"]: {
|
||||
/** Дата рождения */
|
||||
@@ -22479,6 +22605,7 @@ export type ModelTypes = {
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
["ManagedRoomKind"]:ManagedRoomKind;
|
||||
["MarkReportPeriodInput"]: {
|
||||
mark?: ModelTypes["ReportSubmissionMark"] | undefined | null,
|
||||
period?: number | undefined | null,
|
||||
@@ -23023,10 +23150,18 @@ export type ModelTypes = {
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopCreateCalendarIcsSubscription: ModelTypes["ChatCoopCalendarIcsUrlResponse"],
|
||||
/** Создать комнату с секретарём (публичную или приватную); секретарь подключается сразу
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopCreateSecretaryRoom: ModelTypes["ChatcoopSecretaryRoom"],
|
||||
/** Удалить событие календаря
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopDeleteCalendarEvent: boolean,
|
||||
/** Удалить комнату секретаря: вывести секретаря и снять комнату с синхронизации (возвращает matrixRoomId)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopRemoveSecretaryRoom: string,
|
||||
/** Обновить событие календаря
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
@@ -23352,6 +23487,7 @@ export type ModelTypes = {
|
||||
Требуемые роли: chairman. */
|
||||
walmoveWallets: ModelTypes["Ledger2AdjustmentResult"]
|
||||
};
|
||||
["NonProjectRoomKind"]:NonProjectRoomKind;
|
||||
["NotificationWorkflowRecipientInput"]: {
|
||||
/** Username получателя */
|
||||
username: string
|
||||
@@ -24514,10 +24650,18 @@ export type ModelTypes = {
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListCalendarRooms: Array<ModelTypes["ChatCoopCalendarRoomOption"]>,
|
||||
/** Комнаты Matrix вне проектов Capital (пайщики/совет/секретарь) — для синхронизации в blago
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListNonProjectCommunicationRooms: Array<ModelTypes["ChatcoopNonProjectCommunicationRoom"]>,
|
||||
/** Комнаты Matrix, привязанные к проекту Capital (реестр ChatCoop)
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListProjectCommunicationRooms: Array<ModelTypes["ChatcoopProjectCommunicationRoom"]>,
|
||||
/** Все комнаты реестра ChatCoop (системные/проектные — read-only, комнаты секретаря — удаляемые)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListSecretaryRooms: Array<ModelTypes["ChatcoopSecretaryRoom"]>,
|
||||
/** UTC-даты (YYYY-MM-DD), в которых есть сообщения новее afterOriginServerTsExclusive, для комнаты Matrix
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
@@ -24890,6 +25034,10 @@ export type ModelTypes = {
|
||||
requirements?: string | undefined | null,
|
||||
/** Название программы для отображения */
|
||||
title: string
|
||||
};
|
||||
["RemoveSecretaryRoomInput"]: {
|
||||
/** Идентификатор комнаты Matrix, которую нужно удалить */
|
||||
matrixRoomId: string
|
||||
};
|
||||
["ReportCalendarPeriodEntry"]: {
|
||||
dueDate: string,
|
||||
@@ -29030,6 +29178,16 @@ export type GraphQLTypes = {
|
||||
displayLabel: string,
|
||||
matrixRoomId: string,
|
||||
['...on ChatCoopCalendarRoomOption']: Omit<GraphQLTypes["ChatCoopCalendarRoomOption"], "...on ChatCoopCalendarRoomOption">
|
||||
};
|
||||
["ChatcoopNonProjectCommunicationRoom"]: {
|
||||
__typename: "ChatcoopNonProjectCommunicationRoom",
|
||||
/** Подпись для отображения комнаты */
|
||||
displayLabel: string,
|
||||
/** Тип комнаты (пайщики / совет / секретарь) */
|
||||
kind: GraphQLTypes["NonProjectRoomKind"],
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId: string,
|
||||
['...on ChatcoopNonProjectCommunicationRoom']: Omit<GraphQLTypes["ChatcoopNonProjectCommunicationRoom"], "...on ChatcoopNonProjectCommunicationRoom">
|
||||
};
|
||||
["ChatcoopProjectCommunicationRoom"]: {
|
||||
__typename: "ChatcoopProjectCommunicationRoom",
|
||||
@@ -29051,6 +29209,22 @@ export type GraphQLTypes = {
|
||||
/** origin_server_ts из Matrix (мс) */
|
||||
originServerTs: number,
|
||||
['...on ChatcoopRoomMessageLine']: Omit<GraphQLTypes["ChatcoopRoomMessageLine"], "...on ChatcoopRoomMessageLine">
|
||||
};
|
||||
["ChatcoopSecretaryRoom"]: {
|
||||
__typename: "ChatcoopSecretaryRoom",
|
||||
/** Название комнаты */
|
||||
displayLabel: string,
|
||||
/** Можно ли удалить комнату из интерфейса (только комнаты секретаря) */
|
||||
editable: boolean,
|
||||
/** Комната зашифрована (E2EE) — секретарь не транскрибирует такие комнаты */
|
||||
encrypted: boolean,
|
||||
/** Тип комнаты */
|
||||
kind: GraphQLTypes["ManagedRoomKind"],
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId: string,
|
||||
/** Секретарь присутствует в комнате */
|
||||
secretaryInRoom: boolean,
|
||||
['...on ChatcoopSecretaryRoom']: Omit<GraphQLTypes["ChatcoopSecretaryRoom"], "...on ChatcoopSecretaryRoom">
|
||||
};
|
||||
["CheckMatrixUsernameInput"]: {
|
||||
username: string
|
||||
@@ -29783,6 +29957,12 @@ export type GraphQLTypes = {
|
||||
property_hash: string,
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
["CreateSecretaryRoomInput"]: {
|
||||
/** Название комнаты */
|
||||
displayName: string,
|
||||
/** Публичная комната (любой может войти) либо приватная (вход по приглашению создателя) */
|
||||
isPublic: boolean
|
||||
};
|
||||
["CreateSovietIndividualDataInput"]: {
|
||||
/** Дата рождения */
|
||||
@@ -31322,6 +31502,8 @@ export type GraphQLTypes = {
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
/** Тип комнаты: пайщики, совет, проект Capital, комната секретаря */
|
||||
["ManagedRoomKind"]: ManagedRoomKind;
|
||||
["MarkReportPeriodInput"]: {
|
||||
mark?: GraphQLTypes["ReportSubmissionMark"] | undefined | null,
|
||||
period?: number | undefined | null,
|
||||
@@ -31885,10 +32067,18 @@ export type GraphQLTypes = {
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopCreateCalendarIcsSubscription: GraphQLTypes["ChatCoopCalendarIcsUrlResponse"],
|
||||
/** Создать комнату с секретарём (публичную или приватную); секретарь подключается сразу
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopCreateSecretaryRoom: GraphQLTypes["ChatcoopSecretaryRoom"],
|
||||
/** Удалить событие календаря
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopDeleteCalendarEvent: boolean,
|
||||
/** Удалить комнату секретаря: вывести секретаря и снять комнату с синхронизации (возвращает matrixRoomId)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopRemoveSecretaryRoom: string,
|
||||
/** Обновить событие календаря
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
@@ -32215,6 +32405,8 @@ export type GraphQLTypes = {
|
||||
walmoveWallets: GraphQLTypes["Ledger2AdjustmentResult"],
|
||||
['...on Mutation']: Omit<GraphQLTypes["Mutation"], "...on Mutation">
|
||||
};
|
||||
/** Тип комнаты вне проекта: пайщики, совет, комната секретаря */
|
||||
["NonProjectRoomKind"]: NonProjectRoomKind;
|
||||
["NotificationWorkflowRecipientInput"]: {
|
||||
/** Username получателя */
|
||||
username: string
|
||||
@@ -33506,10 +33698,18 @@ export type GraphQLTypes = {
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListCalendarRooms: Array<GraphQLTypes["ChatCoopCalendarRoomOption"]>,
|
||||
/** Комнаты Matrix вне проектов Capital (пайщики/совет/секретарь) — для синхронизации в blago
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListNonProjectCommunicationRooms: Array<GraphQLTypes["ChatcoopNonProjectCommunicationRoom"]>,
|
||||
/** Комнаты Matrix, привязанные к проекту Capital (реестр ChatCoop)
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListProjectCommunicationRooms: Array<GraphQLTypes["ChatcoopProjectCommunicationRoom"]>,
|
||||
/** Все комнаты реестра ChatCoop (системные/проектные — read-only, комнаты секретаря — удаляемые)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListSecretaryRooms: Array<GraphQLTypes["ChatcoopSecretaryRoom"]>,
|
||||
/** UTC-даты (YYYY-MM-DD), в которых есть сообщения новее afterOriginServerTsExclusive, для комнаты Matrix
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
@@ -33895,6 +34095,10 @@ export type GraphQLTypes = {
|
||||
/** Название программы для отображения */
|
||||
title: string,
|
||||
['...on RegistrationProgram']: Omit<GraphQLTypes["RegistrationProgram"], "...on RegistrationProgram">
|
||||
};
|
||||
["RemoveSecretaryRoomInput"]: {
|
||||
/** Идентификатор комнаты Matrix, которую нужно удалить */
|
||||
matrixRoomId: string
|
||||
};
|
||||
["ReportCalendarPeriodEntry"]: {
|
||||
__typename: "ReportCalendarPeriodEntry",
|
||||
@@ -35589,6 +35793,19 @@ export enum LogEventType {
|
||||
VOTING_COMPLETED = "VOTING_COMPLETED",
|
||||
VOTING_STARTED = "VOTING_STARTED"
|
||||
}
|
||||
/** Тип комнаты: пайщики, совет, проект Capital, комната секретаря */
|
||||
export enum ManagedRoomKind {
|
||||
CAPITAL_PROJECT = "CAPITAL_PROJECT",
|
||||
COUNCIL = "COUNCIL",
|
||||
MEMBERS = "MEMBERS",
|
||||
SECRETARY = "SECRETARY"
|
||||
}
|
||||
/** Тип комнаты вне проекта: пайщики, совет, комната секретаря */
|
||||
export enum NonProjectRoomKind {
|
||||
COUNCIL = "COUNCIL",
|
||||
MEMBERS = "MEMBERS",
|
||||
SECRETARY = "SECRETARY"
|
||||
}
|
||||
/** Тип юридического лица */
|
||||
export enum OrganizationType {
|
||||
AO = "AO",
|
||||
@@ -35856,6 +36073,7 @@ type ZEUS_VARIABLES = {
|
||||
["CreateProjectInput"]: ValueTypes["CreateProjectInput"];
|
||||
["CreateProjectInvestInput"]: ValueTypes["CreateProjectInvestInput"];
|
||||
["CreateProjectPropertyInput"]: ValueTypes["CreateProjectPropertyInput"];
|
||||
["CreateSecretaryRoomInput"]: ValueTypes["CreateSecretaryRoomInput"];
|
||||
["CreateSovietIndividualDataInput"]: ValueTypes["CreateSovietIndividualDataInput"];
|
||||
["CreateStoryInput"]: ValueTypes["CreateStoryInput"];
|
||||
["CreateSubscriptionInput"]: ValueTypes["CreateSubscriptionInput"];
|
||||
@@ -35953,9 +36171,11 @@ type ZEUS_VARIABLES = {
|
||||
["LoginInput"]: ValueTypes["LoginInput"];
|
||||
["LogoutInput"]: ValueTypes["LogoutInput"];
|
||||
["MakeClearanceInput"]: ValueTypes["MakeClearanceInput"];
|
||||
["ManagedRoomKind"]: ValueTypes["ManagedRoomKind"];
|
||||
["MarkReportPeriodInput"]: ValueTypes["MarkReportPeriodInput"];
|
||||
["ModerateRequestInput"]: ValueTypes["ModerateRequestInput"];
|
||||
["MoveCapitalIssueToComponentInput"]: ValueTypes["MoveCapitalIssueToComponentInput"];
|
||||
["NonProjectRoomKind"]: ValueTypes["NonProjectRoomKind"];
|
||||
["NotificationWorkflowRecipientInput"]: ValueTypes["NotificationWorkflowRecipientInput"];
|
||||
["NotifyOnAnnualGeneralMeetInput"]: ValueTypes["NotifyOnAnnualGeneralMeetInput"];
|
||||
["OpenProjectInput"]: ValueTypes["OpenProjectInput"];
|
||||
@@ -36001,6 +36221,7 @@ type ZEUS_VARIABLES = {
|
||||
["RegisterAccountInput"]: ValueTypes["RegisterAccountInput"];
|
||||
["RegisterContributorInput"]: ValueTypes["RegisterContributorInput"];
|
||||
["RegisterParticipantInput"]: ValueTypes["RegisterParticipantInput"];
|
||||
["RemoveSecretaryRoomInput"]: ValueTypes["RemoveSecretaryRoomInput"];
|
||||
["ReportHistoryFilterInput"]: ValueTypes["ReportHistoryFilterInput"];
|
||||
["ReportPreviewInput"]: ValueTypes["ReportPreviewInput"];
|
||||
["ReportSubmissionMark"]: ValueTypes["ReportSubmissionMark"];
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { client } from 'src/shared/api/client';
|
||||
import { Queries, Mutations } from '@coopenomics/sdk';
|
||||
import type { ISecretaryRoom, ICreateSecretaryRoomInput } from '../model/types';
|
||||
|
||||
async function listSecretaryRooms(): Promise<ISecretaryRoom[]> {
|
||||
const { [Queries.ChatCoop.ListSecretaryRooms.name]: rows } = await client.Query(
|
||||
Queries.ChatCoop.ListSecretaryRooms.query,
|
||||
{},
|
||||
);
|
||||
return rows ?? [];
|
||||
}
|
||||
|
||||
async function createSecretaryRoom(data: ICreateSecretaryRoomInput): Promise<ISecretaryRoom> {
|
||||
const { [Mutations.ChatCoop.CreateSecretaryRoom.name]: row } = await client.Mutation(
|
||||
Mutations.ChatCoop.CreateSecretaryRoom.mutation,
|
||||
{ variables: { data } },
|
||||
);
|
||||
return row;
|
||||
}
|
||||
|
||||
async function removeSecretaryRoom(matrixRoomId: string): Promise<string> {
|
||||
const { [Mutations.ChatCoop.RemoveSecretaryRoom.name]: result } = await client.Mutation(
|
||||
Mutations.ChatCoop.RemoveSecretaryRoom.mutation,
|
||||
{ variables: { data: { matrixRoomId } } },
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
listSecretaryRooms,
|
||||
createSecretaryRoom,
|
||||
removeSecretaryRoom,
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
export { useSecretaryRoomStore } from './model';
|
||||
export * from './model/types';
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './store';
|
||||
export * from './types';
|
||||
@@ -0,0 +1,78 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref, Ref } from 'vue';
|
||||
import { api } from '../api';
|
||||
import type { ISecretaryRoom, ICreateSecretaryRoomInput } from './types';
|
||||
|
||||
const namespace = 'secretaryRoomStore';
|
||||
|
||||
interface ISecretaryRoomStore {
|
||||
rooms: Ref<ISecretaryRoom[]>;
|
||||
isLoading: Ref<boolean>;
|
||||
isMutating: Ref<boolean>;
|
||||
error: Ref<string | null>;
|
||||
loadRooms: () => Promise<ISecretaryRoom[]>;
|
||||
createRoom: (data: ICreateSecretaryRoomInput) => Promise<ISecretaryRoom>;
|
||||
removeRoom: (matrixRoomId: string) => Promise<void>;
|
||||
clearError: () => void;
|
||||
}
|
||||
|
||||
export const useSecretaryRoomStore = defineStore(namespace, (): ISecretaryRoomStore => {
|
||||
const rooms = ref<ISecretaryRoom[]>([]);
|
||||
const isLoading = ref(false);
|
||||
const isMutating = ref(false);
|
||||
const error = ref<string | null>(null);
|
||||
|
||||
const loadRooms = async (): Promise<ISecretaryRoom[]> => {
|
||||
isLoading.value = true;
|
||||
error.value = null;
|
||||
try {
|
||||
const result = await api.listSecretaryRooms();
|
||||
rooms.value = result;
|
||||
return result;
|
||||
} catch (err) {
|
||||
console.error('Failed to load secretary rooms:', err);
|
||||
error.value = 'Не удалось загрузить список комнат. Попробуйте обновить страницу.';
|
||||
return [];
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const createRoom = async (data: ICreateSecretaryRoomInput): Promise<ISecretaryRoom> => {
|
||||
isMutating.value = true;
|
||||
error.value = null;
|
||||
try {
|
||||
const room = await api.createSecretaryRoom(data);
|
||||
await loadRooms();
|
||||
return room;
|
||||
} finally {
|
||||
isMutating.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const removeRoom = async (matrixRoomId: string): Promise<void> => {
|
||||
isMutating.value = true;
|
||||
error.value = null;
|
||||
try {
|
||||
await api.removeSecretaryRoom(matrixRoomId);
|
||||
await loadRooms();
|
||||
} finally {
|
||||
isMutating.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const clearError = () => {
|
||||
error.value = null;
|
||||
};
|
||||
|
||||
return {
|
||||
rooms,
|
||||
isLoading,
|
||||
isMutating,
|
||||
error,
|
||||
loadRooms,
|
||||
createRoom,
|
||||
removeRoom,
|
||||
clearError,
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { Queries, Mutations } from '@coopenomics/sdk';
|
||||
|
||||
/** Комната из реестра ChatCoop (системная / проектная / секретаря) */
|
||||
export type ISecretaryRoom =
|
||||
Queries.ChatCoop.ListSecretaryRooms.IOutput[typeof Queries.ChatCoop.ListSecretaryRooms.name][number];
|
||||
|
||||
/** Вход для создания комнаты секретаря */
|
||||
export type ICreateSecretaryRoomInput = Mutations.ChatCoop.CreateSecretaryRoom.IInput['data'];
|
||||
@@ -1,3 +1,4 @@
|
||||
export * as ChatCoopCalendar from './ChatCoopCalendar';
|
||||
export * as ChatCoopChat from './ChatCoopChat';
|
||||
export * as SecretaryRoom from './SecretaryRoom';
|
||||
export * as Transcription from './Transcription';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { markRaw } from 'vue';
|
||||
import { CalendarPage, ChatCoopPage, MobileClientPage, TranscriptionsPage, TranscriptionDetailPage } from './pages';
|
||||
import { CalendarPage, ChatCoopPage, MobileClientPage, SecretaryRoomsPage, TranscriptionsPage, TranscriptionDetailPage } from './pages';
|
||||
import { agreementsBase } from 'src/shared/lib/consts/workspaces';
|
||||
import type { IWorkspaceConfig } from 'src/shared/lib/types/workspace';
|
||||
|
||||
@@ -73,6 +73,19 @@ export default async function (): Promise<IWorkspaceConfig[]> {
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
path: 'secretary-rooms',
|
||||
name: 'chatcoop-secretary-rooms',
|
||||
component: markRaw(SecretaryRoomsPage),
|
||||
meta: {
|
||||
title: 'Комнаты секретаря',
|
||||
icon: 'fa-solid fa-user-shield',
|
||||
roles: ['chairman', 'member'],
|
||||
agreements: agreementsBase,
|
||||
requiresAuth: true,
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
path: 'transcriptions/:id',
|
||||
name: 'chatcoop-transcription-detail',
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './ui'
|
||||
+282
@@ -0,0 +1,282 @@
|
||||
<template lang="pug">
|
||||
q-page.secretary-rooms-page(padding)
|
||||
header.sr-head
|
||||
div.sr-head__text
|
||||
h1.sr-head__title Комнаты секретаря
|
||||
p.sr-head__subtitle
|
||||
| Создавайте комнаты для звонков с секретарём — он подключается сразу и ведёт транскрипцию.
|
||||
| Системные и проектные комнаты показаны для справки и не удаляются.
|
||||
.sr-head__actions
|
||||
q-btn(
|
||||
unelevated
|
||||
no-caps
|
||||
color="primary"
|
||||
icon="fa-solid fa-plus"
|
||||
label="Создать комнату"
|
||||
@click="openCreateDialog"
|
||||
)
|
||||
q-btn.sr-head__refresh(
|
||||
flat
|
||||
round
|
||||
dense
|
||||
icon="fa-solid fa-rotate-right"
|
||||
@click="handleRefresh"
|
||||
:loading="store.isLoading"
|
||||
aria-label="Обновить список"
|
||||
)
|
||||
q-tooltip Обновить
|
||||
|
||||
q-banner.sr-error(v-if="store.error" dense rounded class="bg-red-1 text-red-9 q-mb-md")
|
||||
| {{ store.error }}
|
||||
|
||||
q-table(
|
||||
flat
|
||||
bordered
|
||||
:rows="store.rooms"
|
||||
:columns="columns"
|
||||
row-key="matrixRoomId"
|
||||
:loading="store.isLoading"
|
||||
:rows-per-page-options="[0]"
|
||||
hide-pagination
|
||||
no-data-label="Комнат пока нет"
|
||||
)
|
||||
template(#body-cell-displayLabel="props")
|
||||
q-td(:props="props")
|
||||
.sr-name {{ props.row.displayLabel }}
|
||||
.sr-room-id {{ props.row.matrixRoomId }}
|
||||
template(#body-cell-kind="props")
|
||||
q-td(:props="props")
|
||||
q-badge(:color="kindColor(props.row.kind)" :label="kindLabel(props.row.kind)" outline)
|
||||
template(#body-cell-secretary="props")
|
||||
q-td(:props="props")
|
||||
q-icon(
|
||||
:name="props.row.secretaryInRoom ? 'fa-solid fa-circle-check' : 'fa-solid fa-circle-minus'"
|
||||
:color="props.row.secretaryInRoom ? 'positive' : 'grey-5'"
|
||||
size="18px"
|
||||
)
|
||||
q-tooltip {{ props.row.secretaryInRoom ? 'Секретарь в комнате' : 'Секретаря нет' }}
|
||||
q-icon.q-ml-sm(
|
||||
v-if="props.row.encrypted"
|
||||
name="fa-solid fa-lock"
|
||||
color="orange-8"
|
||||
size="16px"
|
||||
)
|
||||
q-tooltip Зашифрованная комната — транскрипция недоступна
|
||||
template(#body-cell-actions="props")
|
||||
q-td(:props="props" align="right")
|
||||
q-btn(
|
||||
v-if="props.row.editable"
|
||||
flat
|
||||
dense
|
||||
no-caps
|
||||
color="negative"
|
||||
icon="fa-solid fa-trash"
|
||||
label="Удалить"
|
||||
@click="confirmRemove(props.row)"
|
||||
)
|
||||
span.text-grey-5(v-else) —
|
||||
|
||||
//- Диалог создания комнаты
|
||||
q-dialog(v-model="createDialog")
|
||||
q-card.sr-dialog
|
||||
q-card-section
|
||||
.text-h6 Новая комната секретаря
|
||||
q-card-section.q-pt-none
|
||||
q-input(
|
||||
v-model="form.displayName"
|
||||
label="Название комнаты"
|
||||
autofocus
|
||||
:rules="[(v) => !!v && v.trim().length > 0 || 'Введите название']"
|
||||
maxlength="240"
|
||||
)
|
||||
.sr-type.q-mt-md
|
||||
.text-subtitle2.q-mb-xs Тип комнаты
|
||||
q-option-group(
|
||||
v-model="form.isPublic"
|
||||
:options="typeOptions"
|
||||
color="primary"
|
||||
type="radio"
|
||||
)
|
||||
.text-caption.text-grey-7.q-mt-xs
|
||||
| {{ form.isPublic ? 'Публичная: войти может любой пайщик.' : 'Приватная: участников приглашаете вы (в клиенте мессенджера).' }}
|
||||
q-card-actions(align="right")
|
||||
q-btn(flat no-caps label="Отмена" v-close-popup :disable="store.isMutating")
|
||||
q-btn(
|
||||
unelevated
|
||||
no-caps
|
||||
color="primary"
|
||||
label="Создать"
|
||||
:loading="store.isMutating"
|
||||
@click="submitCreate"
|
||||
)
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useSecretaryRoomStore } from '../../../entities/SecretaryRoom';
|
||||
import type { ISecretaryRoom } from '../../../entities/SecretaryRoom';
|
||||
|
||||
const $q = useQuasar();
|
||||
const store = useSecretaryRoomStore();
|
||||
|
||||
const createDialog = ref(false);
|
||||
const form = ref<{ displayName: string; isPublic: boolean }>({
|
||||
displayName: '',
|
||||
isPublic: false,
|
||||
});
|
||||
|
||||
const typeOptions = [
|
||||
{ label: 'Приватная (по приглашению)', value: false },
|
||||
{ label: 'Публичная (открытый вход)', value: true },
|
||||
];
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: 'displayLabel',
|
||||
label: 'Комната',
|
||||
field: 'displayLabel',
|
||||
align: 'left' as const,
|
||||
style: 'min-width: 320px;',
|
||||
},
|
||||
{ name: 'kind', label: 'Тип', field: 'kind', align: 'left' as const },
|
||||
{ name: 'secretary', label: 'Секретарь', field: 'secretaryInRoom', align: 'left' as const },
|
||||
{ name: 'actions', label: '', field: 'actions', align: 'right' as const },
|
||||
];
|
||||
|
||||
function kindLabel(kind: ISecretaryRoom['kind']): string {
|
||||
switch (kind) {
|
||||
case 'MEMBERS':
|
||||
return 'Пайщики';
|
||||
case 'COUNCIL':
|
||||
return 'Совет';
|
||||
case 'CAPITAL_PROJECT':
|
||||
return 'Проект';
|
||||
case 'SECRETARY':
|
||||
return 'Секретарь';
|
||||
default:
|
||||
return String(kind);
|
||||
}
|
||||
}
|
||||
|
||||
function kindColor(kind: ISecretaryRoom['kind']): string {
|
||||
switch (kind) {
|
||||
case 'SECRETARY':
|
||||
return 'primary';
|
||||
case 'CAPITAL_PROJECT':
|
||||
return 'teal';
|
||||
default:
|
||||
return 'grey-7';
|
||||
}
|
||||
}
|
||||
|
||||
function openCreateDialog(): void {
|
||||
form.value = { displayName: '', isPublic: false };
|
||||
store.clearError();
|
||||
createDialog.value = true;
|
||||
}
|
||||
|
||||
async function submitCreate(): Promise<void> {
|
||||
const name = form.value.displayName.trim();
|
||||
if (name.length === 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await store.createRoom({ displayName: name, isPublic: form.value.isPublic });
|
||||
createDialog.value = false;
|
||||
$q.notify({ type: 'positive', message: 'Комната создана, секретарь подключён' });
|
||||
} catch (err) {
|
||||
$q.notify({ type: 'negative', message: extractError(err) });
|
||||
}
|
||||
}
|
||||
|
||||
function confirmRemove(room: ISecretaryRoom): void {
|
||||
$q.dialog({
|
||||
title: 'Удалить комнату секретаря?',
|
||||
message: `Секретарь выйдет из «${room.displayLabel}», комната перестанет транскрибироваться и синхронизироваться.`,
|
||||
cancel: { label: 'Отмена', flat: true, noCaps: true },
|
||||
ok: { label: 'Удалить', color: 'negative', noCaps: true, unelevated: true },
|
||||
persistent: true,
|
||||
}).onOk(async () => {
|
||||
try {
|
||||
await store.removeRoom(room.matrixRoomId);
|
||||
$q.notify({ type: 'positive', message: 'Комната удалена' });
|
||||
} catch (err) {
|
||||
$q.notify({ type: 'negative', message: extractError(err) });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function extractError(err: unknown): string {
|
||||
if (err instanceof Error) {
|
||||
return err.message;
|
||||
}
|
||||
return 'Не удалось выполнить операцию';
|
||||
}
|
||||
|
||||
async function handleRefresh(): Promise<void> {
|
||||
await store.loadRooms();
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await store.loadRooms();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sr-head {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.sr-head__title {
|
||||
margin: 0;
|
||||
font-size: 1.35rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.sr-head__subtitle {
|
||||
margin: 6px 0 0;
|
||||
font-size: 0.8125rem;
|
||||
line-height: 1.45;
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
max-width: 48rem;
|
||||
}
|
||||
|
||||
.body--dark .sr-head__subtitle {
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
}
|
||||
|
||||
.sr-head__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sr-name {
|
||||
font-weight: 500;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.sr-room-id {
|
||||
margin-top: 2px;
|
||||
font-size: 0.75rem;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.body--dark .sr-room-id {
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
}
|
||||
|
||||
.sr-dialog {
|
||||
width: 460px;
|
||||
max-width: 90vw;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1 @@
|
||||
export { default as SecretaryRoomsPage } from './SecretaryRoomsPage.vue'
|
||||
@@ -1,5 +1,6 @@
|
||||
export { CalendarPage } from './CalendarPage';
|
||||
export { ChatCoopPage } from './ChatCoopPage';
|
||||
export { MobileClientPage } from './MobileClientPage';
|
||||
export { SecretaryRoomsPage } from './SecretaryRoomsPage';
|
||||
export { TranscriptionsPage } from './TranscriptionsPage';
|
||||
export { TranscriptionDetailPage } from './TranscriptionDetailPage';
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Реализация — ChatcoopCalendarEventNotificationService; токен INTER_COOP_CALENDAR_EVENT_NOTIFICATION в ChatCoopPluginModule.
|
||||
*/
|
||||
/** Совпадает с ChatcoopManagedMatrixRoomKind в реестре управляемых комнат. */
|
||||
export type InterCoopCalendarNotificationRoomKind = 'members' | 'council' | 'capital_project';
|
||||
export type InterCoopCalendarNotificationRoomKind = 'members' | 'council' | 'capital_project' | 'secretary';
|
||||
|
||||
export interface InterCoopCalendarEventNotificationInput {
|
||||
title: string;
|
||||
|
||||
@@ -30,6 +30,8 @@ export type {
|
||||
|
||||
export type {
|
||||
InterCompletedCallTranscriptionHead,
|
||||
InterNonProjectCommunicationRoomRef,
|
||||
InterNonProjectRoomKind,
|
||||
InterProjectCommunicationArtifactsPort,
|
||||
InterProjectCommunicationRoomRef,
|
||||
InterRoomMessageKind,
|
||||
|
||||
@@ -26,9 +26,22 @@ export interface InterProjectCommunicationRoomRef {
|
||||
displayLabel: string;
|
||||
}
|
||||
|
||||
/** Тип непроектной комнаты ChatCoop, синхронизируемой в blago отдельной верхней папкой. */
|
||||
export type InterNonProjectRoomKind = 'members' | 'council' | 'secretary';
|
||||
|
||||
/** Комната ChatCoop вне проекта Capital (пайщики/совет/секретарь) — для синхронизации переписки и транскрипций в blago. */
|
||||
export interface InterNonProjectCommunicationRoomRef {
|
||||
matrixRoomId: string;
|
||||
displayLabel: string;
|
||||
kind: InterNonProjectRoomKind;
|
||||
}
|
||||
|
||||
export interface InterProjectCommunicationArtifactsPort {
|
||||
listCommunicationRoomsForProject(projectHash: string): Promise<InterProjectCommunicationRoomRef[]>;
|
||||
|
||||
/** Комнаты вне проектов Capital (пайщики/совет/секретарь) — синхронизируются в blago отдельной верхней папкой. */
|
||||
listNonProjectCommunicationRooms(): Promise<InterNonProjectCommunicationRoomRef[]>;
|
||||
|
||||
listUtcDatesWithNewMessages(
|
||||
matrixRoomId: string,
|
||||
afterOriginServerTsExclusive: number
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { rawChatcoopSecretaryRoomSelector } from '../../selectors/chatcoop/secretaryRoom'
|
||||
import { $, type GraphQLTypes, type InputType, type ModelTypes, Selector } from '../../zeus/index'
|
||||
|
||||
export const name = 'chatcoopCreateSecretaryRoom'
|
||||
|
||||
export const mutation = Selector('Mutation')({
|
||||
[name]: [{ data: $('data', 'CreateSecretaryRoomInput!') }, rawChatcoopSecretaryRoomSelector],
|
||||
})
|
||||
|
||||
export interface IInput {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
[key: string]: unknown
|
||||
|
||||
data: ModelTypes['CreateSecretaryRoomInput']
|
||||
}
|
||||
|
||||
export type IOutput = InputType<GraphQLTypes['Mutation'], typeof mutation>
|
||||
@@ -1,6 +1,8 @@
|
||||
export * as CreateAccount from './createAccount'
|
||||
export * as CreateCalendarEvent from './createCalendarEvent'
|
||||
export * as CreateCalendarIcsSubscription from './createCalendarIcsSubscription'
|
||||
export * as CreateSecretaryRoom from './createSecretaryRoom'
|
||||
export * as DeleteCalendarEvent from './deleteCalendarEvent'
|
||||
export * as RemoveSecretaryRoom from './removeSecretaryRoom'
|
||||
export * as UpdateCalendarEvent from './updateCalendarEvent'
|
||||
export * as UpdateTranscriptionMemo from './updateTranscriptionMemo'
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { $, type GraphQLTypes, type InputType, type ModelTypes, Selector } from '../../zeus/index'
|
||||
|
||||
export const name = 'chatcoopRemoveSecretaryRoom'
|
||||
|
||||
export const mutation = Selector('Mutation')({
|
||||
[name]: [{ data: $('data', 'RemoveSecretaryRoomInput!') }, true],
|
||||
})
|
||||
|
||||
export interface IInput {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
[key: string]: unknown
|
||||
|
||||
data: ModelTypes['RemoveSecretaryRoomInput']
|
||||
}
|
||||
|
||||
export type IOutput = InputType<GraphQLTypes['Mutation'], typeof mutation>
|
||||
@@ -6,5 +6,7 @@ export * as GetTranscription from './getTranscription'
|
||||
export * as GetTranscriptions from './getTranscriptions'
|
||||
export * as ListCalendarEvents from './listCalendarEvents'
|
||||
export * as ListCalendarRooms from './listCalendarRooms'
|
||||
export * as ListNonProjectCommunicationRooms from './listNonProjectCommunicationRooms'
|
||||
export * as ListProjectCommunicationRooms from './listProjectCommunicationRooms'
|
||||
export * as ListSecretaryRooms from './listSecretaryRooms'
|
||||
export * as ListUtcDatesWithNewRoomMessages from './listUtcDatesWithNewRoomMessages'
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { rawChatcoopNonProjectCommunicationRoomSelector } from '../../selectors/chatcoop/projectCommunication'
|
||||
import { type GraphQLTypes, type InputType, Selector } from '../../zeus/index'
|
||||
|
||||
export const name = 'chatcoopListNonProjectCommunicationRooms'
|
||||
|
||||
export const query = Selector('Query')({
|
||||
[name]: rawChatcoopNonProjectCommunicationRoomSelector,
|
||||
})
|
||||
|
||||
export type IOutput = InputType<GraphQLTypes['Query'], typeof query>
|
||||
@@ -0,0 +1,10 @@
|
||||
import { rawChatcoopSecretaryRoomSelector } from '../../selectors/chatcoop/secretaryRoom'
|
||||
import { type GraphQLTypes, type InputType, Selector } from '../../zeus/index'
|
||||
|
||||
export const name = 'chatcoopListSecretaryRooms'
|
||||
|
||||
export const query = Selector('Query')({
|
||||
[name]: rawChatcoopSecretaryRoomSelector,
|
||||
})
|
||||
|
||||
export type IOutput = InputType<GraphQLTypes['Query'], typeof query>
|
||||
@@ -61,5 +61,6 @@ export const chatCoopCalendarIcsUrlSelector = Selector('ChatCoopCalendarIcsUrlRe
|
||||
)
|
||||
|
||||
export * from './projectCommunication'
|
||||
export * from './secretaryRoom'
|
||||
// Экспорт селекторов для транскрипций
|
||||
export * from './transcription'
|
||||
|
||||
@@ -16,6 +16,22 @@ export const chatcoopProjectCommunicationRoomSelector = Selector('ChatcoopProjec
|
||||
)
|
||||
export { rawChatcoopProjectCommunicationRoomSelector }
|
||||
|
||||
const rawChatcoopNonProjectCommunicationRoomSelector = {
|
||||
matrixRoomId: true,
|
||||
displayLabel: true,
|
||||
kind: true,
|
||||
}
|
||||
|
||||
const _validateNonProjectRoom: MakeAllFieldsRequired<ValueTypes['ChatcoopNonProjectCommunicationRoom']> =
|
||||
rawChatcoopNonProjectCommunicationRoomSelector
|
||||
|
||||
export type ChatcoopNonProjectCommunicationRoomModel = ModelTypes['ChatcoopNonProjectCommunicationRoom']
|
||||
|
||||
export const chatcoopNonProjectCommunicationRoomSelector = Selector('ChatcoopNonProjectCommunicationRoom')(
|
||||
rawChatcoopNonProjectCommunicationRoomSelector,
|
||||
)
|
||||
export { rawChatcoopNonProjectCommunicationRoomSelector }
|
||||
|
||||
const rawChatcoopRoomMessageLineSelector = {
|
||||
originServerTs: true,
|
||||
authorLabel: true,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { MakeAllFieldsRequired } from '../../utils/MakeAllFieldsRequired'
|
||||
import { type ModelTypes, Selector, type ValueTypes } from '../../zeus/index'
|
||||
|
||||
const rawChatcoopSecretaryRoomSelector = {
|
||||
matrixRoomId: true,
|
||||
displayLabel: true,
|
||||
kind: true,
|
||||
encrypted: true,
|
||||
secretaryInRoom: true,
|
||||
editable: true,
|
||||
}
|
||||
|
||||
const _validateSecretaryRoom: MakeAllFieldsRequired<ValueTypes['ChatcoopSecretaryRoom']> =
|
||||
rawChatcoopSecretaryRoomSelector
|
||||
|
||||
export type ChatcoopSecretaryRoomModel = ModelTypes['ChatcoopSecretaryRoom']
|
||||
|
||||
export const chatcoopSecretaryRoomSelector = Selector('ChatcoopSecretaryRoom')(
|
||||
rawChatcoopSecretaryRoomSelector,
|
||||
)
|
||||
export { rawChatcoopSecretaryRoomSelector }
|
||||
@@ -341,6 +341,9 @@ export const AllTypesProps: Record<string,any> = {
|
||||
},
|
||||
CreateProjectPropertyInput:{
|
||||
|
||||
},
|
||||
CreateSecretaryRoomInput:{
|
||||
|
||||
},
|
||||
CreateSovietIndividualDataInput:{
|
||||
passport:"PassportInput"
|
||||
@@ -617,6 +620,7 @@ export const AllTypesProps: Record<string,any> = {
|
||||
MakeClearanceInput:{
|
||||
document:"SignedDigitalDocumentInput"
|
||||
},
|
||||
ManagedRoomKind: "enum" as const,
|
||||
MarkReportPeriodInput:{
|
||||
mark:"ReportSubmissionMark",
|
||||
reportType:"ReportType"
|
||||
@@ -899,8 +903,14 @@ export const AllTypesProps: Record<string,any> = {
|
||||
chatcoopCreateCalendarEvent:{
|
||||
data:"CreateChatCoopCalendarEventInput"
|
||||
},
|
||||
chatcoopCreateSecretaryRoom:{
|
||||
data:"CreateSecretaryRoomInput"
|
||||
},
|
||||
chatcoopDeleteCalendarEvent:{
|
||||
|
||||
},
|
||||
chatcoopRemoveSecretaryRoom:{
|
||||
data:"RemoveSecretaryRoomInput"
|
||||
},
|
||||
chatcoopUpdateCalendarEvent:{
|
||||
data:"UpdateChatCoopCalendarEventInput"
|
||||
@@ -1214,6 +1224,7 @@ export const AllTypesProps: Record<string,any> = {
|
||||
input:"WalmoveInput"
|
||||
}
|
||||
},
|
||||
NonProjectRoomKind: "enum" as const,
|
||||
NotificationWorkflowRecipientInput:{
|
||||
|
||||
},
|
||||
@@ -1643,6 +1654,9 @@ export const AllTypesProps: Record<string,any> = {
|
||||
statement:"ParticipantApplicationSignedDocumentInput",
|
||||
user_agreement:"SignedDigitalDocumentInput",
|
||||
wallet_agreement:"SignedDigitalDocumentInput"
|
||||
},
|
||||
RemoveSecretaryRoomInput:{
|
||||
|
||||
},
|
||||
ReportHistoryFilterInput:{
|
||||
reportType:"ReportType"
|
||||
@@ -2920,6 +2934,11 @@ export const ReturnTypes: Record<string,any> = {
|
||||
displayLabel:"String",
|
||||
matrixRoomId:"String"
|
||||
},
|
||||
ChatcoopNonProjectCommunicationRoom:{
|
||||
displayLabel:"String",
|
||||
kind:"NonProjectRoomKind",
|
||||
matrixRoomId:"String"
|
||||
},
|
||||
ChatcoopProjectCommunicationRoom:{
|
||||
displayLabel:"String",
|
||||
matrixRoomId:"String"
|
||||
@@ -2931,6 +2950,14 @@ export const ReturnTypes: Record<string,any> = {
|
||||
kind:"RoomMessageKind",
|
||||
originServerTs:"Float"
|
||||
},
|
||||
ChatcoopSecretaryRoom:{
|
||||
displayLabel:"String",
|
||||
editable:"Boolean",
|
||||
encrypted:"Boolean",
|
||||
kind:"ManagedRoomKind",
|
||||
matrixRoomId:"String",
|
||||
secretaryInRoom:"Boolean"
|
||||
},
|
||||
ContactsDTO:{
|
||||
chairman:"PublicChairman",
|
||||
details:"OrganizationDetails",
|
||||
@@ -3559,7 +3586,9 @@ export const ReturnTypes: Record<string,any> = {
|
||||
chatcoopCreateAccount:"Boolean",
|
||||
chatcoopCreateCalendarEvent:"ChatCoopCalendarEvent",
|
||||
chatcoopCreateCalendarIcsSubscription:"ChatCoopCalendarIcsUrlResponse",
|
||||
chatcoopCreateSecretaryRoom:"ChatcoopSecretaryRoom",
|
||||
chatcoopDeleteCalendarEvent:"Boolean",
|
||||
chatcoopRemoveSecretaryRoom:"String",
|
||||
chatcoopUpdateCalendarEvent:"ChatCoopCalendarEvent",
|
||||
chatcoopUpdateTranscriptionMemo:"CallTranscription",
|
||||
completeCapitalOnboardingStep:"CapitalOnboardingState",
|
||||
@@ -4128,7 +4157,9 @@ export const ReturnTypes: Record<string,any> = {
|
||||
chatcoopGetTranscriptions:"CallTranscription",
|
||||
chatcoopListCalendarEvents:"ChatCoopCalendarEvent",
|
||||
chatcoopListCalendarRooms:"ChatCoopCalendarRoomOption",
|
||||
chatcoopListNonProjectCommunicationRooms:"ChatcoopNonProjectCommunicationRoom",
|
||||
chatcoopListProjectCommunicationRooms:"ChatcoopProjectCommunicationRoom",
|
||||
chatcoopListSecretaryRooms:"ChatcoopSecretaryRoom",
|
||||
chatcoopListUtcDatesWithNewRoomMessages:"String",
|
||||
checkReportReadiness:"ReportReadinessView",
|
||||
cooperativeAgreements:"CoopAgreement",
|
||||
|
||||
@@ -3851,6 +3851,16 @@ export type ValueTypes = {
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on ChatCoopCalendarRoomOption']?: Omit<ValueTypes["ChatCoopCalendarRoomOption"], "...on ChatCoopCalendarRoomOption">
|
||||
}>;
|
||||
["ChatcoopNonProjectCommunicationRoom"]: AliasType<{
|
||||
/** Подпись для отображения комнаты */
|
||||
displayLabel?:boolean | `@${string}`,
|
||||
/** Тип комнаты (пайщики / совет / секретарь) */
|
||||
kind?:boolean | `@${string}`,
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on ChatcoopNonProjectCommunicationRoom']?: Omit<ValueTypes["ChatcoopNonProjectCommunicationRoom"], "...on ChatcoopNonProjectCommunicationRoom">
|
||||
}>;
|
||||
["ChatcoopProjectCommunicationRoom"]: AliasType<{
|
||||
/** Подпись для отображения (комната / проект Capital) */
|
||||
@@ -3872,6 +3882,22 @@ export type ValueTypes = {
|
||||
originServerTs?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on ChatcoopRoomMessageLine']?: Omit<ValueTypes["ChatcoopRoomMessageLine"], "...on ChatcoopRoomMessageLine">
|
||||
}>;
|
||||
["ChatcoopSecretaryRoom"]: AliasType<{
|
||||
/** Название комнаты */
|
||||
displayLabel?:boolean | `@${string}`,
|
||||
/** Можно ли удалить комнату из интерфейса (только комнаты секретаря) */
|
||||
editable?:boolean | `@${string}`,
|
||||
/** Комната зашифрована (E2EE) — секретарь не транскрибирует такие комнаты */
|
||||
encrypted?:boolean | `@${string}`,
|
||||
/** Тип комнаты */
|
||||
kind?:boolean | `@${string}`,
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
/** Секретарь присутствует в комнате */
|
||||
secretaryInRoom?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on ChatcoopSecretaryRoom']?: Omit<ValueTypes["ChatcoopSecretaryRoom"], "...on ChatcoopSecretaryRoom">
|
||||
}>;
|
||||
["CheckMatrixUsernameInput"]: {
|
||||
username: string | Variable<any, string>
|
||||
@@ -4604,6 +4630,12 @@ export type ValueTypes = {
|
||||
property_hash: string | Variable<any, string>,
|
||||
/** Имя пользователя */
|
||||
username: string | Variable<any, string>
|
||||
};
|
||||
["CreateSecretaryRoomInput"]: {
|
||||
/** Название комнаты */
|
||||
displayName: string | Variable<any, string>,
|
||||
/** Публичная комната (любой может войти) либо приватная (вход по приглашению создателя) */
|
||||
isPublic: boolean | Variable<any, string>
|
||||
};
|
||||
["CreateSovietIndividualDataInput"]: {
|
||||
/** Дата рождения */
|
||||
@@ -6143,6 +6175,8 @@ export type ValueTypes = {
|
||||
/** Имя пользователя */
|
||||
username: string | Variable<any, string>
|
||||
};
|
||||
/** Тип комнаты: пайщики, совет, проект Capital, комната секретаря */
|
||||
["ManagedRoomKind"]:ManagedRoomKind;
|
||||
["MarkReportPeriodInput"]: {
|
||||
mark?: ValueTypes["ReportSubmissionMark"] | undefined | null | Variable<any, string>,
|
||||
period?: number | undefined | null | Variable<any, string>,
|
||||
@@ -6466,7 +6500,9 @@ chatcoopCreateCalendarEvent?: [{ data: ValueTypes["CreateChatCoopCalendarEventIn
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopCreateCalendarIcsSubscription?:ValueTypes["ChatCoopCalendarIcsUrlResponse"],
|
||||
chatcoopCreateSecretaryRoom?: [{ data: ValueTypes["CreateSecretaryRoomInput"] | Variable<any, string>},ValueTypes["ChatcoopSecretaryRoom"]],
|
||||
chatcoopDeleteCalendarEvent?: [{ id: string | Variable<any, string>},boolean | `@${string}`],
|
||||
chatcoopRemoveSecretaryRoom?: [{ data: ValueTypes["RemoveSecretaryRoomInput"] | Variable<any, string>},boolean | `@${string}`],
|
||||
chatcoopUpdateCalendarEvent?: [{ data: ValueTypes["UpdateChatCoopCalendarEventInput"] | Variable<any, string>},ValueTypes["ChatCoopCalendarEvent"]],
|
||||
chatcoopUpdateTranscriptionMemo?: [{ data: ValueTypes["UpdateCallTranscriptionMemoInput"] | Variable<any, string>},ValueTypes["CallTranscription"]],
|
||||
completeCapitalOnboardingStep?: [{ data: ValueTypes["CapitalOnboardingStepInput"] | Variable<any, string>},ValueTypes["CapitalOnboardingState"]],
|
||||
@@ -6566,6 +6602,8 @@ walmoveWallets?: [{ input: ValueTypes["WalmoveInput"] | Variable<any, string>},V
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on Mutation']?: Omit<ValueTypes["Mutation"], "...on Mutation">
|
||||
}>;
|
||||
/** Тип комнаты вне проекта: пайщики, совет, комната секретаря */
|
||||
["NonProjectRoomKind"]:NonProjectRoomKind;
|
||||
["NotificationWorkflowRecipientInput"]: {
|
||||
/** Username получателя */
|
||||
username: string | Variable<any, string>
|
||||
@@ -7774,7 +7812,15 @@ chatcoopGetTranscriptions?: [{ data?: ValueTypes["GetTranscriptionsInput"] | und
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListCalendarRooms?:ValueTypes["ChatCoopCalendarRoomOption"],
|
||||
/** Комнаты Matrix вне проектов Capital (пайщики/совет/секретарь) — для синхронизации в blago
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListNonProjectCommunicationRooms?:ValueTypes["ChatcoopNonProjectCommunicationRoom"],
|
||||
chatcoopListProjectCommunicationRooms?: [{ data: ValueTypes["GetProjectCommunicationRoomsInput"] | Variable<any, string>},ValueTypes["ChatcoopProjectCommunicationRoom"]],
|
||||
/** Все комнаты реестра ChatCoop (системные/проектные — read-only, комнаты секретаря — удаляемые)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListSecretaryRooms?:ValueTypes["ChatcoopSecretaryRoom"],
|
||||
chatcoopListUtcDatesWithNewRoomMessages?: [{ data: ValueTypes["ListUtcDatesWithNewRoomMessagesInput"] | Variable<any, string>},boolean | `@${string}`],
|
||||
checkReportReadiness?: [{ reportType: ValueTypes["ReportType"] | Variable<any, string>},ValueTypes["ReportReadinessView"]],
|
||||
cooperativeAgreements?: [{ coopname: string | Variable<any, string>},ValueTypes["CoopAgreement"]],
|
||||
@@ -8047,6 +8093,10 @@ validateReportEdits?: [{ editsJson: string | Variable<any, string>, reportType:
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on RegistrationProgram']?: Omit<ValueTypes["RegistrationProgram"], "...on RegistrationProgram">
|
||||
}>;
|
||||
["RemoveSecretaryRoomInput"]: {
|
||||
/** Идентификатор комнаты Matrix, которую нужно удалить */
|
||||
matrixRoomId: string | Variable<any, string>
|
||||
};
|
||||
["ReportCalendarPeriodEntry"]: AliasType<{
|
||||
dueDate?:boolean | `@${string}`,
|
||||
dueMonth?:boolean | `@${string}`,
|
||||
@@ -12194,6 +12244,15 @@ export type ResolverInputTypes = {
|
||||
displayLabel?:boolean | `@${string}`,
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["ChatcoopNonProjectCommunicationRoom"]: AliasType<{
|
||||
/** Подпись для отображения комнаты */
|
||||
displayLabel?:boolean | `@${string}`,
|
||||
/** Тип комнаты (пайщики / совет / секретарь) */
|
||||
kind?:boolean | `@${string}`,
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["ChatcoopProjectCommunicationRoom"]: AliasType<{
|
||||
/** Подпись для отображения (комната / проект Capital) */
|
||||
@@ -12213,6 +12272,21 @@ export type ResolverInputTypes = {
|
||||
/** origin_server_ts из Matrix (мс) */
|
||||
originServerTs?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["ChatcoopSecretaryRoom"]: AliasType<{
|
||||
/** Название комнаты */
|
||||
displayLabel?:boolean | `@${string}`,
|
||||
/** Можно ли удалить комнату из интерфейса (только комнаты секретаря) */
|
||||
editable?:boolean | `@${string}`,
|
||||
/** Комната зашифрована (E2EE) — секретарь не транскрибирует такие комнаты */
|
||||
encrypted?:boolean | `@${string}`,
|
||||
/** Тип комнаты */
|
||||
kind?:boolean | `@${string}`,
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId?:boolean | `@${string}`,
|
||||
/** Секретарь присутствует в комнате */
|
||||
secretaryInRoom?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["CheckMatrixUsernameInput"]: {
|
||||
username: string
|
||||
@@ -12940,6 +13014,12 @@ export type ResolverInputTypes = {
|
||||
property_hash: string,
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
["CreateSecretaryRoomInput"]: {
|
||||
/** Название комнаты */
|
||||
displayName: string,
|
||||
/** Публичная комната (любой может войти) либо приватная (вход по приглашению создателя) */
|
||||
isPublic: boolean
|
||||
};
|
||||
["CreateSovietIndividualDataInput"]: {
|
||||
/** Дата рождения */
|
||||
@@ -14435,6 +14515,8 @@ export type ResolverInputTypes = {
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
/** Тип комнаты: пайщики, совет, проект Capital, комната секретаря */
|
||||
["ManagedRoomKind"]:ManagedRoomKind;
|
||||
["MarkReportPeriodInput"]: {
|
||||
mark?: ResolverInputTypes["ReportSubmissionMark"] | undefined | null,
|
||||
period?: number | undefined | null,
|
||||
@@ -14749,7 +14831,9 @@ chatcoopCreateCalendarEvent?: [{ data: ResolverInputTypes["CreateChatCoopCalenda
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopCreateCalendarIcsSubscription?:ResolverInputTypes["ChatCoopCalendarIcsUrlResponse"],
|
||||
chatcoopCreateSecretaryRoom?: [{ data: ResolverInputTypes["CreateSecretaryRoomInput"]},ResolverInputTypes["ChatcoopSecretaryRoom"]],
|
||||
chatcoopDeleteCalendarEvent?: [{ id: string},boolean | `@${string}`],
|
||||
chatcoopRemoveSecretaryRoom?: [{ data: ResolverInputTypes["RemoveSecretaryRoomInput"]},boolean | `@${string}`],
|
||||
chatcoopUpdateCalendarEvent?: [{ data: ResolverInputTypes["UpdateChatCoopCalendarEventInput"]},ResolverInputTypes["ChatCoopCalendarEvent"]],
|
||||
chatcoopUpdateTranscriptionMemo?: [{ data: ResolverInputTypes["UpdateCallTranscriptionMemoInput"]},ResolverInputTypes["CallTranscription"]],
|
||||
completeCapitalOnboardingStep?: [{ data: ResolverInputTypes["CapitalOnboardingStepInput"]},ResolverInputTypes["CapitalOnboardingState"]],
|
||||
@@ -14848,6 +14932,8 @@ voteOnAnnualGeneralMeet?: [{ data: ResolverInputTypes["VoteOnAnnualGeneralMeetIn
|
||||
walmoveWallets?: [{ input: ResolverInputTypes["WalmoveInput"]},ResolverInputTypes["Ledger2AdjustmentResult"]],
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
/** Тип комнаты вне проекта: пайщики, совет, комната секретаря */
|
||||
["NonProjectRoomKind"]:NonProjectRoomKind;
|
||||
["NotificationWorkflowRecipientInput"]: {
|
||||
/** Username получателя */
|
||||
username: string
|
||||
@@ -16002,7 +16088,15 @@ chatcoopGetTranscriptions?: [{ data?: ResolverInputTypes["GetTranscriptionsInput
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListCalendarRooms?:ResolverInputTypes["ChatCoopCalendarRoomOption"],
|
||||
/** Комнаты Matrix вне проектов Capital (пайщики/совет/секретарь) — для синхронизации в blago
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListNonProjectCommunicationRooms?:ResolverInputTypes["ChatcoopNonProjectCommunicationRoom"],
|
||||
chatcoopListProjectCommunicationRooms?: [{ data: ResolverInputTypes["GetProjectCommunicationRoomsInput"]},ResolverInputTypes["ChatcoopProjectCommunicationRoom"]],
|
||||
/** Все комнаты реестра ChatCoop (системные/проектные — read-only, комнаты секретаря — удаляемые)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListSecretaryRooms?:ResolverInputTypes["ChatcoopSecretaryRoom"],
|
||||
chatcoopListUtcDatesWithNewRoomMessages?: [{ data: ResolverInputTypes["ListUtcDatesWithNewRoomMessagesInput"]},boolean | `@${string}`],
|
||||
checkReportReadiness?: [{ reportType: ResolverInputTypes["ReportType"]},ResolverInputTypes["ReportReadinessView"]],
|
||||
cooperativeAgreements?: [{ coopname: string},ResolverInputTypes["CoopAgreement"]],
|
||||
@@ -16268,6 +16362,10 @@ validateReportEdits?: [{ editsJson: string, reportType: ResolverInputTypes["Repo
|
||||
title?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["RemoveSecretaryRoomInput"]: {
|
||||
/** Идентификатор комнаты Matrix, которую нужно удалить */
|
||||
matrixRoomId: string
|
||||
};
|
||||
["ReportCalendarPeriodEntry"]: AliasType<{
|
||||
dueDate?:boolean | `@${string}`,
|
||||
dueMonth?:boolean | `@${string}`,
|
||||
@@ -20303,6 +20401,14 @@ export type ModelTypes = {
|
||||
["ChatCoopCalendarRoomOption"]: {
|
||||
displayLabel: string,
|
||||
matrixRoomId: string
|
||||
};
|
||||
["ChatcoopNonProjectCommunicationRoom"]: {
|
||||
/** Подпись для отображения комнаты */
|
||||
displayLabel: string,
|
||||
/** Тип комнаты (пайщики / совет / секретарь) */
|
||||
kind: ModelTypes["NonProjectRoomKind"],
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId: string
|
||||
};
|
||||
["ChatcoopProjectCommunicationRoom"]: {
|
||||
/** Подпись для отображения (комната / проект Capital) */
|
||||
@@ -20320,6 +20426,20 @@ export type ModelTypes = {
|
||||
kind: ModelTypes["RoomMessageKind"],
|
||||
/** origin_server_ts из Matrix (мс) */
|
||||
originServerTs: number
|
||||
};
|
||||
["ChatcoopSecretaryRoom"]: {
|
||||
/** Название комнаты */
|
||||
displayLabel: string,
|
||||
/** Можно ли удалить комнату из интерфейса (только комнаты секретаря) */
|
||||
editable: boolean,
|
||||
/** Комната зашифрована (E2EE) — секретарь не транскрибирует такие комнаты */
|
||||
encrypted: boolean,
|
||||
/** Тип комнаты */
|
||||
kind: ModelTypes["ManagedRoomKind"],
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId: string,
|
||||
/** Секретарь присутствует в комнате */
|
||||
secretaryInRoom: boolean
|
||||
};
|
||||
["CheckMatrixUsernameInput"]: {
|
||||
username: string
|
||||
@@ -21039,6 +21159,12 @@ export type ModelTypes = {
|
||||
property_hash: string,
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
["CreateSecretaryRoomInput"]: {
|
||||
/** Название комнаты */
|
||||
displayName: string,
|
||||
/** Публичная комната (любой может войти) либо приватная (вход по приглашению создателя) */
|
||||
isPublic: boolean
|
||||
};
|
||||
["CreateSovietIndividualDataInput"]: {
|
||||
/** Дата рождения */
|
||||
@@ -22479,6 +22605,7 @@ export type ModelTypes = {
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
["ManagedRoomKind"]:ManagedRoomKind;
|
||||
["MarkReportPeriodInput"]: {
|
||||
mark?: ModelTypes["ReportSubmissionMark"] | undefined | null,
|
||||
period?: number | undefined | null,
|
||||
@@ -23023,10 +23150,18 @@ export type ModelTypes = {
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopCreateCalendarIcsSubscription: ModelTypes["ChatCoopCalendarIcsUrlResponse"],
|
||||
/** Создать комнату с секретарём (публичную или приватную); секретарь подключается сразу
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopCreateSecretaryRoom: ModelTypes["ChatcoopSecretaryRoom"],
|
||||
/** Удалить событие календаря
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopDeleteCalendarEvent: boolean,
|
||||
/** Удалить комнату секретаря: вывести секретаря и снять комнату с синхронизации (возвращает matrixRoomId)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopRemoveSecretaryRoom: string,
|
||||
/** Обновить событие календаря
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
@@ -23352,6 +23487,7 @@ export type ModelTypes = {
|
||||
Требуемые роли: chairman. */
|
||||
walmoveWallets: ModelTypes["Ledger2AdjustmentResult"]
|
||||
};
|
||||
["NonProjectRoomKind"]:NonProjectRoomKind;
|
||||
["NotificationWorkflowRecipientInput"]: {
|
||||
/** Username получателя */
|
||||
username: string
|
||||
@@ -24514,10 +24650,18 @@ export type ModelTypes = {
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListCalendarRooms: Array<ModelTypes["ChatCoopCalendarRoomOption"]>,
|
||||
/** Комнаты Matrix вне проектов Capital (пайщики/совет/секретарь) — для синхронизации в blago
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListNonProjectCommunicationRooms: Array<ModelTypes["ChatcoopNonProjectCommunicationRoom"]>,
|
||||
/** Комнаты Matrix, привязанные к проекту Capital (реестр ChatCoop)
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListProjectCommunicationRooms: Array<ModelTypes["ChatcoopProjectCommunicationRoom"]>,
|
||||
/** Все комнаты реестра ChatCoop (системные/проектные — read-only, комнаты секретаря — удаляемые)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListSecretaryRooms: Array<ModelTypes["ChatcoopSecretaryRoom"]>,
|
||||
/** UTC-даты (YYYY-MM-DD), в которых есть сообщения новее afterOriginServerTsExclusive, для комнаты Matrix
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
@@ -24890,6 +25034,10 @@ export type ModelTypes = {
|
||||
requirements?: string | undefined | null,
|
||||
/** Название программы для отображения */
|
||||
title: string
|
||||
};
|
||||
["RemoveSecretaryRoomInput"]: {
|
||||
/** Идентификатор комнаты Matrix, которую нужно удалить */
|
||||
matrixRoomId: string
|
||||
};
|
||||
["ReportCalendarPeriodEntry"]: {
|
||||
dueDate: string,
|
||||
@@ -29030,6 +29178,16 @@ export type GraphQLTypes = {
|
||||
displayLabel: string,
|
||||
matrixRoomId: string,
|
||||
['...on ChatCoopCalendarRoomOption']: Omit<GraphQLTypes["ChatCoopCalendarRoomOption"], "...on ChatCoopCalendarRoomOption">
|
||||
};
|
||||
["ChatcoopNonProjectCommunicationRoom"]: {
|
||||
__typename: "ChatcoopNonProjectCommunicationRoom",
|
||||
/** Подпись для отображения комнаты */
|
||||
displayLabel: string,
|
||||
/** Тип комнаты (пайщики / совет / секретарь) */
|
||||
kind: GraphQLTypes["NonProjectRoomKind"],
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId: string,
|
||||
['...on ChatcoopNonProjectCommunicationRoom']: Omit<GraphQLTypes["ChatcoopNonProjectCommunicationRoom"], "...on ChatcoopNonProjectCommunicationRoom">
|
||||
};
|
||||
["ChatcoopProjectCommunicationRoom"]: {
|
||||
__typename: "ChatcoopProjectCommunicationRoom",
|
||||
@@ -29051,6 +29209,22 @@ export type GraphQLTypes = {
|
||||
/** origin_server_ts из Matrix (мс) */
|
||||
originServerTs: number,
|
||||
['...on ChatcoopRoomMessageLine']: Omit<GraphQLTypes["ChatcoopRoomMessageLine"], "...on ChatcoopRoomMessageLine">
|
||||
};
|
||||
["ChatcoopSecretaryRoom"]: {
|
||||
__typename: "ChatcoopSecretaryRoom",
|
||||
/** Название комнаты */
|
||||
displayLabel: string,
|
||||
/** Можно ли удалить комнату из интерфейса (только комнаты секретаря) */
|
||||
editable: boolean,
|
||||
/** Комната зашифрована (E2EE) — секретарь не транскрибирует такие комнаты */
|
||||
encrypted: boolean,
|
||||
/** Тип комнаты */
|
||||
kind: GraphQLTypes["ManagedRoomKind"],
|
||||
/** Идентификатор комнаты Matrix */
|
||||
matrixRoomId: string,
|
||||
/** Секретарь присутствует в комнате */
|
||||
secretaryInRoom: boolean,
|
||||
['...on ChatcoopSecretaryRoom']: Omit<GraphQLTypes["ChatcoopSecretaryRoom"], "...on ChatcoopSecretaryRoom">
|
||||
};
|
||||
["CheckMatrixUsernameInput"]: {
|
||||
username: string
|
||||
@@ -29783,6 +29957,12 @@ export type GraphQLTypes = {
|
||||
property_hash: string,
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
["CreateSecretaryRoomInput"]: {
|
||||
/** Название комнаты */
|
||||
displayName: string,
|
||||
/** Публичная комната (любой может войти) либо приватная (вход по приглашению создателя) */
|
||||
isPublic: boolean
|
||||
};
|
||||
["CreateSovietIndividualDataInput"]: {
|
||||
/** Дата рождения */
|
||||
@@ -31322,6 +31502,8 @@ export type GraphQLTypes = {
|
||||
/** Имя пользователя */
|
||||
username: string
|
||||
};
|
||||
/** Тип комнаты: пайщики, совет, проект Capital, комната секретаря */
|
||||
["ManagedRoomKind"]: ManagedRoomKind;
|
||||
["MarkReportPeriodInput"]: {
|
||||
mark?: GraphQLTypes["ReportSubmissionMark"] | undefined | null,
|
||||
period?: number | undefined | null,
|
||||
@@ -31885,10 +32067,18 @@ export type GraphQLTypes = {
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopCreateCalendarIcsSubscription: GraphQLTypes["ChatCoopCalendarIcsUrlResponse"],
|
||||
/** Создать комнату с секретарём (публичную или приватную); секретарь подключается сразу
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopCreateSecretaryRoom: GraphQLTypes["ChatcoopSecretaryRoom"],
|
||||
/** Удалить событие календаря
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopDeleteCalendarEvent: boolean,
|
||||
/** Удалить комнату секретаря: вывести секретаря и снять комнату с синхронизации (возвращает matrixRoomId)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopRemoveSecretaryRoom: string,
|
||||
/** Обновить событие календаря
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
@@ -32215,6 +32405,8 @@ export type GraphQLTypes = {
|
||||
walmoveWallets: GraphQLTypes["Ledger2AdjustmentResult"],
|
||||
['...on Mutation']: Omit<GraphQLTypes["Mutation"], "...on Mutation">
|
||||
};
|
||||
/** Тип комнаты вне проекта: пайщики, совет, комната секретаря */
|
||||
["NonProjectRoomKind"]: NonProjectRoomKind;
|
||||
["NotificationWorkflowRecipientInput"]: {
|
||||
/** Username получателя */
|
||||
username: string
|
||||
@@ -33506,10 +33698,18 @@ export type GraphQLTypes = {
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListCalendarRooms: Array<GraphQLTypes["ChatCoopCalendarRoomOption"]>,
|
||||
/** Комнаты Matrix вне проектов Capital (пайщики/совет/секретарь) — для синхронизации в blago
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListNonProjectCommunicationRooms: Array<GraphQLTypes["ChatcoopNonProjectCommunicationRoom"]>,
|
||||
/** Комнаты Matrix, привязанные к проекту Capital (реестр ChatCoop)
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
chatcoopListProjectCommunicationRooms: Array<GraphQLTypes["ChatcoopProjectCommunicationRoom"]>,
|
||||
/** Все комнаты реестра ChatCoop (системные/проектные — read-only, комнаты секретаря — удаляемые)
|
||||
|
||||
Требуемые роли: chairman, member. */
|
||||
chatcoopListSecretaryRooms: Array<GraphQLTypes["ChatcoopSecretaryRoom"]>,
|
||||
/** UTC-даты (YYYY-MM-DD), в которых есть сообщения новее afterOriginServerTsExclusive, для комнаты Matrix
|
||||
|
||||
Требуемые роли: chairman, member, user. */
|
||||
@@ -33895,6 +34095,10 @@ export type GraphQLTypes = {
|
||||
/** Название программы для отображения */
|
||||
title: string,
|
||||
['...on RegistrationProgram']: Omit<GraphQLTypes["RegistrationProgram"], "...on RegistrationProgram">
|
||||
};
|
||||
["RemoveSecretaryRoomInput"]: {
|
||||
/** Идентификатор комнаты Matrix, которую нужно удалить */
|
||||
matrixRoomId: string
|
||||
};
|
||||
["ReportCalendarPeriodEntry"]: {
|
||||
__typename: "ReportCalendarPeriodEntry",
|
||||
@@ -35589,6 +35793,19 @@ export enum LogEventType {
|
||||
VOTING_COMPLETED = "VOTING_COMPLETED",
|
||||
VOTING_STARTED = "VOTING_STARTED"
|
||||
}
|
||||
/** Тип комнаты: пайщики, совет, проект Capital, комната секретаря */
|
||||
export enum ManagedRoomKind {
|
||||
CAPITAL_PROJECT = "CAPITAL_PROJECT",
|
||||
COUNCIL = "COUNCIL",
|
||||
MEMBERS = "MEMBERS",
|
||||
SECRETARY = "SECRETARY"
|
||||
}
|
||||
/** Тип комнаты вне проекта: пайщики, совет, комната секретаря */
|
||||
export enum NonProjectRoomKind {
|
||||
COUNCIL = "COUNCIL",
|
||||
MEMBERS = "MEMBERS",
|
||||
SECRETARY = "SECRETARY"
|
||||
}
|
||||
/** Тип юридического лица */
|
||||
export enum OrganizationType {
|
||||
AO = "AO",
|
||||
@@ -35856,6 +36073,7 @@ type ZEUS_VARIABLES = {
|
||||
["CreateProjectInput"]: ValueTypes["CreateProjectInput"];
|
||||
["CreateProjectInvestInput"]: ValueTypes["CreateProjectInvestInput"];
|
||||
["CreateProjectPropertyInput"]: ValueTypes["CreateProjectPropertyInput"];
|
||||
["CreateSecretaryRoomInput"]: ValueTypes["CreateSecretaryRoomInput"];
|
||||
["CreateSovietIndividualDataInput"]: ValueTypes["CreateSovietIndividualDataInput"];
|
||||
["CreateStoryInput"]: ValueTypes["CreateStoryInput"];
|
||||
["CreateSubscriptionInput"]: ValueTypes["CreateSubscriptionInput"];
|
||||
@@ -35953,9 +36171,11 @@ type ZEUS_VARIABLES = {
|
||||
["LoginInput"]: ValueTypes["LoginInput"];
|
||||
["LogoutInput"]: ValueTypes["LogoutInput"];
|
||||
["MakeClearanceInput"]: ValueTypes["MakeClearanceInput"];
|
||||
["ManagedRoomKind"]: ValueTypes["ManagedRoomKind"];
|
||||
["MarkReportPeriodInput"]: ValueTypes["MarkReportPeriodInput"];
|
||||
["ModerateRequestInput"]: ValueTypes["ModerateRequestInput"];
|
||||
["MoveCapitalIssueToComponentInput"]: ValueTypes["MoveCapitalIssueToComponentInput"];
|
||||
["NonProjectRoomKind"]: ValueTypes["NonProjectRoomKind"];
|
||||
["NotificationWorkflowRecipientInput"]: ValueTypes["NotificationWorkflowRecipientInput"];
|
||||
["NotifyOnAnnualGeneralMeetInput"]: ValueTypes["NotifyOnAnnualGeneralMeetInput"];
|
||||
["OpenProjectInput"]: ValueTypes["OpenProjectInput"];
|
||||
@@ -36001,6 +36221,7 @@ type ZEUS_VARIABLES = {
|
||||
["RegisterAccountInput"]: ValueTypes["RegisterAccountInput"];
|
||||
["RegisterContributorInput"]: ValueTypes["RegisterContributorInput"];
|
||||
["RegisterParticipantInput"]: ValueTypes["RegisterParticipantInput"];
|
||||
["RemoveSecretaryRoomInput"]: ValueTypes["RemoveSecretaryRoomInput"];
|
||||
["ReportHistoryFilterInput"]: ValueTypes["ReportHistoryFilterInput"];
|
||||
["ReportPreviewInput"]: ValueTypes["ReportPreviewInput"];
|
||||
["ReportSubmissionMark"]: ValueTypes["ReportSubmissionMark"];
|
||||
|
||||
Reference in New Issue
Block a user