1293 lines
52 KiB
YAML
1293 lines
52 KiB
YAML
openapi: 3.0.3
|
||
|
||
info:
|
||
title: Transmittal Service API
|
||
version: "1.0.0"
|
||
description: |
|
||
REST API сервиса **transmittal-api** (`pdm/transmittal-api`) — управление
|
||
трансмитталами (передачей документации на согласование), их шаблонами,
|
||
шагами/действиями маршрута согласования и генерацией актов.
|
||
|
||
Сервис написан на Python (**FastAPI**). Приложение собирается фабрикой
|
||
`get_application` в `src/transmittal_service/app/http_server.py`. Роутинг
|
||
состоит из двух групп:
|
||
|
||
- публичный API — префикс `/api/v1` (`controller/http/api/v1/api.py`);
|
||
- внутренний API — префикс `/internal/v1` (`controller/http/internal/v1/api.py`),
|
||
предназначен для вызовов внутри кластера (через ingress не публикуется).
|
||
|
||
Интерактивная документация Swagger доступна по `/api/docs`, схема —
|
||
по `/api/openapi.json` (с учётом `root_path`).
|
||
|
||
### Аутентификация
|
||
Публичные эндпоинты (кроме `/api/v1/healthcheck`) требуют аутентификации.
|
||
Токен передаётся заголовком `Authorization: Bearer <jwt>` (FastAPI
|
||
`HTTPBearer`). Поддерживаются два режима (`controller/http/security.py`):
|
||
|
||
1. **Zitadel** — если передан дополнительный заголовок `identity`
|
||
(`Identity <jwt>`), полезная нагрузка берётся из этого токена
|
||
(`urn:zitadel:iam:user:metadata`). Валидность проверяется на уровне
|
||
Istio, подпись сервисом не проверяется.
|
||
2. **sarex-backend** — если заголовка `identity` нет, подпись основного
|
||
токена проверяется публичным RSA-ключом
|
||
(`TRANSMITTAL_SERVICE_AUTH__PUBLIC_KEY`, алгоритм `RS512`).
|
||
|
||
Внутренние эндпоинты (`/internal/v1/*`) аутентификации на уровне приложения
|
||
не требуют — ограничение доступа обеспечивается сетевым слоем.
|
||
|
||
### Пагинация
|
||
Списочные ответы используют «bookmark»-пагинацию. Ответ оборачивается в
|
||
`Page` — `{ result, next, prev }`, где `next`/`prev` — курсоры (bookmark).
|
||
Размер страницы задаётся параметром `limit` (в теле или query, зависит от
|
||
эндпоинта), продолжение — параметром `bookmark`. Часть ответов оборачивается
|
||
в более простой `Result` — `{ result }` (без курсоров).
|
||
|
||
### Обработка ошибок
|
||
Ошибки возвращаются в формате **RFC 7807** (`application/problem+json`),
|
||
схема `ApiError` — `{ type, title, status, detail, instance }`
|
||
(`controller/http/middleware.py`, класс `ExceptionHandler`). Идентификатор
|
||
запроса возвращается в заголовке `X-Request-Id`, длительность обработки —
|
||
в `Server-Timing`.
|
||
|
||
### Замечания (расхождения кода)
|
||
- Ошибка «ресурс не найден» (`NotFound`) маппится на статус **`410 Gone`**,
|
||
а не на привычный `404 Not Found`.
|
||
- При отсутствии/некорректности `Authorization` FastAPI `HTTPBearer`
|
||
возвращает `403`, тогда как ошибки разбора токена в middleware дают `401`.
|
||
- Ошибки валидации тела/параметров запроса (Pydantic) отдаются FastAPI в
|
||
стандартном формате `422` (не `application/problem+json`).
|
||
- Конфликт имени шаблона (`TemplateNameIsNotUnique`) возвращает `409`.
|
||
|
||
contact:
|
||
name: transmittal-api
|
||
url: https://gitlab/pdm/transmittal-api
|
||
|
||
servers:
|
||
- url: https://api.sarex.io/transmittals
|
||
description: Production (ingress, root_path=/transmittals)
|
||
- url: https://stage-api.sarex.io/transmittals
|
||
description: Stage (ingress, root_path=/transmittals)
|
||
- url: http://transmittal-service.transmittal-api-stage.svc.cluster.local
|
||
description: Внутрикластерный адрес (ClusterIP, порт 80 → 8000). Единственный способ достучаться до /internal/v1
|
||
- url: http://localhost:8001
|
||
description: Локальный запуск (Uvicorn, порт по умолчанию 8001)
|
||
|
||
tags:
|
||
- name: infra
|
||
description: Служебные эндпоинты (проверка доступности)
|
||
- name: transmittals
|
||
description: Трансмитталы — создание, просмотр, согласование, поиск, акты
|
||
- name: transmittal_templates
|
||
description: Шаблоны трансмитталов
|
||
- name: steps
|
||
description: Шаги маршрута согласования
|
||
- name: internal
|
||
description: Внутренние эндпоинты (только внутри кластера)
|
||
|
||
security:
|
||
- bearerAuth: []
|
||
|
||
paths:
|
||
# ==========================================================================
|
||
# Infra
|
||
# ==========================================================================
|
||
/api/v1/healthcheck:
|
||
get:
|
||
tags: [infra]
|
||
summary: Проверка доступности зависимостей
|
||
description: |
|
||
Параллельно проверяет доступность всех внешних зависимостей (БД, S3,
|
||
и HTTP-сервисов) и возвращает агрегированный статус `healthy` или
|
||
`partially_healthy`. Аутентификация не требуется.
|
||
operationId: healthcheck
|
||
security: []
|
||
responses:
|
||
'200':
|
||
description: Статус доступности зависимостей
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/HealthCheckResponse'
|
||
|
||
# ==========================================================================
|
||
# Steps
|
||
# ==========================================================================
|
||
/api/v1/steps:
|
||
get:
|
||
tags: [steps]
|
||
summary: Список шагов
|
||
operationId: getSteps
|
||
parameters:
|
||
- name: limit
|
||
in: query
|
||
required: false
|
||
schema:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 32767
|
||
default: 100
|
||
- name: bookmark
|
||
in: query
|
||
required: false
|
||
schema:
|
||
type: string
|
||
nullable: true
|
||
responses:
|
||
'200':
|
||
description: Страница шагов
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/Page_StepReadResponseDto'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/steps/{id}:
|
||
get:
|
||
tags: [steps]
|
||
summary: Шаг по id
|
||
operationId: getStep
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
minimum: 0
|
||
maximum: 32767
|
||
responses:
|
||
'200':
|
||
description: Шаг
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/StepReadResponseDto'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
# ==========================================================================
|
||
# Transmittals
|
||
# ==========================================================================
|
||
/api/v1/transmittals:
|
||
post:
|
||
tags: [transmittals]
|
||
summary: Список трансмитталов ресурса
|
||
description: Пагинированный список трансмитталов по `resource_id` со сводной статистикой по статусам.
|
||
operationId: listTransmittals
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalListRequestDto'
|
||
responses:
|
||
'200':
|
||
description: Страница трансмитталов и статистика по статусам
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalListResponseDto'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittals/create:
|
||
post:
|
||
tags: [transmittals]
|
||
summary: Создать трансмиттал
|
||
description: |
|
||
Создаёт трансмиттал. Требуется хотя бы один документ (`documents_to_approve`)
|
||
и хотя бы один получатель (`receivers`).
|
||
operationId: createTransmittal
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalCreateRequestDto'
|
||
responses:
|
||
'200':
|
||
description: Идентификатор созданного трансмиттала
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalCreateResponseDto'
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittals/global_statuses:
|
||
post:
|
||
tags: [transmittals]
|
||
summary: Глобальные статусы по набору ресурсов
|
||
description: Возвращает статистику статусов трансмитталов по списку `resource_ids`.
|
||
operationId: getGlobalStatuses
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalGetGlobalStatusesRequestDto'
|
||
responses:
|
||
'200':
|
||
description: Статистика статусов по ресурсам
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalGetGlobalStatusesResponseDto'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittals/status:
|
||
get:
|
||
tags: [transmittals]
|
||
summary: Справочник статусов
|
||
operationId: listStatuses
|
||
responses:
|
||
'200':
|
||
description: Список типов статусов
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/StatusesListResponseDto'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
|
||
/api/v1/transmittals/count:
|
||
get:
|
||
tags: [transmittals]
|
||
summary: Число открытых трансмитталов пользователя
|
||
description: Количество незакрытых трансмитталов, требующих действия текущего пользователя.
|
||
operationId: myOpenTransmittalsCount
|
||
responses:
|
||
'200':
|
||
description: Количество открытых трансмитталов
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalOpenCountResponseDto'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
|
||
/api/v1/transmittals/search:
|
||
post:
|
||
tags: [transmittals]
|
||
summary: Поиск трансмитталов в ресурсе
|
||
description: Поиск и фильтрация трансмитталов в рамках одного ресурса (`resource_id`).
|
||
operationId: searchTransmittals
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalSearchFilterRequestDto'
|
||
responses:
|
||
'200':
|
||
description: Страница трансмитталов и статистика по статусам
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalListResponseDto'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittals/search/resources:
|
||
post:
|
||
tags: [transmittals]
|
||
summary: Поиск по нескольким ресурсам
|
||
description: Фильтрация трансмитталов по списку ресурсов (`resource_ids`); возвращает статистику статусов по ресурсам.
|
||
operationId: searchTransmittalsResources
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalSearchFilterDto'
|
||
responses:
|
||
'200':
|
||
description: Статистика статусов по ресурсам
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalGetGlobalStatusesResponseDto'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittals/{transmittal_id}:
|
||
parameters:
|
||
- $ref: '#/components/parameters/TransmittalId'
|
||
get:
|
||
tags: [transmittals]
|
||
summary: Трансмиттал по id
|
||
operationId: getTransmittal
|
||
responses:
|
||
'200':
|
||
description: Трансмиттал с историей действий и документами
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalReadResponseDto'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
delete:
|
||
tags: [transmittals]
|
||
summary: Удалить трансмиттал
|
||
operationId: deleteTransmittal
|
||
responses:
|
||
'204': { description: Удалено }
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittals/{transmittal_id}/approve:
|
||
parameters:
|
||
- $ref: '#/components/parameters/TransmittalId'
|
||
put:
|
||
tags: [transmittals]
|
||
summary: Принять трансмиттал
|
||
description: Фиксирует действие «принять» текущего пользователя на текущем шаге (с опциональным комментарием). По завершении может инициировать генерацию акта.
|
||
operationId: approveTransmittal
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UserActionCreateRequest'
|
||
responses:
|
||
'200':
|
||
description: Созданное действие пользователя
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UserActionCreateResponseDto'
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittals/{transmittal_id}/decline:
|
||
parameters:
|
||
- $ref: '#/components/parameters/TransmittalId'
|
||
put:
|
||
tags: [transmittals]
|
||
summary: Отклонить трансмиттал
|
||
description: Фиксирует действие «отклонить» текущего пользователя на текущем шаге (с опциональным комментарием).
|
||
operationId: declineTransmittal
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UserActionCreateRequest'
|
||
responses:
|
||
'200':
|
||
description: Созданное действие пользователя
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UserActionCreateResponseDto'
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittals/{transmittal_id}/act_available:
|
||
parameters:
|
||
- $ref: '#/components/parameters/TransmittalId'
|
||
get:
|
||
tags: [transmittals]
|
||
summary: Доступность акта
|
||
description: Признак готовности акта для скачивания по данному трансмитталу.
|
||
operationId: actAvailable
|
||
responses:
|
||
'200':
|
||
description: Готовность акта
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalGetActReadinessResponse'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittals/{transmittal_id}/download_act:
|
||
parameters:
|
||
- $ref: '#/components/parameters/TransmittalId'
|
||
get:
|
||
tags: [transmittals]
|
||
summary: Скачать акт
|
||
description: Возвращает presigned-URL для скачивания акта из S3.
|
||
operationId: downloadAct
|
||
responses:
|
||
'200':
|
||
description: Presigned-URL акта
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalDownloadActResponse'
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittals/{transmittal_id}/link_review:
|
||
parameters:
|
||
- $ref: '#/components/parameters/TransmittalId'
|
||
post:
|
||
tags: [transmittals]
|
||
summary: Привязать review к трансмитталу
|
||
operationId: linkReview
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalLinkReviewRequest'
|
||
responses:
|
||
'204': { description: Review привязан }
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
# ==========================================================================
|
||
# Transmittal templates
|
||
# ==========================================================================
|
||
/api/v1/transmittal_templates:
|
||
post:
|
||
tags: [transmittal_templates]
|
||
summary: Список шаблонов трансмитталов
|
||
description: Пагинированный список шаблонов с фильтрами. Тело запроса опционально (при отсутствии применяются значения по умолчанию).
|
||
operationId: listTransmittalTemplates
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalTemplateListFiltersRequest'
|
||
responses:
|
||
'200':
|
||
description: Страница шаблонов
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/Page_TransmittalTemplateListResponse'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittal_templates/create:
|
||
post:
|
||
tags: [transmittal_templates]
|
||
summary: Создать шаблон
|
||
operationId: createTransmittalTemplate
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalTemplateCreateRequestDto'
|
||
responses:
|
||
'200':
|
||
description: Идентификатор созданного шаблона
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalTemplateCreateResponseDto'
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'409': { $ref: '#/components/responses/Conflict' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittal_templates/select:
|
||
get:
|
||
tags: [transmittal_templates]
|
||
summary: Шаблоны для выбора
|
||
description: Плоский список шаблонов (id/имя/автор), доступных для выбора в рамках ресурса.
|
||
operationId: listTransmittalTemplatesForSelect
|
||
parameters:
|
||
- name: resource
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
- name: template_id
|
||
in: query
|
||
required: false
|
||
description: Один или несколько id шаблонов для фильтрации
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
responses:
|
||
'200':
|
||
description: Список шаблонов для выбора
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/Result_TransmittalTemplateSelectListResponse'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/api/v1/transmittal_templates/{transmittal_template_id}:
|
||
parameters:
|
||
- $ref: '#/components/parameters/TransmittalTemplateId'
|
||
get:
|
||
tags: [transmittal_templates]
|
||
summary: Шаблон по id
|
||
operationId: getTransmittalTemplate
|
||
parameters:
|
||
- name: resource
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
'200':
|
||
description: Шаблон трансмиттала
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalTemplateGetSingleResponse'
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
patch:
|
||
tags: [transmittal_templates]
|
||
summary: Обновить шаблон
|
||
operationId: updateTransmittalTemplate
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalTemplateUpdateRequest'
|
||
responses:
|
||
'204': { description: Обновлено }
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'409': { $ref: '#/components/responses/Conflict' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
delete:
|
||
tags: [transmittal_templates]
|
||
summary: Удалить шаблон
|
||
operationId: deleteTransmittalTemplate
|
||
responses:
|
||
'204': { description: Удалено }
|
||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||
'403': { $ref: '#/components/responses/Forbidden' }
|
||
'410': { $ref: '#/components/responses/Gone' }
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
# ==========================================================================
|
||
# Internal (cluster-only)
|
||
# ==========================================================================
|
||
/internal/v1/transmittals:
|
||
post:
|
||
tags: [internal]
|
||
summary: Список трансмитталов (внутренний)
|
||
description: Внутренний список трансмитталов по фильтрам. Без аутентификации на уровне приложения; доступен только внутри кластера.
|
||
operationId: internalGetTransmittals
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalListInternalRequest'
|
||
responses:
|
||
'200':
|
||
description: Список трансмитталов
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/Result_TransmittalReadListResponseDto'
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
/internal/v1/transmittals/by_bundle_ids:
|
||
post:
|
||
tags: [internal]
|
||
summary: Трансмитталы по bundle id (внутренний)
|
||
description: Возвращает трансмитталы, связанные с переданными `bundle_ids`. Без аутентификации на уровне приложения; доступен только внутри кластера.
|
||
operationId: internalGetTransmittalsByBundleIds
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/TransmittalGetByBundleIdsRequest'
|
||
responses:
|
||
'200':
|
||
description: Трансмитталы по bundle id
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/Result_TransmittalGetByBundleIdsResponse'
|
||
'422': { $ref: '#/components/responses/ValidationError' }
|
||
|
||
components:
|
||
securitySchemes:
|
||
bearerAuth:
|
||
type: http
|
||
scheme: bearer
|
||
bearerFormat: JWT
|
||
description: |
|
||
JWT в заголовке `Authorization: Bearer <token>`. Проверяется публичным
|
||
ключом (`RS512`) в режиме sarex-backend либо принимается как есть в
|
||
режиме Zitadel (см. заголовок `identity`).
|
||
identityToken:
|
||
type: apiKey
|
||
in: header
|
||
name: identity
|
||
description: |
|
||
Опциональный заголовок `identity` (`Identity <jwt>`) для режима Zitadel.
|
||
При его наличии полезная нагрузка берётся из этого токена, а подпись
|
||
основного токена сервисом не проверяется.
|
||
|
||
parameters:
|
||
TransmittalId:
|
||
name: transmittal_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
TransmittalTemplateId:
|
||
name: transmittal_template_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
|
||
responses:
|
||
BadRequest:
|
||
description: Некорректный запрос / бизнес-правило нарушено
|
||
content:
|
||
application/problem+json:
|
||
schema:
|
||
$ref: '#/components/schemas/ApiError'
|
||
Unauthorized:
|
||
description: Токен не предоставлен или невалиден
|
||
content:
|
||
application/problem+json:
|
||
schema:
|
||
$ref: '#/components/schemas/ApiError'
|
||
Forbidden:
|
||
description: Недостаточно прав
|
||
content:
|
||
application/problem+json:
|
||
schema:
|
||
$ref: '#/components/schemas/ApiError'
|
||
Conflict:
|
||
description: Конфликт (например, имя шаблона уже занято)
|
||
content:
|
||
application/problem+json:
|
||
schema:
|
||
$ref: '#/components/schemas/ApiError'
|
||
Gone:
|
||
description: Запрошенный ресурс не существует (маппинг `NotFound` → `410`)
|
||
content:
|
||
application/problem+json:
|
||
schema:
|
||
$ref: '#/components/schemas/ApiError'
|
||
ValidationError:
|
||
description: Ошибка валидации тела/параметров запроса (FastAPI/Pydantic)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/HTTPValidationError'
|
||
|
||
schemas:
|
||
# --- Общие ------------------------------------------------------------
|
||
ApiError:
|
||
type: object
|
||
description: Ошибка в формате RFC 7807 (application/problem+json)
|
||
properties:
|
||
type: { type: string }
|
||
title: { type: string }
|
||
status: { type: integer }
|
||
detail: { type: string }
|
||
instance:
|
||
type: string
|
||
description: URL запроса, вызвавшего ошибку
|
||
required: [type, title, status, detail, instance]
|
||
|
||
HTTPValidationError:
|
||
type: object
|
||
properties:
|
||
detail:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/ValidationErrorItem'
|
||
|
||
ValidationErrorItem:
|
||
type: object
|
||
properties:
|
||
loc:
|
||
type: array
|
||
items:
|
||
anyOf:
|
||
- type: string
|
||
- type: integer
|
||
msg: { type: string }
|
||
type: { type: string }
|
||
required: [loc, msg, type]
|
||
|
||
ReceiversRequestDto:
|
||
type: object
|
||
description: Получатели трансмиттала (запрос). Хотя бы один из наборов должен быть непуст.
|
||
properties:
|
||
users:
|
||
type: array
|
||
items: { type: integer, minimum: 0, maximum: 9223372036854775807 }
|
||
uniqueItems: true
|
||
departments:
|
||
type: array
|
||
items: { type: integer }
|
||
uniqueItems: true
|
||
roles:
|
||
type: array
|
||
items: { type: integer }
|
||
uniqueItems: true
|
||
|
||
ReceiversReadResponseDto:
|
||
type: object
|
||
properties:
|
||
users: { type: array, items: { type: integer } }
|
||
departments: { type: array, items: { type: integer } }
|
||
roles: { type: array, items: { type: integer } }
|
||
required: [users, departments, roles]
|
||
|
||
ReceiversFilterDto:
|
||
type: object
|
||
properties:
|
||
users: { type: array, items: { type: integer } }
|
||
departments: { type: array, items: { type: integer } }
|
||
roles: { type: array, items: { type: integer } }
|
||
|
||
DocumentVersionRequestDto:
|
||
type: object
|
||
properties:
|
||
document_id: { type: integer, minimum: 0, maximum: 2147483647 }
|
||
bundle_id: { type: string, format: uuid }
|
||
required: [document_id, bundle_id]
|
||
|
||
DocumentVersionReadResponse:
|
||
type: object
|
||
properties:
|
||
document_id: { type: integer }
|
||
bundle_id: { type: string, format: uuid }
|
||
required: [document_id, bundle_id]
|
||
|
||
StatusReadResponseDto:
|
||
type: object
|
||
properties:
|
||
id: { type: integer }
|
||
name: { type: string }
|
||
slug: { type: string }
|
||
required: [id, name, slug]
|
||
|
||
StatusSimpleDto:
|
||
type: object
|
||
properties:
|
||
slug: { type: string }
|
||
name: { type: string }
|
||
required: [slug, name]
|
||
|
||
StatusesListResponseDto:
|
||
type: object
|
||
properties:
|
||
statuses:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/StatusSimpleDto' }
|
||
required: [statuses]
|
||
|
||
StepReadResponseDto:
|
||
type: object
|
||
properties:
|
||
id: { type: integer }
|
||
name: { type: string }
|
||
slug: { type: string }
|
||
required: [id, name, slug]
|
||
|
||
ActionReadResponse:
|
||
type: object
|
||
properties:
|
||
id: { type: integer }
|
||
step_id: { type: integer }
|
||
name: { type: string }
|
||
slug: { type: string }
|
||
required: [id, step_id, name, slug]
|
||
|
||
ReviewLightResponse:
|
||
type: object
|
||
properties:
|
||
id: { type: integer }
|
||
name: { type: string }
|
||
required: [id, name]
|
||
|
||
UserActionCreateRequest:
|
||
type: object
|
||
properties:
|
||
comment: { type: string, nullable: true }
|
||
|
||
UserActionCreateResponseDto:
|
||
type: object
|
||
properties:
|
||
id: { type: string, format: uuid }
|
||
transmittal_id: { type: string, format: uuid }
|
||
action_id: { type: integer }
|
||
comment: { type: string, nullable: true }
|
||
required: [id, transmittal_id, action_id, comment]
|
||
|
||
UserActionReadResponse:
|
||
type: object
|
||
properties:
|
||
id: { type: string, format: uuid }
|
||
user_id: { type: integer }
|
||
transmittal_id: { type: string, format: uuid }
|
||
action_id: { type: integer }
|
||
comment: { type: string, nullable: true }
|
||
action: { $ref: '#/components/schemas/ActionReadResponse' }
|
||
created_at: { type: string, format: date-time }
|
||
required: [id, user_id, transmittal_id, action_id, comment, action, created_at]
|
||
|
||
# --- Wrappers ---------------------------------------------------------
|
||
Page_StepReadResponseDto:
|
||
type: object
|
||
properties:
|
||
result:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/StepReadResponseDto' }
|
||
next: { type: string }
|
||
prev: { type: string }
|
||
required: [result, next, prev]
|
||
|
||
Page_TransmittalReadListResponseDto:
|
||
type: object
|
||
properties:
|
||
result:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/TransmittalReadListResponseDto' }
|
||
next: { type: string }
|
||
prev: { type: string }
|
||
required: [result, next, prev]
|
||
|
||
Page_TransmittalTemplateListResponse:
|
||
type: object
|
||
properties:
|
||
result:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/TransmittalTemplateListResponse' }
|
||
next: { type: string }
|
||
prev: { type: string }
|
||
required: [result, next, prev]
|
||
|
||
Result_TransmittalTemplateSelectListResponse:
|
||
type: object
|
||
properties:
|
||
result:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/TransmittalTemplateSelectListResponse' }
|
||
required: [result]
|
||
|
||
Result_TransmittalReadListResponseDto:
|
||
type: object
|
||
properties:
|
||
result:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/TransmittalReadListResponseDto' }
|
||
required: [result]
|
||
|
||
Result_TransmittalGetByBundleIdsResponse:
|
||
type: object
|
||
properties:
|
||
result:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/TransmittalGetByBundleIdsResponse' }
|
||
required: [result]
|
||
|
||
# --- Transmittals -----------------------------------------------------
|
||
TransmittalCreateRequestDto:
|
||
type: object
|
||
properties:
|
||
name: { type: string, minLength: 1, maxLength: 255 }
|
||
company_id: { type: integer, minimum: 0, maximum: 18446744073709551615 }
|
||
additional_information: { type: string, nullable: true }
|
||
resource_id: { type: string, format: uuid }
|
||
auto_send: { type: boolean }
|
||
documents_to_approve:
|
||
type: array
|
||
description: Не менее одного документа
|
||
minItems: 1
|
||
uniqueItems: true
|
||
items: { $ref: '#/components/schemas/DocumentVersionRequestDto' }
|
||
receivers: { $ref: '#/components/schemas/ReceiversRequestDto' }
|
||
deadline_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
description: Дедлайн в будущем
|
||
required: [name, company_id, additional_information, resource_id, auto_send, documents_to_approve, receivers, deadline_at]
|
||
|
||
TransmittalCreateResponseDto:
|
||
type: object
|
||
properties:
|
||
id: { type: string, format: uuid }
|
||
required: [id]
|
||
|
||
TransmittalListRequestDto:
|
||
type: object
|
||
properties:
|
||
limit: { type: integer, default: 1000 }
|
||
bookmark: { type: string, nullable: true }
|
||
resource_id: { type: string, format: uuid }
|
||
required: [resource_id]
|
||
|
||
TransmittalReadListResponseDto:
|
||
type: object
|
||
properties:
|
||
id: { type: string, format: uuid }
|
||
resource_id: { type: string, format: uuid }
|
||
created_by: { type: integer }
|
||
current_step_id: { type: integer }
|
||
"no": { type: integer }
|
||
name: { type: string }
|
||
additional_information: { type: string, nullable: true }
|
||
steps: { type: array, items: { type: integer } }
|
||
auto_send: { type: boolean }
|
||
receivers: { $ref: '#/components/schemas/ReceiversReadResponseDto' }
|
||
deadline_at: { type: string, format: date-time, nullable: true }
|
||
status: { $ref: '#/components/schemas/StatusReadResponseDto' }
|
||
step: { $ref: '#/components/schemas/StepReadResponseDto' }
|
||
sent_at: { type: string, format: date-time, nullable: true }
|
||
received_at: { type: string, format: date-time, nullable: true }
|
||
act_available: { type: boolean }
|
||
reviews:
|
||
type: array
|
||
nullable: true
|
||
items: { $ref: '#/components/schemas/ReviewLightResponse' }
|
||
required: [id, resource_id, created_by, current_step_id, "no", name, additional_information, steps, auto_send, receivers, deadline_at, status, step, sent_at, received_at, act_available]
|
||
|
||
TransmittalReadResponseDto:
|
||
type: object
|
||
properties:
|
||
id: { type: string, format: uuid }
|
||
resource_id: { type: string, format: uuid }
|
||
created_by: { type: integer }
|
||
current_step_id: { type: integer }
|
||
"no": { type: integer }
|
||
name: { type: string }
|
||
additional_information: { type: string, nullable: true }
|
||
steps: { type: array, items: { type: integer } }
|
||
auto_send: { type: boolean }
|
||
receivers: { $ref: '#/components/schemas/ReceiversReadResponseDto' }
|
||
deadline_at: { type: string, format: date-time, nullable: true }
|
||
sent_at: { type: string, format: date-time, nullable: true }
|
||
received_at: { type: string, format: date-time, nullable: true }
|
||
act_available: { type: boolean }
|
||
status: { $ref: '#/components/schemas/StatusReadResponseDto' }
|
||
step: { $ref: '#/components/schemas/StepReadResponseDto' }
|
||
documents_to_approve:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/DocumentVersionReadResponse' }
|
||
history:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/UserActionReadResponse' }
|
||
required: [id, resource_id, created_by, current_step_id, "no", name, additional_information, steps, auto_send, receivers, deadline_at, sent_at, received_at, act_available, status, step, documents_to_approve, history]
|
||
|
||
TransmittalStatusesStatResponseDto:
|
||
type: object
|
||
properties:
|
||
status: { $ref: '#/components/schemas/StatusReadResponseDto' }
|
||
count: { type: integer }
|
||
required: [status, count]
|
||
|
||
TransmittalListResponseDto:
|
||
type: object
|
||
properties:
|
||
page: { $ref: '#/components/schemas/Page_TransmittalReadListResponseDto' }
|
||
statuses_stat:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/TransmittalStatusesStatResponseDto' }
|
||
required: [page, statuses_stat]
|
||
|
||
TransmittalGlobalStatusesStatResponseDto:
|
||
type: object
|
||
properties:
|
||
resource_id: { type: string, format: uuid }
|
||
statuses:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/TransmittalStatusesStatResponseDto' }
|
||
required: [resource_id, statuses]
|
||
|
||
TransmittalGetGlobalStatusesRequestDto:
|
||
type: object
|
||
properties:
|
||
resource_ids:
|
||
type: array
|
||
items: { type: string, format: uuid }
|
||
required: [resource_ids]
|
||
|
||
TransmittalGetGlobalStatusesResponseDto:
|
||
type: object
|
||
properties:
|
||
result:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/TransmittalGlobalStatusesStatResponseDto' }
|
||
required: [result]
|
||
|
||
TransmittalDownloadActResponse:
|
||
type: object
|
||
properties:
|
||
presigned_url: { type: string }
|
||
required: [presigned_url]
|
||
|
||
TransmittalGetActReadinessResponse:
|
||
type: object
|
||
properties:
|
||
act_available: { type: boolean }
|
||
required: [act_available]
|
||
|
||
TransmittalOpenCountResponseDto:
|
||
type: object
|
||
properties:
|
||
count: { type: integer }
|
||
required: [count]
|
||
|
||
TransmittalLinkReviewRequest:
|
||
type: object
|
||
properties:
|
||
review_id: { type: integer }
|
||
required: [review_id]
|
||
|
||
TransmittalSearchFilterRequestDto:
|
||
type: object
|
||
description: Фильтр поиска в рамках одного ресурса
|
||
properties:
|
||
q: { type: string, nullable: true }
|
||
resource_id: { type: string, format: uuid }
|
||
status_slug: { type: array, items: { type: string } }
|
||
created_by: { type: array, items: { type: integer } }
|
||
receivers:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversFilterDto' }]
|
||
created_from: { type: string, format: date-time, nullable: true }
|
||
created_to: { type: string, format: date-time, nullable: true }
|
||
received_from: { type: string, format: date-time, nullable: true }
|
||
received_to: { type: string, format: date-time, nullable: true }
|
||
deadline_at: { type: string, format: date-time, nullable: true }
|
||
unlimited: { type: boolean, nullable: true, default: false }
|
||
auto_send: { type: array, items: { type: boolean } }
|
||
limit: { type: integer, nullable: true, default: 100 }
|
||
bookmark: { type: string, nullable: true }
|
||
required: [resource_id]
|
||
|
||
TransmittalSearchFilterDto:
|
||
type: object
|
||
description: Фильтр поиска по нескольким ресурсам
|
||
properties:
|
||
q: { type: string, nullable: true }
|
||
resource_ids: { type: array, items: { type: string, format: uuid } }
|
||
status_slug: { type: array, items: { type: string } }
|
||
created_by: { type: array, items: { type: integer } }
|
||
receivers:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversFilterDto' }]
|
||
created_from: { type: string, format: date-time, nullable: true }
|
||
created_to: { type: string, format: date-time, nullable: true }
|
||
received_from: { type: string, format: date-time, nullable: true }
|
||
received_to: { type: string, format: date-time, nullable: true }
|
||
deadline_at: { type: string, format: date-time, nullable: true }
|
||
unlimited: { type: boolean, nullable: true, default: false }
|
||
auto_send: { type: array, items: { type: boolean } }
|
||
limit: { type: integer, nullable: true, default: 100 }
|
||
bookmark: { type: string, nullable: true }
|
||
|
||
# --- Internal ---------------------------------------------------------
|
||
TransmittalListInternalRequest:
|
||
type: object
|
||
properties:
|
||
limit: { type: integer, default: 100 }
|
||
transmittal_ids: { type: array, items: { type: string, format: uuid } }
|
||
company_id: { type: integer, nullable: true }
|
||
resource_id: { type: string, format: uuid, nullable: true }
|
||
|
||
TransmittalGetByBundleIdsRequest:
|
||
type: object
|
||
properties:
|
||
bundle_ids: { type: array, items: { type: string, format: uuid } }
|
||
required: [bundle_ids]
|
||
|
||
TransmittalGetByBundleIdsReadDto:
|
||
type: object
|
||
properties:
|
||
id: { type: string, format: uuid }
|
||
name: { type: string }
|
||
status: { $ref: '#/components/schemas/StatusReadResponseDto' }
|
||
created_at: { type: string, format: date-time }
|
||
required: [id, name, status, created_at]
|
||
|
||
TransmittalGetByBundleIdsResponse:
|
||
type: object
|
||
properties:
|
||
bundle_id: { type: string, format: uuid }
|
||
transmittals:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/TransmittalGetByBundleIdsReadDto' }
|
||
required: [bundle_id, transmittals]
|
||
|
||
# --- Templates --------------------------------------------------------
|
||
TransmittalTemplateListFiltersRequest:
|
||
type: object
|
||
properties:
|
||
include_wo_resources: { type: boolean, default: true }
|
||
resources: { type: array, nullable: true, items: { type: string, format: uuid } }
|
||
companies: { type: array, nullable: true, items: { type: integer } }
|
||
q: { type: string, nullable: true }
|
||
bookmark: { type: string, nullable: true }
|
||
limit: { type: integer, default: 20 }
|
||
|
||
TransmittalTemplateListResponse:
|
||
type: object
|
||
properties:
|
||
id: { type: string, format: uuid }
|
||
name: { type: string }
|
||
is_active: { type: boolean }
|
||
resource_id: { type: string, format: uuid, nullable: true }
|
||
allowed_initiators:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversReadResponseDto' }]
|
||
created_by: { type: integer }
|
||
created_at: { type: string, format: date-time }
|
||
has_deadline_interval: { type: boolean }
|
||
deadline_interval: { type: integer, minimum: 1, nullable: true, description: Интервал дедлайна в днях }
|
||
auto_send: { type: boolean, nullable: true }
|
||
has_additional_information: { type: boolean }
|
||
additional_information: { type: string, nullable: true }
|
||
receivers:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversReadResponseDto' }]
|
||
invalid_receivers:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversReadResponseDto' }]
|
||
required: [id, name, is_active, resource_id, allowed_initiators, created_by, created_at, has_deadline_interval, deadline_interval, auto_send, has_additional_information, additional_information, receivers, invalid_receivers]
|
||
|
||
TransmittalTemplateCreateRequestDto:
|
||
type: object
|
||
properties:
|
||
name: { type: string, minLength: 1, maxLength: 255 }
|
||
resource_id: { type: string, format: uuid, nullable: true }
|
||
allowed_initiators:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversRequestDto' }]
|
||
company_id: { type: integer }
|
||
has_deadline_interval: { type: boolean }
|
||
deadline_interval: { type: integer, minimum: 1, nullable: true, description: Интервал дедлайна в днях }
|
||
auto_send: { type: boolean, nullable: true }
|
||
has_additional_information: { type: boolean }
|
||
additional_information: { type: string, nullable: true }
|
||
receivers:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversRequestDto' }]
|
||
required: [name, resource_id, allowed_initiators, company_id, has_deadline_interval, deadline_interval, auto_send, has_additional_information, additional_information, receivers]
|
||
|
||
TransmittalTemplateCreateResponseDto:
|
||
type: object
|
||
properties:
|
||
id: { type: string, format: uuid }
|
||
required: [id]
|
||
|
||
TransmittalTemplateSelectListResponse:
|
||
type: object
|
||
properties:
|
||
id: { type: string, format: uuid }
|
||
name: { type: string }
|
||
created_by: { type: integer }
|
||
required: [id, name, created_by]
|
||
|
||
TransmittalTemplateGetSingleResponse:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
created_by: { type: integer }
|
||
has_deadline_interval: { type: boolean }
|
||
deadline_interval: { type: integer, minimum: 1, nullable: true, description: Интервал дедлайна в днях }
|
||
auto_send: { type: boolean, nullable: true }
|
||
has_additional_information: { type: boolean }
|
||
additional_information: { type: string, nullable: true }
|
||
receivers:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversReadResponseDto' }]
|
||
invalid_receivers:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversReadResponseDto' }]
|
||
required: [name, created_by, has_deadline_interval, deadline_interval, auto_send, has_additional_information, additional_information, receivers, invalid_receivers]
|
||
|
||
TransmittalTemplateUpdateRequest:
|
||
type: object
|
||
description: Частичное обновление. Все поля опциональны.
|
||
properties:
|
||
name: { type: string, minLength: 1, maxLength: 255, nullable: true }
|
||
is_active: { type: boolean, nullable: true }
|
||
resource_id: { type: string, format: uuid, nullable: true }
|
||
allowed_initiators:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversRequestDto' }]
|
||
has_deadline_interval: { type: boolean, nullable: true }
|
||
deadline_interval: { type: integer, minimum: 1, nullable: true, description: Интервал дедлайна в днях }
|
||
auto_send: { type: boolean, nullable: true }
|
||
has_additional_information: { type: boolean, nullable: true }
|
||
additional_information: { type: string, nullable: true }
|
||
receivers:
|
||
nullable: true
|
||
allOf: [{ $ref: '#/components/schemas/ReceiversRequestDto' }]
|
||
|
||
# --- Infra ------------------------------------------------------------
|
||
ResourceStatus:
|
||
type: object
|
||
properties:
|
||
name: { type: string }
|
||
available: { type: boolean }
|
||
required: [name, available]
|
||
|
||
HealthCheckResponse:
|
||
type: object
|
||
properties:
|
||
availability:
|
||
type: array
|
||
items: { $ref: '#/components/schemas/ResourceStatus' }
|
||
status:
|
||
type: string
|
||
enum: [healthy, partially_healthy]
|
||
description: Вычисляемое поле — `healthy`, если доступны все зависимости
|
||
readOnly: true
|
||
required: [availability, status]
|