scalar JSON type Query { hello: String boards(groupChatId: ID, onlyArchived: Boolean, limit: Int, beforeId: ID, afterId: ID): [Board!]! board(id: ID!): Board boardByNamespace(namespaceSlug: String!, boardCode: String!): Board boardMembers(boardId: ID!): [BoardMember!]! pendingInvitations(boardId: ID): [BoardInvitation!]! boardSettingsSchema(key: String): [SettingSchemaDef!]! taskStatuses(boardId: ID!): [TaskStatus!]! taskStatus(id: ID!): TaskStatus taskStatusByCode(boardId: ID!, code: String!): TaskStatus groupChats(page: Int, limit: Int): GroupChatsPage! allGroupChats(limit: Int, beforeId: ID, afterId: ID): [GroupChat!]! groupChat(id: ID!): GroupChat activeGroupChat: GroupChat tasks(boardId: ID, assigneeId: ID, creatorId: ID, groupChatId: ID, search: String): [Task!]! task(id: ID!, boardId: ID): Task userTasks(userId: ID!): [Task!]! tasksByStatus(statusId: ID!): [Task!]! searchTasks(query: String, assigneeId: ID, status: String, priority: String, attention: String, boardId: ID): [Task!]! myWork(namespaceSlug: String): [Task!]! me: User users(groupChatId: ID, boardId: ID): [User!]! user(id: ID!): User userByUsername(username: String!): User searchUsers(query: String!, limit: Int): [User!]! allUsers(limit: Int, before: String, after: String): [User!]! files: [File!]! file(id: ID!): File filesByObject(objectModel: String!, objectId: ID!): [File!]! filesByUploadType(uploadType: String!): [File!]! messages(limit: Int, beforeId: ID, afterId: ID): [Message!]! message(id: ID!): Message comments(taskId: ID!): [Comment!]! comment(id: ID!): Comment """Get activity logs with optional filters and pagination""" activityLogs(actions: [String!], userId: Int, telegramId: String, entityType: String, entityId: String, success: Boolean, dateFrom: String, dateTo: String, limit: Int, offset: Int): ActivityLogsResult! """Get a single activity log by ID""" activityLog(id: ID!): ActivityLog """Get activity logs for a specific entity""" activityLogsByEntity(entityType: String!, entityId: String!, limit: Int, offset: Int): ActivityLogsResult! """Get activity logs for a specific user""" activityLogsByUser(userId: Int!, limit: Int, offset: Int): ActivityLogsResult! """Get recent error logs""" activityLogErrors(limit: Int, offset: Int): ActivityLogsResult! """Get activity statistics for a time period""" activityLogStats(dateFrom: String!, dateTo: String!): ActivityLogStats! """Get all unique action types in the system""" activityLogActionTypes: [String!]! """Get all unique entity types in the system""" activityLogEntityTypes: [String!]! """Get activity logs for a specific task (board members only)""" taskActivityLogs(taskId: ID!, limit: Int, offset: Int): ActivityLogsResult! """ 294_v2_attention_activity: board-scoped activity feed (board members / public read — NOT superadmin-gated like the queries above). Returns recent ActivityLog entries for the board's tasks. Diagnostic fields (error, correlationId) are stripped from the projection. """ boardActivity(boardId: ID!, limit: Int, beforeId: ID): BoardActivityResult! apiKeys: [ApiKey!]! connectionConfigs: [ClientConfig!]! seoPage(slug: String!): SeoPage seoPageSlugs: [String!]! myNamespaces: [NamespaceSummary!]! namespaceBySlug(slug: String!): NamespaceSummary boardsInNamespace(namespaceSlug: String!, onlyArchived: Boolean): [Board!]! namespaceMembers(namespaceSlug: String!): [NamespaceMemberView!]! orgMembers(namespaceSlug: String!): [OrgMember!]! oauthClients: [OAuthClient!]! myDigest: DigestSummary! myDigestPreferences: DigestPreferences savedViews: [SavedView!]! productFunnel: FunnelReport! } type Mutation { hello: String createBoard(groupChatId: Int, title: String, namespaceSlug: String, code: String, visibility: String, template: String): Board! updateBoard(id: ID!, title: String, code: String, visibility: String): Board! updateBoardPrompt(id: ID!, prompt: String!): Board! updateBoardFile(boardId: ID!, name: String!, content: String, format: String): BoardFile! archiveBoard(id: ID!): Board! restoreBoard(id: ID!): Board! cloneBoard(sourceBoardId: ID!, title: String, code: String): Board! deleteBoard(id: ID!): Boolean! moveBoard(boardId: ID!, namespaceSlug: String!): Board! transferBoardOwnership(boardId: ID!, toUserId: ID!, demoteCurrentOwnerTo: String): Board! inviteBoardMember(boardId: ID!, username: String!, role: String): BoardInvitation! removeBoardMember(boardId: ID!, userId: ID!): Boolean! updateMemberRole(boardId: ID!, userId: ID!, role: String!): BoardMember! respondToInvitation(token: String!, accept: Boolean!): BoardInvitation! cancelBoardInvitation(invitationId: ID!): BoardInvitation! updateBoardSetting(boardId: ID!, key: String!, value: String!): BoardSettings! unlinkBoardGroupChat(boardId: ID!): Board! createTaskStatus(boardId: ID!, name: String!, code: String, color: String, index: Int): TaskStatus! updateTaskStatus(id: ID!, name: String, code: String, color: String, index: Int): TaskStatus! reorderTaskStatuses(boardId: ID!, orderedStatusIds: [ID!]!): Boolean! deleteTaskStatus(id: ID!): Boolean! createProject(title: String!, boardTitle: String): GroupChat! generateProjectTelegramLinkCode(projectId: ID!): ProjectTelegramLinkCode! setActiveGroupChat(groupChatId: ID!): GroupChat! groupChatUpdate(groupChatId: ID!, title: String): GroupChat! createTask(title: String!, description: String!, deadline: String, priority: TaskPriority, tags: [String!], assigneeId: String, boardId: ID!, statusId: ID, parentId: ID): Task! updateTask(id: ID, number: Int, boardId: ID!, title: String, description: String, deadline: String, priority: TaskPriority, tags: [String!], assigneeId: String, status: String, statusId: ID, parentId: ID): Task! deleteTask(id: ID, number: Int, boardId: ID!): Boolean! addChecklistItem(taskId: ID!, title: String!): ChecklistItem! updateChecklistItem(id: ID!, title: String, done: Boolean, sortOrder: Int): ChecklistItem! deleteChecklistItem(id: ID!): Boolean! reorderTasksInStatus(boardId: ID!, statusId: ID!, orderedTaskIds: [ID!]!): Boolean! createUser(telegramId: String!, username: String!, firstName: String, lastName: String): User! updateUser(id: ID!, username: String, firstName: String, lastName: String, timezone: String, slug: String): User! deleteUser(id: ID!): Boolean! updateFileCaption(id: ID!, caption: String!): File! deleteFile(id: ID!): Boolean! createComment(taskId: ID!, text: String!): Comment! updateComment(id: ID!, text: String!): Comment! deleteComment(id: ID!): Boolean! createApiKey(name: String!, scope: String): CreateApiKeyPayload! revokeApiKey(id: ID!): ApiKey! createPersonalProject(name: String!): NamespaceSummary! archiveNamespace(slug: String!): NamespaceSummary! updateNamespace(slug: String!, name: String, newSlug: String): NamespaceSummary! addNamespaceMember(namespaceSlug: String!, username: String!, role: String): NamespaceMemberView! updateNamespaceMemberRole(namespaceSlug: String!, userId: ID!, role: String!): NamespaceMemberView! removeNamespaceMember(namespaceSlug: String!, userId: ID!): Boolean! createOrganization(name: String!): Organization! createAgent(namespaceSlug: String!, username: String!, displayName: String, role: String): CreateAgentPayload! issueAgentKey(agentId: ID!, name: String, scope: String): IssueAgentKeyPayload! revokeAgentApiKey(keyId: ID!): RevokeAgentKeyPayload! deleteAgent(agentId: ID!): DeleteAgentPayload! createOAuthClient(input: CreateOAuthClientInput!): CreateOAuthClientPayload! revokeOAuthClient(id: ID!): OAuthClient! updateDigestPreferences(frequency: String, telegramEnabled: Boolean, webEnabled: Boolean): DigestPreferences! createSavedView(name: String!, filters: JSON!): SavedView! deleteSavedView(id: ID!): Boolean! } type Namespace { id: ID! slug: String! ownerType: String! ownerId: ID displayName: String! role: NamespaceRole! isPrimary: Boolean! archivedAt: String } type Board { id: ID! title: String! code: String namespaceId: ID namespace: Namespace groupChatId: ID creatorId: ID lastTaskNumber: ID! createdAt: String! updatedAt: String! timezone: String archivedAt: String visibility: String! prompt: String files: [BoardFile!]! access: BoardAccess! groupChat: GroupChat taskStatuses: [TaskStatus!]! tickets(limit: Int, beforeId: ID, afterId: ID): [Task!]! members: [BoardMember!]! creator: User settings: BoardSettings } type BoardSettings { autoAddAssignees: Boolean! } type LocalizedText { en: String! ru: String! } type SettingSchemaDef { key: String! type: String! default: String! title: LocalizedText! description: LocalizedText! } type BoardFile { id: ID! boardId: ID! name: String! content: String format: String! sortOrder: Int! createdAt: String! updatedAt: String! } type BoardAccess { isMember: Boolean! role: String isOwner: Boolean! isPublic: Boolean! isArchived: Boolean! readOnly: Boolean! canEdit: Boolean! canManage: Boolean! canClone: Boolean! canUseAssistant: Boolean! } type BoardMember { id: ID! userId: ID! boardId: ID! role: String! user: User! createdAt: String! } type BoardInvitation { id: ID! boardId: ID! invitedById: ID! inviteeId: ID! role: String! status: String! token: String board: Board! invitedBy: User! invitee: User! expiresAt: String createdAt: String! } type TaskStatus { id: ID! code: String! name: String! color: String index: Int! boardId: ID! createdAt: String! updatedAt: String! statusId: ID! } type GroupChat { id: ID! telegramId: String! telegramLinked: Boolean! title: String! username: String description: String users: [GroupChatUser!]! tasks: [Task!]! primaryBoard: Board boards: [Board!]! messages(limit: Int, beforeId: ID, afterId: ID): [Message!]! } type GroupChatUser { id: ID! user: User! groupChat: GroupChat! joinedAt: String! updatedAt: String! activeAt: String } type ProjectTelegramLinkCode { code: String! expiresAt: String! } type GroupChatsPage { items: [GroupChat!]! total: Int! page: Int! limit: Int! pages: Int! } enum TaskPriority { critical major normal low } type Task { id: ID! number: Int! title: String! text: String priority: TaskPriority! status: TaskStatus! statusId: ID! tags: [String!]! deadline: String assignee: User creator: User groupChat: GroupChat taskCode: String! boardId: ID! board: Board attention: String! parentId: ID parent: Task subtasks: [Task!]! subtasksCount: Int! checklist: [ChecklistItem!]! files: [File!]! comments: [Comment!]! commentsCount: Int! sortOrder: Int! updatedAt: String! createdAt: String! } type ChecklistItem { id: ID! title: String! done: Boolean! sortOrder: Int! } type User { id: ID! telegramId: String email: String username: String firstName: String lastName: String timezone: String type: String namespace: Namespace organizations: [Organization!]! tasks: [Task!]! systemRoles: [String!]! messages(limit: Int, before: String, after: String): [Message!]! } type File { id: ID! url: String! caption: String! originalName: String! fileName: String! storage: String path: String! uploadType: String! size: Int mimeType: String extension: String objectModel: String! objectId: ID! uploadedBy: User! metadata: JSON createdAt: String! updatedAt: String! } type Message { id: ID! content: String! isFromBot: Boolean! telegramMessageId: Int telegramChatId: String action: String task: Task user: User data: JSON createdAt: String! updatedAt: String! } type Comment { id: ID! text: String! task: Task! taskId: ID! author: User! authorId: ID! createdAt: String! updatedAt: String! } type ActivityLog { id: ID! action: String! correlationId: String userId: Int telegramId: String username: String entityType: String entityId: String metadata: JSON changes: JSON duration: Int success: Boolean! error: JSON createdAt: String! } type ActivityLogsResult { items: [ActivityLog!]! total: Int! hasMore: Boolean! } type BoardActivityResult { items: [ActivityLog!]! hasMore: Boolean! nextCursor: ID } type ActivityLogStats { total: Int! successful: Int! failed: Int! byAction: JSON! } type ApiKey { id: ID! name: String! keyPrefix: String! scope: String! commandCount: Int! health: String! lastUsedAt: String createdAt: String! revokedAt: String revoked: Boolean! } type CreateApiKeyPayload { apiKey: ApiKey! plainKey: String! } type ClientConfig { id: String! name: String! icon: String! fileLocation: String! } type SeoPageMeta { title: String! description: String! ogImage: String } type SeoPageBlock { component: String! props: JSON } type SeoPage { slug: String! meta: SeoPageMeta! blocks: [SeoPageBlock!]! } enum NamespaceRole { owner member } type NamespaceSummary { id: ID! slug: String! ownerType: String! ownerId: ID displayName: String! role: NamespaceRole! isPrimary: Boolean! archivedAt: String } type NamespaceMemberView { userId: ID! username: String firstName: String lastName: String type: String! role: String! source: String! } type Organization { id: ID! name: String! ownerId: ID! namespace: Namespace } type OrgMember { userId: ID! username: String firstName: String lastName: String type: String! role: String! activeKeys: Int! activeKeyIds: [ID!]! lastKeyUse: String createdAt: String! } type CreateAgentPayload { agent: OrgMember! plainKey: String! } type IssueAgentKeyPayload { apiKeyName: String! plainKey: String! } type RevokeAgentKeyPayload { apiKeyId: ID! } type DeleteAgentPayload { status: String! username: String } type OAuthClient { id: ID! clientId: String! name: String! redirectUris: [String!]! scopes: [String!]! revokedAt: String createdAt: String! } type CreateOAuthClientPayload { client: OAuthClient! plainSecret: String! } input CreateOAuthClientInput { name: String! redirectUris: [String!]! scopes: [String!] } type DigestTask { id: ID! number: Int! title: String! taskCode: String! deadline: String statusName: String priority: String boardId: ID! boardTitle: String } type DigestSummary { overdue: [DigestTask!]! stale: [DigestTask!]! newAssignments: [DigestTask!]! totalOpen: Int! completedRecently: Int! } type DigestPreferences { frequency: String! telegramEnabled: Boolean! webEnabled: Boolean! lastSentAt: String } type SavedView { id: ID! name: String! filters: JSON! createdAt: String! } type FunnelStage { eventType: String! total: Int! uniqueUsers: Int! } type ConversionRate { from: String! to: String! rate: Float! } type FunnelReport { stages: [FunnelStage!]! conversionRates: [ConversionRate!]! }