From ca6fa721f257750aa0f981e26647af9e6e6e809d Mon Sep 17 00:00:00 2001 From: Anton Pomorzin Date: Mon, 27 Jul 2026 16:22:57 +0500 Subject: [PATCH] =?UTF-8?q?feature/H-1267:=20=D0=9A=D0=B0=D1=82=D0=B0?= =?UTF-8?q?=D0=BB=D0=BE=D0=B3=20=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82?= =?UTF-8?q?=D0=B5=D0=BA=D0=B8=20=E2=80=94=20/library/catalog=20=D0=B8=20/a?= =?UTF-8?q?dmin/library-category/*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- v2/swagger.yaml | 407 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 407 insertions(+) diff --git a/v2/swagger.yaml b/v2/swagger.yaml index f7cca68..386513d 100644 --- a/v2/swagger.yaml +++ b/v2/swagger.yaml @@ -79,6 +79,12 @@ tags: description: Methods for admin oversight of personal API tokens. Requires "api-tokens-admin" permission. - name: admin-employment description: Methods for administrative read-only access to employee employments, including external identifiers used by integrations. Requires "user-edit" permission. + - name: library + description: Корпоративная библиотека (книги). Требуется право `book-access`. + - name: admin-library-category + description: | + Редактор каталога библиотеки: дерево категорий и книг (H-1267). Требуется + право `book-manager`. paths: /mobile/bind/{id}/{token}: @@ -8264,6 +8270,312 @@ paths: Запись не найдена. Включает случаи обращения к записям, принадлежащим другим тенантам. + + /library/catalog: + get: + tags: [library] + summary: Каталог библиотеки (категории и книги) + description: | + Клиентский каталог библиотеки (H-1267). Контракт идентичен /article/category: + без параметров — корень каталога, с id/hash_id — содержимое категории. + Видимость категорий и книг по группам пользователей применяется автоматически. + operationId: libraryCatalog + security: + - SessionAuth: [ ] + parameters: + - name: id + in: query + required: false + description: ID категории (пусто — корень каталога) + schema: { type: string, format: uuid } + - name: hash_id + in: query + required: false + description: Хэш категории, альтернатива id + schema: { type: string } + - name: q + in: query + required: false + description: Поиск по названию, автору и серии книги + schema: { type: string } + - name: tags + in: query + required: false + description: ID тегов через запятую + schema: { type: string } + responses: + 200: + description: Содержимое категории или результаты поиска + content: + application/json: + schema: + type: object + properties: + category: + description: Текущая категория (null для корня) + nullable: true + allOf: + - $ref: '#/components/schemas/libraryCatalogCategory' + categories: + type: array + description: Подкатегории текущей категории + items: + $ref: '#/components/schemas/libraryCatalogCategory' + items: + type: array + description: Книги текущей категории + items: + $ref: '#/components/schemas/libraryCatalogBook' + tags: + type: array + description: Теги, доступные в текущей категории + items: + $ref: '#/components/schemas/tag' + breadcrumbs: + type: array + description: Хлебные крошки (пусто для корня) + items: + type: object + properties: + id: { type: string, format: uuid } + label: { type: string } + url: { type: string } + q: + type: string + nullable: true + description: Поисковый запрос + 400: { description: Некорректный id категории } + 404: { description: Категория не найдена } + 401: { description: Unauthorized request } + 403: { description: Unauthorized request } + + /admin/library-category/items: + get: + tags: [admin-library-category] + summary: Дерево каталога (один уровень) + description: | + Узлы одного уровня дерева для редактора каталога. Без id — корень, + с id категории — её дети. Дети категорий грузятся лениво повторным + запросом. У категорий в data есть children_count. + operationId: adminLibraryCategoryItems + security: + - SessionAuth: [ ] + parameters: + - name: id + in: query + required: false + description: ID категории (item_id узла, не узла дерева) + schema: { type: string, format: uuid } + responses: + 200: + description: Массив узлов дерева + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/libraryCatalogTreeNode' + 403: { description: Нет права book-manager } + + /admin/library-category/create: + post: + tags: [admin-library-category] + summary: Создать категорию + operationId: adminLibraryCategoryCreate + security: + - SessionAuth: [ ] + requestBody: + content: + application/json: + schema: + type: object + required: [name] + properties: + name: { type: string } + parent_id: + type: string + format: uuid + nullable: true + description: ID родительского узла дерева (null — корень) + responses: + 200: + description: Результат (errors при ошибке валидации) + content: + application/json: + schema: + $ref: '#/components/schemas/libraryCatalogEditorResult' + 403: { description: Нет права book-manager } + + /admin/library-category/update: + put: + tags: [admin-library-category] + summary: Обновить узел дерева (категорию или книгу) + description: | + id — идентификатор УЗЛА дерева (key из items). Для категории принимает + name/description/status_id/thumb_style_id/content_style_id/tags_id/ + userGroupsVisibleId/userGroupsHiddenId/image; для книги — title и другие + поля книги. tags_id — строка с ID через запятую. image — объект {id, fid} + (fid обязателен для построения URL картинки категории; image: null — не менять). + Узлы чужих каталогов недоступны (404). + operationId: adminLibraryCategoryUpdate + security: + - SessionAuth: [ ] + parameters: + - name: id + in: query + required: true + schema: { type: string, format: uuid } + requestBody: + content: + application/json: + schema: + type: object + responses: + 200: + description: Результат + content: + application/json: + schema: + $ref: '#/components/schemas/libraryCatalogEditorResult' + 400: { description: Некорректный uuid } + 404: { description: Узел не найден или принадлежит другому каталогу } + + /admin/library-category/delete: + delete: + tags: [admin-library-category] + summary: Удалить узел дерева + description: | + Категория удаляется вместе с поддеревом; для книги удаляется только узел + (книга остаётся в библиотеке). id — идентификатор узла дерева. + operationId: adminLibraryCategoryDelete + security: + - SessionAuth: [ ] + parameters: + - name: id + in: query + required: true + schema: { type: string, format: uuid } + responses: + 200: { description: Удалено (true) } + 400: { description: Некорректный uuid } + 404: { description: Узел не найден или принадлежит другому каталогу } + + /admin/library-category/update-tree: + post: + tags: [admin-library-category] + summary: Перенести узел в другую категорию + operationId: adminLibraryCategoryUpdateTree + security: + - SessionAuth: [ ] + requestBody: + content: + application/json: + schema: + type: object + required: [childId] + properties: + childId: + type: string + format: uuid + description: ID переносимого узла дерева + parentId: + type: string + format: uuid + nullable: true + description: ID узла целевой категории (null — в корень) + responses: + 200: { description: Перенесено } + 400: { description: Не передан childId } + 404: { description: Узел не найден, либо родитель — не категория } + 500: { description: Перенос не выполнен } + + /admin/library-category/sort: + post: + tags: [admin-library-category] + summary: Сохранить порядок узлов + description: Карта «ID узла дерева → порядковый номер». Чужие узлы игнорируются. + operationId: adminLibraryCategorySort + security: + - SessionAuth: [ ] + requestBody: + content: + application/json: + schema: + type: object + required: [sort] + properties: + sort: + type: object + additionalProperties: { type: integer } + responses: + 200: { description: Сохранено } + 400: { description: sort — не объект } + + /admin/library-category/create-item: + post: + tags: [admin-library-category] + summary: Добавить книгу в категорию + description: | + entity_id принудительно Entity::Book (375) — подменить нельзя. Дубликаты + по (parent_id, item_id) не создаются. + operationId: adminLibraryCategoryCreateItem + security: + - SessionAuth: [ ] + requestBody: + content: + application/json: + schema: + type: object + required: [item_id] + properties: + item_id: + type: string + format: uuid + description: ID книги + parent_id: + type: string + format: uuid + nullable: true + description: ID узла категории (null — корень) + responses: + 200: + description: Результат + content: + application/json: + schema: + $ref: '#/components/schemas/libraryCatalogEditorResult' + 404: { description: Родитель не найден или не категория } + + /admin/library-category/create-items: + post: + tags: [admin-library-category] + summary: Добавить несколько книг (мультивыбор) + description: Транзакционно; при ошибке валидации любого элемента — полный откат. + operationId: adminLibraryCategoryCreateItems + security: + - SessionAuth: [ ] + requestBody: + content: + application/json: + schema: + type: array + items: + type: object + required: [item_id] + properties: + item_id: { type: string, format: uuid } + parent_id: + type: string + format: uuid + nullable: true + responses: + 200: + description: Результат (data — массив созданных узлов) + content: + application/json: + schema: + $ref: '#/components/schemas/libraryCatalogEditorResult' + components: securitySchemes: SessionAuth: @@ -8875,6 +9187,101 @@ components: items: $ref: '#/components/schemas/tag' + libraryCatalogCategory: + type: object + description: Категория каталога библиотеки + properties: + id: { type: string, format: uuid } + name: { type: string } + title: { type: string } + description: { type: string, nullable: true } + hash_id: { type: string } + url: { type: string } + status_id: + type: integer + description: 1 - Active, 2 - Disabled + thumb_style_id: + type: integer + description: Превью 1 - картинка и текст, 2 - только текст, 3 - только картинка + content_style_id: + type: integer + description: Вид содержимого 1 - плитка, 2 - список + thumbUrl: { type: string } + imageUrl: { type: string } + iconUrl: { type: string } + tags: + type: array + items: + $ref: '#/components/schemas/tag' + + libraryCatalogBook: + type: object + description: Книга в каталоге библиотеки (состав полей карточки книги) + properties: + id: { type: string, format: uuid } + entity_id: { type: integer, example: 375 } + entityId: { type: integer, example: 375 } + name: { type: string, description: Совпадает с title } + title: { type: string } + description: { type: string, nullable: true } + url: { type: string } + status_id: + type: integer + description: 1 - В библиотеке, 2 - На руках, 3 - Удалена + statusName: { type: string } + author: { type: string, nullable: true } + series: { type: string, nullable: true } + publishing_house: { type: string, nullable: true } + year_issue: { type: integer, nullable: true } + page_quantity: { type: integer, nullable: true } + read_quantity: { type: integer, nullable: true } + is_print: { type: boolean, description: Есть бумажная версия } + thumbUrl: { type: string, description: Обложка (или плейсхолдер) } + thumbMiniCubeUrl: { type: string } + tags: + type: array + items: + $ref: '#/components/schemas/tag' + countLike: { type: integer } + isLikeUser: { type: boolean } + isFavoriteUser: { type: boolean } + isOnHandUser: { type: boolean, description: Книга сейчас на руках } + + libraryCatalogTreeNode: + type: object + description: Узел дерева редактора каталога библиотеки + properties: + key: + type: string + format: uuid + description: ID узла дерева (hr_category_tree_item) + title: { type: string } + folder: { type: boolean, description: true — категория } + lazy: { type: boolean, description: Дети грузятся отдельным запросом } + children: + type: array + nullable: true + description: null — не загружены (лениво) + items: { type: object } + data: + type: object + description: | + treeData сущности. Для категории — поля libraryCatalogCategory плюс item_id, + children_count, userGroupsVisible/Hidden, organization_id, isTenantSynced. + Для книги — поля libraryCatalogBook плюс item_id. + + libraryCatalogEditorResult: + type: object + description: Единый формат ответа редактора каталога + properties: + success: { type: boolean } + data: + nullable: true + description: Созданный/обновлённый узел (или массив узлов для create-items) + errors: + nullable: true + description: Ошибки валидации (null при успехе) + calendarEventType: type: object properties: