"""Корневой тип запросов публичного API Таски. """ type Query { """ Информация о ключе, которым выполнен запрос: права, пространство, действующий пользователь, лимиты. """ viewer: ViewerType! """Справочник допустимых значений перечислимых полей.""" metadata: MetadataType! """Пространство, к которому привязан ключ.""" space: SpaceType! """Участники пространства.""" members(roles: [String!], statuses: [String!], limit: Int, offset: Int): MemberConnection! """Проекты пространства.""" projects(filter: ProjectFilterInput, limit: Int, offset: Int): ProjectConnection! """Проект по идентификатору.""" project(id: ID!): ProjectType """Канбан-доски пространства (или одного проекта).""" boards(projectId: ID, limit: Int, offset: Int): BoardConnection! board(id: ID!): BoardType """Колонки досок.""" statuses(boardId: ID, projectId: ID, limit: Int, offset: Int): StatusConnectionList! status(id: ID!): StatusType """Переходы между статусами (связи на диаграмме процесса).""" statusTransitions(projectId: ID, limit: Int, offset: Int): StatusTransitionConnection! """Задачи пространства с фильтрацией и сортировкой.""" tasks(filter: TaskFilterInput, orderBy: TaskOrderField, orderDirection: SortDirection, limit: Int, offset: Int): TaskConnection! task(id: ID!): TaskType """Чек-лист задачи.""" todos(taskId: ID!, limit: Int, offset: Int): TodoConnection! tags(projectId: ID, boardId: ID, limit: Int, offset: Int): TagConnection! """Поля задач проекта (системные и пользовательские).""" taskFields(projectId: ID!, includeHidden: Boolean, limit: Int, offset: Int): TaskFieldConnection! files(taskId: ID, projectId: ID, limit: Int, offset: Int): FileConnection! """ Графики (диаграммы Гантта) пространства или одного проекта. Их id нужен, чтобы создать эпик в конкретной диаграмме расширенного проекта. """ roadmaps(projectId: ID, limit: Int, offset: Int): RoadmapConnection! roadmap(id: ID!): RoadmapType epics(filter: EpicFilterInput, limit: Int, offset: Int): EpicConnectionPage! epic(id: ID!): EpicType epicDependencies(projectId: ID!, limit: Int, offset: Int): EpicDependencyConnection! calendars(projectId: ID, limit: Int, offset: Int): CalendarConnection! calendar(id: ID!): CalendarType storages(projectId: ID, limit: Int, offset: Int): StorageConnection! storage(id: ID!): StorageType folders(storageId: ID!, parentId: ID, inRoot: Boolean, limit: Int, offset: Int): FolderConnection! pages(filter: PageFilterInput, limit: Int, offset: Int): PageConnection! page(id: ID!): PageType serviceDesks(projectId: ID, limit: Int, offset: Int): ServiceDeskConnection! connectors(projectId: ID, limit: Int, offset: Int): ConnectorConnection! } """Информация о самом ключе: чем он может пользоваться и от чьего имени. """ type ViewerType { tokenName: String! tokenPrefix: String! scopes: [String!]! spaceId: ID! spaceTitle: String actingUserId: ID! actingUserEmail: String expiresAt: DateTimeScalar rateLimitPerMinute: Int! } """Обработка дат и времени. """ scalar DateTimeScalar """ Справочник допустимых значений перечислимых полей. Запрашивается один раз при интеграции — дальше клиент валидирует значения сам, не дожидаясь ошибки от сервера. """ type MetadataType { priorities: [ChoiceOption!]! colors: [ChoiceOption!]! statusIcons: [ChoiceOption!]! projectTypes: [ChoiceOption!]! taskFieldTypes: [ChoiceOption!]! pageTypes: [ChoiceOption!]! memberRoles: [ChoiceOption!]! epicConnectionTypes: [ChoiceOption!]! scopes: [ChoiceOption!]! } """Один допустимый вариант перечислимого поля. """ type ChoiceOption { """Значение для записи в API.""" value: String! """Человекочитаемое название.""" label: String! } """Пространство, к которому привязан ключ. """ type SpaceType { id: ID! title: String slug: String """"personal" или "team".""" type: String color: String isPersonal: Boolean! isTeam: Boolean! owner: UserType membersCount: Int! createdAt: DateTimeScalar } """ Пользователь. Отдаём минимум: внешнему сервису нужны идентификация и отображение, а не профиль целиком. """ type UserType { id: ID! email: String firstName: String lastName: String """Имя и фамилия, либо username.""" fullName: String username: String timezone: String } """Страница списка MemberType.""" type MemberConnection { items: [MemberType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Участник пространства. """ type MemberType { id: ID! user: UserType! """owner / admin / member / guest.""" role: String """active / invited / suspended / left.""" status: String joinedAt: DateTimeScalar } """Страница списка ProjectType.""" type ProjectConnection { items: [ProjectType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Проект — корневой контейнер внутри пространства. """ type ProjectType { id: ID! title: String! """complex / simple / storage / roadmap / calendar.""" type: String isArchived: Boolean! archivedAt: DateTimeScalar owner: UserType spaceId: ID! createdAt: DateTimeScalar updatedAt: DateTimeScalar boards: [BoardType!]! storages: [StorageType!]! """ Графики (диаграммы Гантта) проекта. У расширенного проекта их может быть несколько, у проекта-графика — ровно один. """ roadmaps: [RoadmapType!]! """ Календарные разделы проекта — задачи по срокам, без колонок и статусов. У расширенного проекта их может быть несколько, у проекта-календаря — ровно один. """ calendars: [CalendarType!]! epics: [EpicType!]! taskFields: [TaskFieldType!]! tags: [TagType!]! """Количество незакрытых задач проекта.""" tasksCount: Int! } """Канбан-доска внутри проекта. """ type BoardType { id: ID! title: String! description: String icon: String color: String ordering: Int projectId: ID! project: ProjectType spaceId: ID! createdAt: DateTimeScalar updatedAt: DateTimeScalar statuses: [StatusType!]! """Незакрытые задачи доски.""" tasksCount: Int! } """Колонка канбан-доски. """ type StatusType { id: ID! title: String! icon: String color: String ordering: Int boardId: ID! projectId: ID! board: BoardType tasksCount: Int! createdAt: DateTimeScalar } """Хранилище базы знаний внутри проекта. """ type StorageType { id: ID! title: String! description: String color: String ordering: Int projectId: ID! pagesCount: Int! foldersCount: Int! createdAt: DateTimeScalar updatedAt: DateTimeScalar } """ График — диаграмма Гантта, собирающая эпики. Раздел проекта наравне с доской и хранилищем: расширенный проект держит их сколько нужно, проект типа `roadmap` состоит ровно из одного. Эпик всегда лежит в конкретном графике, поэтому именно `id` отсюда передаётся в `createEpic(roadmapId: ...)`. """ type RoadmapType { id: ID! title: String! description: String color: String ordering: Int projectId: ID! spaceId: ID! epicsCount: Int! createdAt: DateTimeScalar updatedAt: DateTimeScalar } """ Календарный раздел проекта. Отличие от доски одно, но определяющее: у календаря НЕТ статусов — задача в нём живёт во времени. Задача без дедлайна лежит в колонке «Без дедлайна», задача с дедлайном — в своём дне. """ type CalendarType { id: ID! title: String! description: String color: String ordering: Int projectId: ID! """Количество незакрытых задач календаря.""" tasksCount: Int! """Незакрытые задачи без дедлайна.""" backlogCount: Int! createdAt: DateTimeScalar updatedAt: DateTimeScalar } """Эпик — укрупнённая веха проекта (строка диаграммы Гантта). """ type EpicType { id: ID! title: String! description: String color: String startDate: DateScalar endDate: DateScalar ordering: Int """Прогресс в процентах, 0–100.""" progress: Int projectId: ID! """График, которому принадлежит эпик.""" roadmapId: ID! tasksCount: Int! createdAt: DateTimeScalar } """ Дата без времени в формате YYYY-MM-DD. Некорректный ввод возвращает `Undefined`, а не `None`: для GraphQL `None` — это валидное значение null (то есть «очистить поле»), и подсунутая клиентом строка «31.12.2026» молча стирала бы дату вместо понятной ошибки. """ scalar DateScalar """Пользовательское (или системное) поле задач проекта. """ type TaskFieldType { id: ID! title: String! """ text / textarea / number / date / datetime / checkbox / select / multiselect / url. """ fieldType: String isRequired: Boolean! isHidden: Boolean! """half / full.""" width: String ordering: Int """ Ключ системного поля (description, performer, status, ...). У пользовательских полей — null. """ builtinKey: String """Варианты для select/multiselect: [{"id": "...", "title": "..."}].""" options: JSONScalar projectId: ID! } """ Произвольное JSON-значение, передаваемое КАК ЕСТЬ. Отличается от встроенного `graphene.JSONString` тем, что не оборачивает значение в строку: клиент получает `[{"id": "a1"}]`, а не `"[{\"id\": \"a1\"}]"`. Для полей, где тип значения зависит от данных (значения пользовательских полей, опции select), это принципиально — иначе каждому потребителю пришлось бы делать лишний JSON.parse. """ scalar JSONScalar """Тег задач. Живёт в проекте, может быть привязан к доске. """ type TagType { id: ID! title: String! projectId: ID! boardId: ID tasksCount: Int! } """Фильтр списка проектов. """ input ProjectFilterInput { """complex / simple / storage / roadmap / calendar.""" types: [String!] """По умолчанию архивные проекты НЕ возвращаются.""" isArchived: Boolean search: String updatedFrom: DateTimeScalar } """Страница списка BoardType.""" type BoardConnection { items: [BoardType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Страница списка StatusType.""" type StatusConnectionList { items: [StatusType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Страница списка StatusConnectionType.""" type StatusTransitionConnection { items: [StatusConnectionType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Переход между статусами (стрелка на диаграмме процесса). """ type StatusConnectionType { id: ID! label: String isActive: Boolean! projectId: ID! sourceStatusId: ID targetStatusId: ID sourceStatus: StatusType targetStatus: StatusType sourceCalendarId: ID targetCalendarId: ID sourceCalendar: CalendarType targetCalendar: CalendarType """Исполнитель, назначаемый автоматически при переходе.""" newPerformer: UserType serviceDeskId: ID sourceConnectorId: ID targetConnectorId: ID } """Страница списка TaskType.""" type TaskConnection { items: [TaskType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Задача — центральная сущность API. """ type TaskType { id: ID! title: String! description: String """first / second / third / fourth.""" priority: String ordering: Int """Плановая дата и время (plan_datetime).""" deadline: DateTimeScalar """ Время окончания (plan_end_datetime). Вместе с `deadline` задаёт длительность задачи в календаре. null — длительности нет. """ deadlineEnd: DateTimeScalar """Момент выполнения (fact_datetime).""" completedAt: DateTimeScalar isCompleted: Boolean! spaceId: ID! projectId: ID boardId: ID statusId: ID epicId: ID """Календарный раздел задачи. Взаимоисключающе с board/status.""" calendarId: ID project: ProjectType board: BoardType calendar: CalendarType status: StatusType epic: EpicType """Кто создал задачу.""" author: UserType """Исполнитель.""" performer: UserType todos: [TodoType!]! tags: [TagType!]! fieldValues: [TaskFieldValueType!]! files: [FileType!]! recurrence: RecurrenceType createdAt: DateTimeScalar updatedAt: DateTimeScalar """Момент первого перехода в рабочий статус.""" startedAt: DateTimeScalar """Момент появления на текущей доске.""" boardEnteredAt: DateTimeScalar """Момент последней смены статуса.""" statusChangedAt: DateTimeScalar } """Пункт чек-листа задачи. """ type TodoType { id: ID! text: String! isCompleted: Boolean! ordering: Int taskId: ID! createdAt: DateTimeScalar } """Значение пользовательского поля у конкретной задачи. """ type TaskFieldValueType { id: ID! fieldId: ID! field: TaskFieldType taskId: ID! """ Тип значения зависит от field_type: строка, число, bool или список id опций. """ value: JSONScalar } """Файл, прикреплённый к задаче или проекту. """ type FileType { id: ID! title: String originalFilename: String slug: String fileType: String mimeType: String """Размер файла в байтах.""" fileSize: Float width: Int height: Int """Прямая ссылка на скачивание (временная).""" url: String projectId: ID createdAt: DateTimeScalar } """Правило повторения задачи. """ type RecurrenceType { """none / daily / weekly / monthly / yearly / custom.""" type: String interval: Int weekdays: [String] monthlyType: String monthlyDay: Int monthlyWeek: Int endDate: DateTimeScalar count: Int completedCount: Int customUnit: String anchorDatetime: DateTimeScalar } """ Фильтр списка задач. Все поля необязательны и комбинируются по И. Списковые поля (`projectIds`, `statusIds`, ...) работают как ИЛИ внутри себя: `projectIds: [1, 2]` — это «задачи проекта 1 ИЛИ проекта 2». """ input TaskFilterInput { projectIds: [ID!] boardIds: [ID!] """Задачи этих календарных разделов.""" calendarIds: [ID!] statusIds: [ID!] epicIds: [ID!] tagIds: [ID!] """Задачи этих исполнителей.""" performerIds: [ID!] authorIds: [ID!] priorities: [String!] """ true — только выполненные, false — только открытые, не указано — и те и другие. """ isCompleted: Boolean hasDeadline: Boolean """Открытые задачи с дедлайном в прошлом.""" isOverdue: Boolean """Задачи без проекта/доски (входящие пространства).""" inInbox: Boolean deadlineFrom: DateTimeScalar deadlineTo: DateTimeScalar createdFrom: DateTimeScalar createdTo: DateTimeScalar """ Ключ инкрементальной синхронизации: отдаёт всё, что изменилось после указанного момента. """ updatedFrom: DateTimeScalar completedFrom: DateTimeScalar completedTo: DateTimeScalar """Подстрока в названии или описании.""" search: String } """Поле сортировки задач. """ enum TaskOrderField { CREATED UPDATED DEADLINE COMPLETED_AT ORDERING TITLE PRIORITY } """Направление сортировки. """ enum SortDirection { ASC DESC } """Страница списка TodoType.""" type TodoConnection { items: [TodoType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Страница списка TagType.""" type TagConnection { items: [TagType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Страница списка TaskFieldType.""" type TaskFieldConnection { items: [TaskFieldType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Страница списка FileType.""" type FileConnection { items: [FileType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Страница списка RoadmapType.""" type RoadmapConnection { items: [RoadmapType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Страница списка EpicType.""" type EpicConnectionPage { items: [EpicType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Фильтр списка эпиков. """ input EpicFilterInput { projectIds: [ID!] """Эпики только этих графиков (диаграмм Гантта).""" roadmapIds: [ID!] startsAfter: DateScalar endsBefore: DateScalar search: String } """Страница списка EpicConnectionType.""" type EpicDependencyConnection { items: [EpicConnectionType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Зависимость между эпиками на диаграмме Гантта. """ type EpicConnectionType { id: ID! projectId: ID! """График, на котором нарисована связь.""" roadmapId: ID! sourceEpicId: ID! targetEpicId: ID! """finish_to_start / start_to_start / finish_to_finish / start_to_finish.""" connectionType: String } """Страница списка CalendarType.""" type CalendarConnection { items: [CalendarType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Страница списка StorageType.""" type StorageConnection { items: [StorageType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Страница списка FolderType.""" type FolderConnection { items: [FolderType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Папка внутри хранилища. Может быть вложена в другую папку. """ type FolderType { id: ID! title: String! description: String color: String ordering: Int storageId: ID! parentId: ID createdAt: DateTimeScalar } """Страница списка PageType.""" type PageConnection { items: [PageType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Страница (статья) базы знаний. """ type PageType { id: ID! title: String! """Содержимое: HTML для wysiwyg, текст для markdown.""" content: String """wysiwyg / markdown / blocks.""" pageType: String """ В избранном ли страница У ВЛАДЕЛЬЦА КЛЮЧА. Отметка персональная: её видит и меняет только тот пользователь, от имени которого выдан ключ. """ isFavorite: Boolean! ordering: Int storageId: ID! folderId: ID author: UserType createdAt: DateTimeScalar updatedAt: DateTimeScalar } """Фильтр списка страниц базы знаний. """ input PageFilterInput { storageIds: [ID!] folderId: ID """Только страницы в корне хранилища.""" inRoot: Boolean isFavorite: Boolean pageTypes: [String!] """Подстрока в названии или содержимом.""" search: String updatedFrom: DateTimeScalar } """Страница списка ServiceDeskType.""" type ServiceDeskConnection { items: [ServiceDeskType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Внешний деск постановки задач. """ type ServiceDeskType { id: ID! title: String! """Используется в публичной ссылке на деск.""" slug: String! description: String externalDescription: String isActive: Boolean! deskType: String projectId: ID! boardId: ID statusId: ID } """Страница списка ConnectorType.""" type ConnectorConnection { items: [ConnectorType!]! """Всего объектов, подходящих под фильтр.""" totalCount: Int! """Есть ли ещё страницы после текущей.""" hasMore: Boolean! """Применённый размер страницы.""" limit: Int! """Применённое смещение.""" offset: Int! } """Коннектор — узел маршрутизации задач между проектами. """ type ConnectorType { id: ID! title: String isActive: Boolean! projectId: ID! } """Корневой тип мутаций публичного API Таски. """ type Mutation { """Создаёт хранилище базы знаний внутри проекта. """ createStorage(color: String, description: String, projectId: ID!, title: String!): CreateStorage """Изменяет название, описание или цвет хранилища. """ updateStorage(color: String, description: String, id: ID!, title: String): UpdateStorage """Удаляет хранилище вместе со всеми папками и страницами. """ deleteStorage(id: ID!): DeleteResult """Создаёт папку в хранилище или внутри другой папки. """ createFolder( color: String description: String """Родительская папка. Не передана — папка в корне.""" parentId: ID storageId: ID! title: String! ): CreateFolder """Изменяет папку: название, описание, цвет, а также её место в дереве. """ updateFolder( color: String description: String id: ID! """Новая родительская папка. null — перенести в корень.""" parentId: ID """Позиция среди соседей (с 1).""" position: Int title: String ): UpdateFolder """Удаляет папку вместе с вложенными папками и страницами. """ deleteFolder(id: ID!): DeleteResult """ Создаёт страницу базы знаний. Тип страницы фиксируется при создании и не меняется: wysiwyg-страница и markdown-страница рендерятся разными редакторами, и содержимое одной не является валидным содержимым другой. """ createPage( content: String """Папка. Не передана — страница в корне хранилища.""" folderId: ID isFavorite: Boolean """wysiwyg (по умолчанию) / markdown / blocks.""" pageType: String storageId: ID! title: String! ): CreatePage """ Изменяет страницу: заголовок, содержимое, признак избранного, а также её место в дереве хранилища. """ updatePage( content: String """Новая папка. null — перенести в корень хранилища.""" folderId: ID id: ID! isFavorite: Boolean """Позиция среди соседей (с 1).""" position: Int title: String ): UpdatePage """Удаляет страницу базы знаний. """ deletePage(id: ID!): DeleteResult """Создаёт эпик в графике проекта. """ createEpic( color: String description: String endDate: DateScalar projectId: ID! """ График (диаграмма Гантта), в который попадёт эпик. Не передан — берётся первый график проекта по порядку. """ roadmapId: ID startDate: DateScalar title: String! ): CreateEpic """Изменяет эпик: название, описание, цвет, даты, прогресс. """ updateEpic( color: String description: String endDate: DateScalar id: ID! """0–100.""" progress: Int startDate: DateScalar title: String ): UpdateEpic """Удаляет эпик. Задачи эпика сохраняются — с них снимается привязка. """ deleteEpic(id: ID!): DeleteResult """ Привязывает задачи к эпику (или снимает привязку, если `epicId` не передан). """ assignTasksToEpic( """Не передан или null — снять привязку.""" epicId: ID taskIds: [ID!]! ): AssignTasksToEpic """ Создаёт зависимость между эпиками на диаграмме Гантта. Типы, отличные от `finish_to_start`, доступны не на всех тарифах — в этом случае вернётся ошибка `feature_not_allowed`. """ createEpicDependency( """ finish_to_start (по умолчанию) / start_to_start / finish_to_finish / start_to_finish. """ connectionType: String sourceEpicId: ID! targetEpicId: ID! ): CreateEpicDependency """Удаляет зависимость между эпиками. """ deleteEpicDependency(id: ID!): DeleteResult """Создаёт пользовательское поле задач в проекте. """ createTaskField( """Один из вариантов metadata.taskFieldTypes.""" fieldType: String! isRequired: Boolean """Обязательно для типов select и multiselect.""" options: [TaskFieldOptionInput!] projectId: ID! title: String! """half (по умолчанию) / full.""" width: String ): CreateTaskField """ Изменяет поле задач. ВАЖНО про опции: при изменении списка опций сохраняйте `id` тех, что остаются. Опция без `id` считается новой и получает свежий идентификатор, а значения задач, ссылавшиеся на старую опцию, «повиснут». """ updateTaskField( id: ID! isHidden: Boolean isRequired: Boolean options: [TaskFieldOptionInput!] """Позиция поля в деске задачи (с 1).""" position: Int """Недоступно для системных полей.""" title: String width: String ): UpdateTaskField """ Удаляет пользовательское поле вместе со всеми его значениями. Системные поля удалить нельзя — их можно только скрыть (`isHidden`). """ deleteTaskField(id: ID!): DeleteResult """ Создаёт задачу. Три режима: * **на доске** — переданы `statusId` (доска и проект выводятся из него); * **в календаре** — передан `calendarId` (проект выводится из него); * **во входящих пространства** — не передан ни один из идентификаторов. Если указан только `projectId`, задача создаётся в проекте без доски (так же, как задачи, пришедшие из внешней деска). """ createTask( """Поместить в начало колонки. По умолчанию — в конец.""" addToTop: Boolean """ Календарный раздел. Определяет проект. Задача без `deadline` попадёт в колонку «Без дедлайна». """ calendarId: ID """Плановая дата и время.""" deadline: DateTimeScalar """ Время окончания. Задаёт длительность задачи в календаре и учитывается только вместе с `deadline`, причём строго позже него. """ deadlineEnd: DateTimeScalar description: String epicId: ID fieldValues: [TaskFieldValueInput!] performerId: ID """first / second / third / fourth.""" priority: String """Проект — если задача создаётся вне доски.""" projectId: ID recurrence: RecurrenceInput """Колонка доски. Определяет доску и проект.""" statusId: ID tagIds: [ID!] title: String! ): CreateTask """ Изменяет поля задачи. Передаются только те поля, которые надо поменять. Чтобы очистить необязательное поле, передайте `null` (например, `deadline: null` снимет дедлайн, `performerId: null` — исполнителя). """ updateTask(deadline: DateTimeScalar, deadlineEnd: DateTimeScalar, description: String, epicId: ID, id: ID!, performerId: ID, priority: String, recurrence: RecurrenceInput, title: String): UpdateTask """ Перемещает задачу в другую колонку или в календарный раздел и/или меняет её позицию. Обновляет flow-метрики: смена доски начинает новый цикл, первый переход в другую колонку фиксирует начало работы. Если для перехода настроен автоматический исполнитель, он назначается — так же, как при перетаскивании карточки в интерфейсе. """ moveTask( """ Целевой календарный раздел. Задача без `deadline` встанет в колонку «Без дедлайна». Взаимоисключающе с `statusId`. """ calendarId: ID id: ID! """ Позиция в колонке (с 1). По умолчанию — в начало. В календаре не используется: место там задаёт срок. """ position: Int """ Целевая колонка (может быть на другой доске). Взаимоисключающе с `calendarId`. """ statusId: ID ): MoveTask """ Отмечает задачу выполненной. Для повторяющейся задачи вместо закрытия переносит её на следующую итерацию серии — как это делает приложение. Момент выполнения можно задать явно через `completedAt` (например, при импорте истории). """ completeTask( """Момент выполнения. По умолчанию — сейчас.""" completedAt: DateTimeScalar id: ID! ): CompleteTask """Возвращает выполненную задачу в работу — в конец её колонки. """ reopenTask(id: ID!): ReopenTask """Удаляет задачу вместе с чек-листом и значениями полей. """ deleteTask(id: ID!): DeleteResult """ Задаёт полный набор тегов задачи: переданные привязываются, все остальные — снимаются. Пустой список снимает все теги. """ setTaskTags(tagIds: [ID!]!, taskId: ID!): SetTaskTags """ Записывает значения пользовательских полей задачи. Обновляются только переданные поля; остальные остаются как были. Чтобы очистить поле, передайте для него `value: null`. """ setTaskFieldValues(taskId: ID!, values: [TaskFieldValueInput!]!): SetTaskFieldValues """Добавляет пункт в чек-лист задачи. """ createTodo(isCompleted: Boolean, taskId: ID!, text: String!): CreateTodo """Меняет текст, отметку выполнения или позицию пункта чек-листа. """ updateTodo( id: ID! isCompleted: Boolean """Новая позиция в чек-листе (с 1).""" position: Int text: String ): UpdateTodo """Удаляет пункт чек-листа. """ deleteTodo(id: ID!): DeleteResult """ Создаёт канбан-доску в проекте вместе с набором статусов по умолчанию («Новая», «В работе», «Готова» и т.д.) — как при создании доски в интерфейсе. """ createBoard( color: String description: String icon: String projectId: ID! title: String! """Создать стандартный набор статусов. По умолчанию true.""" withDefaultStatuses: Boolean ): CreateBoard """ Изменяет название, описание, иконку, цвет или позицию доски в проекте. """ updateBoard( color: String description: String icon: String id: ID! """Новая позиция доски в проекте (с 1).""" ordering: Int title: String ): UpdateBoard """Удаляет доску вместе со статусами и задачами на ней. """ deleteBoard(id: ID!): DeleteResult """Добавляет колонку на доску. """ createStatus( boardId: ID! color: String icon: String """Позиция в ряду колонок (с 1). По умолчанию — в конец.""" position: Int title: String! ): CreateStatus """Изменяет колонку: название, иконку, цвет, позицию. """ updateStatus( color: String icon: String id: ID! """Новая позиция колонки на доске (с 1).""" position: Int title: String ): UpdateStatus """ Удаляет колонку. Если в колонке есть задачи, удаление отклоняется: задачи ушли бы вместе с ней. Передайте `moveTasksToStatusId`, чтобы сначала перенести их. """ deleteStatus( id: ID! """Куда перенести задачи удаляемой колонки.""" moveTasksToStatusId: ID ): DeleteResult """Создаёт тег в проекте. """ createTag( """Ограничить тег одной доской проекта.""" boardId: ID projectId: ID! title: String! ): CreateTag """Переименовывает тег. """ updateTag(id: ID!, title: String!): UpdateTag """Удаляет тег. Задачи при этом не удаляются — с них снимается метка. """ deleteTag(id: ID!): DeleteResult """ Создаёт проект в пространстве ключа. Для типа `simple` автоматически создаётся канбан-доска с набором статусов по умолчанию, для `storage` — хранилище базы знаний, для `calendar` — календарный раздел (задачи по срокам, без колонок и статусов). Это то же поведение, что и в приложении: тип проекта определяет его стартовое наполнение. """ createProject( title: String! """complex / simple / storage / roadmap / calendar. По умолчанию simple.""" type: String ): CreateProject """ Изменяет название проекта. Тип проекта после создания не меняется — от него зависит структура уже созданных сущностей. """ updateProject(id: ID!, title: String): UpdateProject """ Архивирует проект: он остаётся доступен на чтение и перестаёт считаться в квоте тарифа. """ archiveProject(id: ID!): ArchiveProject """ Возвращает проект из архива. Проходит проверку квоты проектов тарифа — поэтому может вернуть ошибку `quota_exceeded`. """ unarchiveProject(id: ID!): UnarchiveProject """ Удаляет проект вместе со всем содержимым (доски, задачи, хранилища). Удаление мягкое (soft-delete), но через API восстановление не предусмотрено — операция необратима для внешнего клиента. """ deleteProject(id: ID!): DeleteResult } """Создаёт хранилище базы знаний внутри проекта. """ type CreateStorage { storage: StorageType! } """Изменяет название, описание или цвет хранилища. """ type UpdateStorage { storage: StorageType! } """Единый ответ для всех операций удаления. """ type DeleteResult { success: Boolean! deletedId: ID! } """Создаёт папку в хранилище или внутри другой папки. """ type CreateFolder { folder: FolderType! } """Изменяет папку: название, описание, цвет, а также её место в дереве. """ type UpdateFolder { folder: FolderType! } """ Создаёт страницу базы знаний. Тип страницы фиксируется при создании и не меняется: wysiwyg-страница и markdown-страница рендерятся разными редакторами, и содержимое одной не является валидным содержимым другой. """ type CreatePage { page: PageType! } """ Изменяет страницу: заголовок, содержимое, признак избранного, а также её место в дереве хранилища. """ type UpdatePage { page: PageType! } """Создаёт эпик в графике проекта. """ type CreateEpic { epic: EpicType! } """Изменяет эпик: название, описание, цвет, даты, прогресс. """ type UpdateEpic { epic: EpicType! } """ Привязывает задачи к эпику (или снимает привязку, если `epicId` не передан). """ type AssignTasksToEpic { updatedCount: Int! } """ Создаёт зависимость между эпиками на диаграмме Гантта. Типы, отличные от `finish_to_start`, доступны не на всех тарифах — в этом случае вернётся ошибка `feature_not_allowed`. """ type CreateEpicDependency { dependency: EpicConnectionType! } """Создаёт пользовательское поле задач в проекте. """ type CreateTaskField { taskField: TaskFieldType! } """Вариант select/multiselect. """ input TaskFieldOptionInput { """ Стабильный id опции. При создании можно не передавать — сервер сгенерирует. При изменении обязателен, иначе сохранённые значения задач «съедут» на соседние опции. """ id: String title: String! } """ Изменяет поле задач. ВАЖНО про опции: при изменении списка опций сохраняйте `id` тех, что остаются. Опция без `id` считается новой и получает свежий идентификатор, а значения задач, ссылавшиеся на старую опцию, «повиснут». """ type UpdateTaskField { taskField: TaskFieldType! } """ Создаёт задачу. Три режима: * **на доске** — переданы `statusId` (доска и проект выводятся из него); * **в календаре** — передан `calendarId` (проект выводится из него); * **во входящих пространства** — не передан ни один из идентификаторов. Если указан только `projectId`, задача создаётся в проекте без доски (так же, как задачи, пришедшие из внешней деска). """ type CreateTask { task: TaskType! } """Значение пользовательского поля задачи. """ input TaskFieldValueInput { fieldId: ID! """ Значение в формате, соответствующем типу поля. Для очистки поля передайте null. """ value: JSONScalar } """ Правило повторения задачи. Передаётся целиком: сервер применяет его как единое правило, а не домердживает по полю. `type: "none"` снимает повторение. """ input RecurrenceInput { """none / daily / weekly / monthly / yearly / custom.""" type: String! """Каждые N единиц. По умолчанию 1.""" interval: Int """Для type=weekly: ["monday", "wednesday"].""" weekdays: [String!] """day_of_month / day_of_week.""" monthlyType: String """1–31.""" monthlyDay: Int """1–4 — неделя месяца, 5 — последняя.""" monthlyWeek: Int """Когда серия заканчивается.""" endDate: DateTimeScalar """Сколько раз повторить.""" count: Int """Единица для type=custom.""" customUnit: String } """ Изменяет поля задачи. Передаются только те поля, которые надо поменять. Чтобы очистить необязательное поле, передайте `null` (например, `deadline: null` снимет дедлайн, `performerId: null` — исполнителя). """ type UpdateTask { task: TaskType! } """ Перемещает задачу в другую колонку или в календарный раздел и/или меняет её позицию. Обновляет flow-метрики: смена доски начинает новый цикл, первый переход в другую колонку фиксирует начало работы. Если для перехода настроен автоматический исполнитель, он назначается — так же, как при перетаскивании карточки в интерфейсе. """ type MoveTask { task: TaskType! } """ Отмечает задачу выполненной. Для повторяющейся задачи вместо закрытия переносит её на следующую итерацию серии — как это делает приложение. Момент выполнения можно задать явно через `completedAt` (например, при импорте истории). """ type CompleteTask { task: TaskType! """ true, если задача повторяющаяся и была перенесена на следующую итерацию. """ rescheduled: Boolean! } """Возвращает выполненную задачу в работу — в конец её колонки. """ type ReopenTask { task: TaskType! } """ Задаёт полный набор тегов задачи: переданные привязываются, все остальные — снимаются. Пустой список снимает все теги. """ type SetTaskTags { task: TaskType! } """ Записывает значения пользовательских полей задачи. Обновляются только переданные поля; остальные остаются как были. Чтобы очистить поле, передайте для него `value: null`. """ type SetTaskFieldValues { task: TaskType! } """Добавляет пункт в чек-лист задачи. """ type CreateTodo { todo: TodoType! } """Меняет текст, отметку выполнения или позицию пункта чек-листа. """ type UpdateTodo { todo: TodoType! } """ Создаёт канбан-доску в проекте вместе с набором статусов по умолчанию («Новая», «В работе», «Готова» и т.д.) — как при создании доски в интерфейсе. """ type CreateBoard { board: BoardType! } """ Изменяет название, описание, иконку, цвет или позицию доски в проекте. """ type UpdateBoard { board: BoardType! } """Добавляет колонку на доску. """ type CreateStatus { status: StatusType! } """Изменяет колонку: название, иконку, цвет, позицию. """ type UpdateStatus { status: StatusType! } """Создаёт тег в проекте. """ type CreateTag { tag: TagType! } """Переименовывает тег. """ type UpdateTag { tag: TagType! } """ Создаёт проект в пространстве ключа. Для типа `simple` автоматически создаётся канбан-доска с набором статусов по умолчанию, для `storage` — хранилище базы знаний, для `calendar` — календарный раздел (задачи по срокам, без колонок и статусов). Это то же поведение, что и в приложении: тип проекта определяет его стартовое наполнение. """ type CreateProject { project: ProjectType! } """ Изменяет название проекта. Тип проекта после создания не меняется — от него зависит структура уже созданных сущностей. """ type UpdateProject { project: ProjectType! } """ Архивирует проект: он остаётся доступен на чтение и перестаёт считаться в квоте тарифа. """ type ArchiveProject { project: ProjectType! } """ Возвращает проект из архива. Проходит проверку квоты проектов тарифа — поэтому может вернуть ошибку `quota_exceeded`. """ type UnarchiveProject { project: ProjectType! }