openspec: архив nats-files-subjects (#28)

Change слит PR #29; спеки обновлены (subject'ы files.tabular_uploaded,
files.img_uploaded, files.tabular_parsed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
This commit is contained in:
Andrey Epifancev 2026-10-08 23:50:24 +04:00
parent 46ef814b10
commit fc9d6d4902
6 changed files with 5 additions and 5 deletions

View File

@ -17,15 +17,15 @@ Stateless-сервис разбора табличных файлов (XLS/XLSX/
- **THEN** `GET /healthcheck` отвечает 200 с полями `uptime`, `version`, `nats` - **THEN** `GET /healthcheck` отвечает 200 с полями `uptime`, `version`, `nats`
### Requirement: Подтверждение запроса до обработки ### Requirement: Подтверждение запроса до обработки
Сервис SHALL быть подписан на `recognition.tabular.request` в queue group `tabular-parser`. Получив запрос, проходящий Сервис SHALL быть подписан на `files.tabular_uploaded` в queue group `tabular-parser`. Получив запрос, проходящий
`recognition-request.schema.json`, сервис SHALL до чтения файла из S3 опубликовать в `recognition.result` конверт `recognition-request.schema.json`, сервис SHALL до чтения файла из S3 опубликовать в `files.tabular_parsed` конверт
`status = processing` с `job_id`, `file_id`, `service {name: "tabular-parser", version}` и заголовком `status = processing` с `job_id`, `file_id`, `service {name: "tabular-parser", version}` и заголовком
`Nats-Msg-Id = ack:<job_id>:<attempt>`. Повторный запрос с `job_id`, который уже обрабатывается или обработан этим `Nats-Msg-Id = ack:<job_id>:<attempt>`. Повторный запрос с `job_id`, который уже обрабатывается или обработан этим
процессом, SHALL получить повторный ack и MUST NOT обрабатываться второй раз. процессом, SHALL получить повторный ack и MUST NOT обрабатываться второй раз.
#### Scenario: Ack раньше результата #### Scenario: Ack раньше результата
- **WHEN** опубликован запрос из `docs/contracts/examples/request-tabular.json` - **WHEN** опубликован запрос из `docs/contracts/examples/request-tabular.json`
- **THEN** первым сообщением сервиса в `recognition.result` является конверт `processing`, и только затем — результат - **THEN** первым сообщением сервиса в `files.tabular_parsed` является конверт `processing`, и только затем — результат
#### Scenario: Повторный запрос во время обработки #### Scenario: Повторный запрос во время обработки
- **WHEN** тот же запрос доставлен второй раз, пока первый обрабатывается - **WHEN** тот же запрос доставлен второй раз, пока первый обрабатывается
@ -40,12 +40,12 @@ Stateless-сервис разбора табличных файлов (XLS/XLSX/
#### Scenario: Запрос с заглушкой парсера (Срез 0) #### Scenario: Запрос с заглушкой парсера (Срез 0)
- **WHEN** воркеру явно передана заглушка `NullParser` (только тесты воркера; реализация по умолчанию — реальный парсер), - **WHEN** воркеру явно передана заглушка `NullParser` (только тесты воркера; реализация по умолчанию — реальный парсер),
запрос подтверждён и объект существует в `uploads/` запрос подтверждён и объект существует в `uploads/`
- **THEN** в `recognition.result` появляется конверт `status = error`, `error.code = NOT_IMPLEMENTED`, `job_id`/`file_id` - **THEN** в `files.tabular_parsed` появляется конверт `status = error`, `error.code = NOT_IMPLEMENTED`, `job_id`/`file_id`
из запроса, `metrics.duration_ms ≥ 0`; файл результата может отсутствовать из запроса, `metrics.duration_ms ≥ 0`; файл результата может отсутствовать
#### Scenario: Запрос с реальным парсером #### Scenario: Запрос с реальным парсером
- **WHEN** запрос подтверждён и объект в `uploads/` существует, но не является книгой Excel (сигнатура не XLS/XLSX/XLSB) - **WHEN** запрос подтверждён и объект в `uploads/` существует, но не является книгой Excel (сигнатура не XLS/XLSX/XLSB)
- **THEN** в `recognition.result` появляется конверт `status = error`, `error.code = UNSUPPORTED_FORMAT` (повреждённая - **THEN** в `files.tabular_parsed` появляется конверт `status = error`, `error.code = UNSUPPORTED_FORMAT` (повреждённая
книга — `UNREADABLE`), `job_id`/`file_id` из запроса, `metrics.duration_ms ≥ 0`; файл результата может отсутствовать; книга — `UNREADABLE`), `job_id`/`file_id` из запроса, `metrics.duration_ms ≥ 0`; файл результата может отсутствовать;
корректная ОСВ в том же потоке даёт `done` (см. «Парсер — заменяемый интерфейс») корректная ОСВ в том же потоке даёт `done` (см. «Парсер — заменяемый интерфейс»)