openapi: 3.0.3 info: title: Inspections version: "0.1.0" description: | REST API сервиса **inspections-backend** (`proc/inspections-backend`) — управление событиями/инспекциями (создание, редактирование, поиск, экспорт), их типами, статусами, атрибутами, историей изменений и расчётом доступности исполнителей. Сервис написан на Python (**FastAPI** + **Piccolo ORM**, PostgreSQL). Приложение собирается фабрикой `create_app` в `src/app/http.py`. Помимо HTTP-приложения есть отдельный процесс-консьюмер Kafka (`src/app/kafka.py`), который слушает события EAV-ассетов; в OpenAPI он не отражён. Роутинг: корневой роутер имеет префикс `/api` (`controller/http/api/router.py`), вложенный — `/v1` (`controller/http/api/v1/router.py`), ресурс инспекций — `/inspections` (`controller/http/api/v1/inspection.py`). За реверс-прокси добавляется `root_path` (в k8s — `/inspections`, задаётся `HTTP_APP_ROOT_PATH`). Схема OpenAPI отдаётся по `/openapi.json/`, документация ReDoc — по `/docs/` (Swagger UI отключён). Админ-панель Piccolo монтируется по `/admin/` (если `HTTP_APP_ADMIN_ENABLE=true`). ### Аутентификация Если включён middleware (`JWT_AUTH_ENABLE=true`), все запросы, кроме `/docs/`, `/openapi.json/`, `/admin/`, `/internal/`, требуют заголовок `Authorization: Bearer `. Поддерживается дополнительный заголовок `identity` (метаданные Zitadel): при его наличии полезная нагрузка берётся из него, иначе — из `Authorization`. Токен декодируется **без проверки подписи** (`verify_signature=False`) — доверие обеспечивается сетевым слоем/ingress. При отсутствии заголовка `Authorization` middleware возвращает `401`. При `JWT_AUTH_ENABLE=false` middleware не подключается и используется захардкоженный дефолтный пользователь (`entity/context.py`) — режим локальной разработки. ### Права доступа Операции защищены правами (`InspectionPermission`): `core.can_view_inspections`, `core.can_create_inspection`, `core.can_edit_inspection`, `core.can_delete_inspection`, `core.can_view_all_inspections`. Права берутся из токена; при их отсутствии проверяются права по сервисным аккаунтам на конкретный тип события. Недостаток прав — ответ `403`. ### Пагинация Списочные ответы используют limit/offset-пагинацию и оборачиваются в `Page` (`{ count, result }`). Сортировка задаётся параметрами `order_by` и `ascending`. ### Обработка ошибок Доменные ошибки маппятся на HTTP-статусы (`controller/http/errors.py`) и возвращаются как `{ "detail": "<текст>" }`. Ошибки валидации тела/параметров (Pydantic) отдаются FastAPI в стандартном формате `422`. servers: - url: https://api.sarex.io/inspections description: production - url: https://api.preprod.sarex.io/inspections description: preprod - url: https://stage-api.sarex.io/inspections description: stage - url: http://localhost:8000 description: local (без root_path) tags: - name: Inspections description: События / инспекции - name: Mobile app description: Версии мобильного приложения security: - bearerAuth: [] paths: /api/v1/mobile-app/version/: get: tags: [Mobile app] summary: Версии мобильного приложения operationId: get_mobile_app_version responses: "200": description: Текущая, рекомендуемая и минимально требуемая версии content: application/json: schema: $ref: "#/components/schemas/MobileAppVersion" "401": $ref: "#/components/responses/Unauthorized" /api/v1/inspections/: get: tags: [Inspections] summary: Список событий description: Требует право `core.can_view_inspections`. operationId: get_all parameters: - $ref: "#/components/parameters/OrderByInspection" - $ref: "#/components/parameters/Ascending" - $ref: "#/components/parameters/Limit" - $ref: "#/components/parameters/Offset" - $ref: "#/components/parameters/Search" - $ref: "#/components/parameters/CompanyIdList" - $ref: "#/components/parameters/ResourceIdList" - $ref: "#/components/parameters/TypeIdList" - $ref: "#/components/parameters/StatusIdList" responses: "200": description: Страница событий content: application/json: schema: $ref: "#/components/schemas/PageInspectionRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" post: tags: [Inspections] summary: Создать событие description: Требует право `core.can_create_inspection`. operationId: create requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InspectionCreate" responses: "201": description: Созданное событие content: application/json: schema: $ref: "#/components/schemas/InspectionRead" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "422": $ref: "#/components/responses/ValidationError" /api/v1/inspections/filter/: post: tags: [Inspections] summary: Список событий (фильтры в теле) description: | Аналог `GET /api/v1/inspections/` с передачей фильтров и пагинации в теле запроса. Требует право `core.can_view_inspections`. operationId: post_filter_all requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InspectionFiltersWithPagination" responses: "200": description: Страница событий content: application/json: schema: $ref: "#/components/schemas/PageInspectionRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "422": $ref: "#/components/responses/ValidationError" /api/v1/inspections/light/: get: tags: [Inspections] summary: Список событий (облегчённое представление) description: Требует право `core.can_view_inspections`. operationId: get_all_light parameters: - $ref: "#/components/parameters/OrderByInspection" - $ref: "#/components/parameters/Ascending" - $ref: "#/components/parameters/Limit" - $ref: "#/components/parameters/Offset" - $ref: "#/components/parameters/Search" - $ref: "#/components/parameters/CompanyIdList" - $ref: "#/components/parameters/ResourceIdList" responses: "200": description: Страница облегчённых событий content: application/json: schema: $ref: "#/components/schemas/PageInspectionLightRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" /api/v1/inspections/export/: get: tags: [Inspections] summary: Экспорт событий (xlsx) description: | Возвращает файл экспорта. Поддерживается единственный тип — `xlsx`. Требует право `core.can_view_inspections`. operationId: export parameters: - name: type in: query required: false schema: $ref: "#/components/schemas/InspectionExportType" - $ref: "#/components/parameters/Search" - $ref: "#/components/parameters/CompanyIdList" - $ref: "#/components/parameters/ResourceIdList" - $ref: "#/components/parameters/TypeIdList" - $ref: "#/components/parameters/StatusIdList" responses: "200": description: Файл экспорта headers: Content-Disposition: schema: type: string example: attachment; filename=inspections_export.xlsx content: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet: schema: type: string format: binary "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" /api/v1/inspections/types/: get: tags: [Inspections] summary: Типы событий компании description: Требует право `core.can_view_inspections`. operationId: get_types parameters: - name: company_id in: query required: true description: ID компании schema: type: integer example: 1 responses: "200": description: Список типов событий (полное представление) content: application/json: schema: type: array items: $ref: "#/components/schemas/InspectionTypeFullRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" /api/v1/inspections/status-count/: get: tags: [Inspections] summary: Счётчики по статусам (фильтры в query) description: Требует право `core.can_view_inspections`. operationId: get_status_count parameters: - $ref: "#/components/parameters/Search" - $ref: "#/components/parameters/CompanyIdList" - $ref: "#/components/parameters/ResourceIdList" - $ref: "#/components/parameters/TypeIdList" - $ref: "#/components/parameters/StatusIdList" responses: "200": description: Счётчики по статусам, сгруппированные по ресурсам content: application/json: schema: type: array items: $ref: "#/components/schemas/InspectionStatusCountRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" post: tags: [Inspections] summary: Счётчики по статусам (фильтры в теле) description: Требует право `core.can_view_inspections`. operationId: post_filter_status_count requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InspectionFilters" responses: "200": description: Счётчики по статусам, сгруппированные по ресурсам content: application/json: schema: type: array items: $ref: "#/components/schemas/InspectionStatusCountRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "422": $ref: "#/components/responses/ValidationError" /api/v1/inspections/unavailable-dates/: post: tags: [Inspections] summary: Недоступные даты для исполнителей description: Требует право `core.can_view_inspections`. operationId: get_unavailable_dates requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InspectionUnavailableDatesRequest" responses: "200": description: Список отрезков недоступных дат content: application/json: schema: type: array items: $ref: "#/components/schemas/InspectionUnavailableDatesRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "422": $ref: "#/components/responses/ValidationError" /api/v1/inspections/unavailable-users/: post: tags: [Inspections] summary: Недоступные исполнители на интервал description: Требует право `core.can_view_inspections`. operationId: get_unavailable_users requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InspectionUnavailableUsersRequest" responses: "200": description: Список недоступных пользователей content: application/json: schema: $ref: "#/components/schemas/InspectionUnavailableUsersRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "422": $ref: "#/components/responses/ValidationError" /api/v1/inspections/change-history/: get: tags: [Inspections] summary: История изменений событий description: Требует право `core.can_view_inspections`. operationId: get_change_history parameters: - $ref: "#/components/parameters/OrderByChangeHistory" - $ref: "#/components/parameters/Ascending" - $ref: "#/components/parameters/Limit" - $ref: "#/components/parameters/Offset" - name: created_at_after in: query schema: { type: string, format: date-time, nullable: true } - name: created_at_before in: query schema: { type: string, format: date-time, nullable: true } - name: updated_at_after in: query schema: { type: string, format: date-time, nullable: true } - name: updated_at_before in: query schema: { type: string, format: date-time, nullable: true } - name: inspection_public_id in: query schema: type: array nullable: true items: { type: string, format: uuid } - $ref: "#/components/parameters/CompanyIdList" - $ref: "#/components/parameters/ResourceIdList" responses: "200": description: Страница записей истории изменений content: application/json: schema: $ref: "#/components/schemas/PageInspectionChangeRecordRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" /api/v1/inspections/filter-options/: post: tags: [Inspections] summary: Доступные значения фильтров description: | Возвращает возможные значения для перечисленных полей фильтра. Требует право `core.can_view_inspections`. operationId: get_filter_options requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InspectionFilterOptionsRequest" responses: "200": description: Маппинг «поле фильтра → список значений» content: application/json: schema: $ref: "#/components/schemas/InspectionFilterOptionsRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "422": $ref: "#/components/responses/ValidationError" /api/v1/inspections/aggregate/{field_name}/{aggregate_func}/: get: tags: [Inspections] summary: Агрегация по полю события description: Требует право `core.can_view_inspections`. operationId: aggregate parameters: - name: field_name in: path required: true schema: $ref: "#/components/schemas/InspectionAggregateField" - name: aggregate_func in: path required: true schema: $ref: "#/components/schemas/AggregateFunc" - $ref: "#/components/parameters/Search" - $ref: "#/components/parameters/CompanyIdList" - $ref: "#/components/parameters/ResourceIdList" responses: "200": description: Результат агрегации content: application/json: schema: $ref: "#/components/schemas/AggregateResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" /api/v1/inspections/{instance_id}/: get: tags: [Inspections] summary: Событие по id description: Требует право `core.can_view_inspections`. operationId: retrieve parameters: - $ref: "#/components/parameters/InstanceId" responses: "200": description: Событие content: application/json: schema: $ref: "#/components/schemas/InspectionRead" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" patch: tags: [Inspections] summary: Частичное обновление события description: Требует право `core.can_edit_inspection`. operationId: partial_update parameters: - $ref: "#/components/parameters/InstanceId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InspectionPartialUpdate" responses: "200": description: Обновлённое событие content: application/json: schema: $ref: "#/components/schemas/InspectionRead" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "422": $ref: "#/components/responses/ValidationError" delete: tags: [Inspections] summary: Удалить событие description: Требует право `core.can_delete_inspection`. operationId: delete parameters: - $ref: "#/components/parameters/InstanceId" responses: "204": description: Удалено "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT description: | JWT в заголовке `Authorization: Bearer `. Опционально — дополнительный заголовок `identity: Bearer ` (метаданные Zitadel). Подпись токена не проверяется. parameters: InstanceId: name: instance_id in: path required: true description: Публичный ID (UUID) события schema: type: string format: uuid Limit: name: limit in: query description: Максимальное количество объектов schema: { type: integer, default: 100 } Offset: name: offset in: query description: Количество пропущенных объектов schema: { type: integer, default: 0 } Ascending: name: ascending in: query description: Сортировка по возрастанию schema: { type: boolean, default: true } OrderByInspection: name: order_by in: query description: Поле сортировки schema: type: string enum: [id, inspection_dt] default: id OrderByChangeHistory: name: order_by in: query description: Поле сортировки schema: type: string enum: [id, created_at] default: id Search: name: search in: query description: Поиск по названию, локации и описанию schema: { type: string, nullable: true } CompanyIdList: name: company_id in: query description: ID компании schema: type: array nullable: true items: { type: integer } ResourceIdList: name: resource_id in: query description: ID ресурса (проекта) schema: type: array nullable: true items: { type: string, format: uuid } TypeIdList: name: type_id in: query description: ID типа schema: type: array nullable: true items: { type: integer } StatusIdList: name: status_id in: query description: ID статуса schema: type: array nullable: true items: { type: integer } responses: BadRequest: description: Некорректный запрос content: application/json: schema: $ref: "#/components/schemas/HTTPError" example: { detail: "Bad Request" } Unauthorized: description: Не аутентифицирован content: application/json: schema: $ref: "#/components/schemas/HTTPError" example: { detail: "Authorization header is required" } Forbidden: description: Недостаточно прав content: application/json: schema: $ref: "#/components/schemas/HTTPError" example: { detail: "Forbidden" } NotFound: description: Ресурс не найден content: application/json: schema: $ref: "#/components/schemas/HTTPError" example: { detail: "Not Found" } ValidationError: description: Ошибка валидации (Pydantic / FastAPI) content: application/json: schema: $ref: "#/components/schemas/HTTPValidationError" schemas: HTTPError: type: object properties: detail: type: string description: Описание ошибки required: [detail] HTTPValidationError: type: object properties: detail: type: array items: type: object properties: loc: type: array items: anyOf: - { type: string } - { type: integer } msg: { type: string } type: { type: string } MobileAppVersion: type: object properties: current_version: { type: string, example: "1.0.0" } recommended_version: { type: string, example: "1.0.0" } required_version: { type: string, example: "1.0.0" } required: [current_version, recommended_version, required_version] AttributeValueType: description: Значение атрибута (одиночное) nullable: true anyOf: - { type: boolean } - { type: integer } - { type: number } - { type: string } - { type: array, items: { type: integer } } AttributeMultivalueType: description: Мультизначение атрибута type: array items: nullable: true anyOf: - { type: boolean } - { type: integer } - { type: number } - { type: string } InspectionExportType: type: string enum: [xlsx] default: xlsx InspectionAggregateField: type: string enum: [created_at, inspection_dt] AggregateFunc: type: string enum: [minmax] AggregateResponse: type: object properties: min: nullable: true description: Минимальное значение example: 0 max: nullable: true description: Максимальное значение example: 1 AllowedToSetRole: type: string enum: [author, responsible_user, author_or_responsible_user] SetRole: type: string enum: [author, responsible_user] InspectionFilters: type: object description: Фильтры выборки событий properties: search: { type: string, nullable: true, description: Поиск по названию, локации и описанию } created_at_after: { type: string, format: date-time, nullable: true } created_at_before: { type: string, format: date-time, nullable: true } updated_at_after: { type: string, format: date-time, nullable: true } updated_at_before: { type: string, format: date-time, nullable: true } public_id: type: array nullable: true items: { type: string, format: uuid } company_id: type: array nullable: true items: { type: integer, minimum: 1 } resource_id: type: array nullable: true items: { type: string, format: uuid } premise_id: type: array nullable: true items: { type: string, format: uuid } author_id: type: array nullable: true items: { type: integer, minimum: 1 } inspection_dt_after: { type: string, format: date-time, nullable: true } inspection_dt_before: { type: string, format: date-time, nullable: true } inspection_dt_end_after: { type: string, format: date-time, nullable: true } inspection_dt_end_before: { type: string, format: date-time, nullable: true } responsible_user_id: type: array nullable: true items: { type: integer, minimum: 1 } type_id: type: array nullable: true items: { type: integer } status_id: type: array nullable: true items: { type: integer } attributes: type: object nullable: true description: >- Маппинг id атрибута → значение. Может передаваться JSON-строкой. additionalProperties: oneOf: - $ref: "#/components/schemas/AttributeValueType" - $ref: "#/components/schemas/AttributeMultivalueType" InspectionFiltersWithPagination: allOf: - $ref: "#/components/schemas/InspectionFilters" - type: object properties: order_by: type: string enum: [id, inspection_dt] default: id ascending: { type: boolean, default: true } limit: { type: integer, default: 100 } offset: { type: integer, default: 0 } InspectionExportFilters: allOf: - $ref: "#/components/schemas/InspectionFilters" - type: object properties: type: $ref: "#/components/schemas/InspectionExportType" InspectionFilterOptionsRequest: type: object properties: filters: $ref: "#/components/schemas/InspectionFilters" fields: type: array description: Список полей, для которых нужно получить значения items: { type: string } example: [author_id, company_id] required: [fields] InspectionFilterOptionsRead: type: object properties: options: type: object description: Маппинг «поле фильтра» → «список значений» additionalProperties: true example: { company_id: [1, 2, 3, null] } required: [options] AssetAttributeCreate: type: object properties: attribute_id: { type: integer, example: 1 } asset_id: { type: string, example: "1" } order: { type: integer, example: 1 } required: [attribute_id, asset_id, order] AssetAttributeRead: allOf: - $ref: "#/components/schemas/AssetAttributeCreate" - type: object properties: value: $ref: "#/components/schemas/AttributeValueType" required: [value] AttributeRead: type: object properties: id: { type: integer, example: 1 } created_at: { type: string, format: date-time } updated_at: { type: string, format: date-time } attribute_id: { type: integer, example: 1 } attribute_name: { type: string, example: "Название атрибута" } asset_id: { type: string, nullable: true, example: "1" } asset_name: { type: string, nullable: true, example: "Название ассета" } root_asset_id: { type: string, nullable: true, example: "1" } required: { type: boolean, example: false } resource_id: { type: string, format: uuid, nullable: true } required: [id, created_at, updated_at, attribute_id, attribute_name, required] AttachmentsChange: type: object description: Состояние вложений до и после изменения properties: before: type: array items: { type: string } after: type: array items: { type: string } example: { before: ["report.pdf"], after: ["report.pdf", "photo.jpg"] } StatusSettingRead: type: object properties: id: { type: integer, example: 1 } created_at: { type: string, format: date-time } updated_at: { type: string, format: date-time } inspection_status_id: { type: integer, example: 1 } set_service_account_id: { type: string, format: uuid, nullable: true } set_role: nullable: true allOf: [{ $ref: "#/components/schemas/SetRole" }] comment_required: { type: boolean, example: false } required: [id, created_at, updated_at, inspection_status_id, comment_required] StatusRead: type: object properties: id: { type: integer, example: 1 } created_at: { type: string, format: date-time } updated_at: { type: string, format: date-time } inspection_status_model_id: { type: integer, example: 1 } name: { type: string, example: "Название статуса" } color: { type: string, example: "#000000" } is_final: { type: boolean, example: false } allowed_to_set: nullable: true deprecated: true allOf: [{ $ref: "#/components/schemas/AllowedToSetRole" }] comment_required: { type: boolean, deprecated: true, example: false } set_status_ids: type: array items: { type: integer } example: [1, 2, 3] settings: type: array items: { $ref: "#/components/schemas/StatusSettingRead" } required: [id, created_at, updated_at, inspection_status_model_id, name, color, is_final, comment_required] StatusWithCountRead: allOf: - $ref: "#/components/schemas/StatusRead" - type: object properties: count: { type: integer, example: 1 } required: [count] StatusModelRead: type: object properties: id: { type: integer, example: 1 } created_at: { type: string, format: date-time } updated_at: { type: string, format: date-time } inspection_type_id: { type: integer, example: 1 } resource_id: { type: string, format: uuid, nullable: true } statuses: type: array items: { $ref: "#/components/schemas/StatusRead" } required: [id, created_at, updated_at, inspection_type_id] InspectionTypePermissionsRead: type: object properties: id: { type: integer, example: 1 } created_at: { type: string, format: date-time } updated_at: { type: string, format: date-time } inspection_type_id: { type: integer, example: 1 } service_account_id: { type: string, format: uuid } permissions: type: array items: { $ref: "#/components/schemas/InspectionPermission" } required: [id, created_at, updated_at, inspection_type_id, service_account_id] InspectionPermission: type: string enum: - core.can_create_inspection - core.can_view_inspections - core.can_edit_inspection - core.can_delete_inspection - core.can_view_all_inspections InspectionTypeLightRead: type: object properties: id: { type: integer, example: 1 } issue_types: type: array items: { type: integer } example: [1, 2] required: [id] InspectionTypeRead: type: object properties: id: { type: integer, example: 1 } created_at: { type: string, format: date-time } updated_at: { type: string, format: date-time } company_id: { type: integer, example: 1 } name: { type: string, example: "Название типа события" } event_duration: type: integer description: Длительность события в минутах example: 30 columns_order: type: array items: { type: string } example: [name, description, "attribute[1]"] issue_types: type: array items: { type: integer } example: [1, 2] required: [id, created_at, updated_at, company_id, name, event_duration] InspectionTypeFullRead: allOf: - $ref: "#/components/schemas/InspectionTypeRead" - type: object properties: permissions: type: array items: { $ref: "#/components/schemas/InspectionTypePermissionsRead" } status_models: type: array items: { $ref: "#/components/schemas/StatusModelRead" } attributes: type: array items: { $ref: "#/components/schemas/AttributeRead" } inspection_dt_overlap_allowed: { type: boolean, example: false } inspection_dt_current_day_allowed: { type: boolean, example: false } required: [inspection_dt_overlap_allowed, inspection_dt_current_day_allowed] InspectionCreate: type: object properties: company_id: { type: integer, minimum: 1, example: 1 } resource_id: { type: string, format: uuid } name: { type: string, minLength: 1, maxLength: 255, example: "Название события" } inspection_dt: type: string format: date-time description: Дата/время проведения (обнуляются секунды; не в прошлом) inspection_dt_end: { type: string, format: date-time, nullable: true } responsible_users: type: array minItems: 1 items: { type: integer, minimum: 1 } example: [1, 2] location: { type: string, nullable: true } description: { type: string, nullable: true } type_id: { type: integer, minimum: 1, example: 1 } status_id: { type: integer, nullable: true, example: 1 } attributes: type: object additionalProperties: $ref: "#/components/schemas/AttributeMultivalueType" example: { "1": [null], "2": [true, false], "3": [1, 2] } asset_attributes: type: array items: { $ref: "#/components/schemas/AssetAttributeCreate" } premise_id: { type: string, format: uuid, nullable: true } required: [company_id, resource_id, name, inspection_dt, responsible_users, type_id] InspectionPartialUpdate: type: object description: Все поля опциональны properties: name: { type: string, minLength: 1, maxLength: 255, nullable: true } inspection_dt: { type: string, format: date-time, nullable: true } inspection_dt_end: { type: string, format: date-time, nullable: true } responsible_users: type: array minItems: 1 nullable: true items: { type: integer, minimum: 1 } location: { type: string, nullable: true } description: { type: string, nullable: true } type_id: { type: integer, nullable: true } status_id: { type: integer, nullable: true } attributes: type: object nullable: true additionalProperties: $ref: "#/components/schemas/AttributeMultivalueType" asset_attributes: type: array nullable: true items: { $ref: "#/components/schemas/AssetAttributeCreate" } status_comment: { type: string, nullable: true } attachments: nullable: true allOf: [{ $ref: "#/components/schemas/AttachmentsChange" }] premise_id: { type: string, format: uuid, nullable: true } InspectionLightRead: type: object properties: public_id: { type: string, format: uuid } name: { type: string, example: "Название события" } type: $ref: "#/components/schemas/InspectionTypeLightRead" required: [public_id, name, type] InspectionRead: type: object properties: id: { type: integer, example: 1 } created_at: { type: string, format: date-time } updated_at: { type: string, format: date-time } public_id: { type: string, format: uuid } company_id: { type: integer, example: 1 } resource_id: { type: string, format: uuid } author_id: { type: integer, example: 1 } name: { type: string, example: "Название события" } inspection_dt: { type: string, format: date-time } inspection_dt_end: { type: string, format: date-time } responsible_users: type: array items: { type: integer } example: [1, 2] location: { type: string, nullable: true } description: { type: string, nullable: true } type: $ref: "#/components/schemas/InspectionTypeRead" status: $ref: "#/components/schemas/StatusRead" attributes: type: object additionalProperties: $ref: "#/components/schemas/AttributeMultivalueType" asset_attributes: type: array items: { $ref: "#/components/schemas/AssetAttributeRead" } premise_id: { type: string, format: uuid, nullable: true } required: - id - created_at - updated_at - public_id - company_id - resource_id - author_id - name - inspection_dt - inspection_dt_end - responsible_users - type - status - attributes - premise_id InspectionStatusCountRead: type: object properties: resource_id: { type: string, format: uuid } statuses: type: array items: { $ref: "#/components/schemas/StatusWithCountRead" } required: [resource_id, statuses] InspectionUnavailableDatesRequest: type: object properties: company_id: { type: integer, minimum: 1, nullable: true, example: 1 } responsible_users: type: array minItems: 1 items: { type: integer, minimum: 1 } example: [1, 2] excluded_inspection_ids: type: array items: { type: integer } example: [1, 2] required: [responsible_users] InspectionUnavailableDatesRead: type: object properties: unavailable_from: { type: string, format: date-time } unavailable_to: { type: string, format: date-time } required: [unavailable_from, unavailable_to] InspectionUnavailableUsersRequest: type: object properties: company_id: { type: integer, minimum: 1, nullable: true, example: 1 } inspection_dt: { type: string, format: date-time } inspection_dt_end: { type: string, format: date-time, nullable: true } users: type: array minItems: 1 items: { type: integer, minimum: 1 } example: [1, 2] required: [inspection_dt, users] InspectionUnavailableUsersRead: type: object properties: unavailable_users: type: array items: { type: integer } example: [1, 2] required: [unavailable_users] InspectionChangeRecordRead: type: object properties: id: { type: integer, example: 1 } created_at: { type: string, format: date-time } inspection_id: { type: integer, example: 1 } created_by: { type: integer, example: 1023 } field_name: { type: string, example: "name" } attribute_name: { type: string, nullable: true, example: "Локация" } was: oneOf: - $ref: "#/components/schemas/AttributeValueType" - $ref: "#/components/schemas/AttributeMultivalueType" became: oneOf: - $ref: "#/components/schemas/AttributeValueType" - $ref: "#/components/schemas/AttributeMultivalueType" was_text: { type: string, nullable: true } became_text: { type: string, nullable: true } required: [id, created_at, inspection_id, created_by, field_name, attribute_name, was, became, was_text, became_text] PageInspectionRead: type: object properties: count: { type: integer, example: 1 } result: type: array items: { $ref: "#/components/schemas/InspectionRead" } required: [count, result] PageInspectionLightRead: type: object properties: count: { type: integer, example: 1 } result: type: array items: { $ref: "#/components/schemas/InspectionLightRead" } required: [count, result] PageInspectionChangeRecordRead: type: object properties: count: { type: integer, example: 1 } result: type: array items: { $ref: "#/components/schemas/InspectionChangeRecordRead" } required: [count, result]