# documents-api Specification ## Purpose Чтение файлов, документов и строк ОСВ для панели «Первичные документы» (подсрез 2d) и подтверждение документа. ## Requirements ### Requirement: Файлы организации и карточка файла `GET /api/v1/legal-entities/{id}/files` (`DOCUMENT_VIEW`, policy; `include_superseded=false` по умолчанию) SHALL возвращать `Page` файлов ЮЛ по убыванию `uploaded_at`: поля `stored_file`, текущее задание (`status`, `error_code`, `error_message`, `mapping_error` (`metrics.mapping_error`: причина `ERROR` файла после неудачного маппинга, когда у задания `error_code` пуст), `metrics.warnings`, `metrics.mapping_warnings`, `finished_at`), документы файла (`id`, `document_type`, `osv_account_code`, `period_year`, `period_quarter`, `is_cumulative`, `status`, `period_check`, `counterparty_check`). `GET /api/v1/files/{file_id}` SHALL отдавать ту же карточку; чужой или несуществующий файл — 404. #### Scenario: Список после обработки - **WHEN** у ЮЛ два файла: `PROCESSED` с документом и `ERROR` - **THEN** оба в списке; у первого `documents` непустой, у второго `job.error_code` заполнен ### Requirement: Документ и строки `GET /api/v1/documents/{document_id}` (`DOCUMENT_VIEW`, policy по ЮЛ владельца) SHALL отдавать документ, статус, проверки, `locator`, схему группировок листа из `recognition_job.group_schema` и `file_id`. `GET /api/v1/documents/{document_id}/entries` SHALL отдавать `Page` строк по возрастанию `row_number` (`limit` ≤ 2000, по умолчанию 500) с полями `osv_entry`, включая `parent_entry_id`, `account_id`, `counterparty_id`. #### Scenario: Строки деревом - **WHEN** запрошены строки документа ОСВ 66 - **THEN** первая строка — счёт `66` уровня 0 без родителя, у строк уровня 2 `parent_entry_id` указывает на субсчёт ### Requirement: Подтверждение документа `POST /api/v1/documents/{document_id}/confirm` (`DOCUMENT_EDIT`, policy) SHALL переводить документ из `RECOGNIZED` или `NEEDS_CHECK` в `CONFIRMED` (`confirmed_by`, `confirmed_at`) с `audit_event(DOCUMENT_CONFIRM, PRIMARY_DOCUMENTS)`; из `CONFIRMED` повторно — 409 `ALREADY_CONFIRMED`; документ файла `SUPERSEDED` — 409 `FILE_SUPERSEDED`; документ в любом другом статусе (например, `ERROR`) — 409 `DOCUMENT_NOT_CONFIRMABLE`. Если совпали несколько условий, приоритет у `FILE_SUPERSEDED`. Подтверждение берёт блокировки в порядке «файл → документ» и перечитывает оба под `FOR UPDATE`; документ или файл, исчезнувшие за время ожидания блокировки, — 404 `NOT_FOUND`. #### Scenario: Причина ошибки маппинга в карточке файла - **WHEN** файл в `ERROR` после неудачного маппинга (задание `done`, `error_code` пуст) - **THEN** `job.mapping_error` содержит причину, `job.error_code` пуст #### Scenario: Документ не подтверждается - **WHEN** подтверждается документ в статусе `ERROR` - **THEN** 409 `DOCUMENT_NOT_CONFIRMABLE`, статус не изменился #### Scenario: Подтверждение - **WHEN** `ka_rf` подтверждает документ `NEEDS_CHECK` своего филиала - **THEN** `status = CONFIRMED`, `confirmed_by` = пользователь, `audit_event(DOCUMENT_CONFIRM)` с `before_value.status = NEEDS_CHECK`