Срез 0 реализован и влит (PR #3), change перенесён в openspec/changes/archive, спеки — в openspec/specs. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
58 lines
4.9 KiB
Markdown
58 lines
4.9 KiB
Markdown
# dev-environment Specification
|
||
|
||
## Purpose
|
||
Локальное окружение разработки всего workspace одной командой: инфраструктура (PostgreSQL 16, NATS без JetStream, MinIO),
|
||
эмулятор внешней ИС Сканирование и три сервиса системы, собранные из соседних каталогов workspace.
|
||
|
||
## Requirements
|
||
|
||
### Requirement: Инфраструктура поднимается одной командой
|
||
`docker compose -f docs/dev/docker-compose.yml up -d` без профилей SHALL поднять PostgreSQL 16 (БД `armka`,
|
||
пользователь `armka`, порт 5432), NATS 2.10 **без JetStream** (как на платформе; порты 4222, мониторинг 8222) и MinIO
|
||
(API 9000, консоль 9001) с уже созданным бакетом `arm-ka`. Все учётные данные — в `docs/dev/.env.example`, копируемом
|
||
в `docs/dev/.env`.
|
||
|
||
#### Scenario: Чистый старт
|
||
- **WHEN** разработчик выполняет `cp .env.example .env && docker compose up -d` в `docs/dev/` на машине без томов
|
||
- **THEN** в течение 60 с все три контейнера проходят healthcheck, `psql` подключается к `armka`, `curl :8222/varz`
|
||
отвечает и `jetstream` в нём отсутствует/выключен, `mc ls local/arm-ka` возвращает пустой бакет
|
||
|
||
### Requirement: Профиль сервисов собирает приложения из workspace
|
||
Профиль `services` SHALL добавить контейнеры `arm-core`, `tabular-parser`, `scan-gateway` и `scan-emulator`, собранные
|
||
из `../../arm-core`, `../../tabular-parser`, `../../scan-gateway` относительно `docs/dev/` (работает и из зеркального
|
||
workspace `.wt/<срез>/`). Сервисы читают настройки через переменные `OPENBAO__*` шаблона, `DEBUG=true`, и получают
|
||
`fixtures/ocr` смонтированным только для чтения в эмулятор.
|
||
|
||
#### Scenario: Сервисы стартуют против инфраструктуры compose
|
||
- **WHEN** выполняется `docker compose --profile services up -d --build`
|
||
- **THEN** `GET http://localhost:8000/healthcheck` (arm-core), `:8001/healthcheck` (tabular-parser),
|
||
`:8002/healthcheck` (scan-gateway) отвечают 200 с `version` и `nats = ok`; в логах нет ошибок подключения к NATS/S3
|
||
|
||
#### Scenario: Запуск из venv против compose без Nexus
|
||
- **WHEN** разработчик поднял только инфраструктуру, создал venv командой `make venv` (ставит `requirements.txt` без
|
||
строк `raisa_*`) и запускает `python run_server.py` из `api/` любого сервиса с `.env`, скопированным из
|
||
`docs/dev/.env.example`
|
||
- **THEN** сервис подключается к тем же PostgreSQL/NATS/MinIO по `localhost` и проходит healthcheck
|
||
|
||
### Requirement: Эмулятор ИС Сканирование воспроизводит горячие папки
|
||
Контейнер `scan-emulator` SHALL следить за каталогом `Input/` общего тома `hotfolder`; для файла `UUID_имя.ext` он
|
||
SHALL через настраиваемую задержку (по умолчанию 2 с) создать `Output/UUID/UUID.json` с содержимым
|
||
`fixtures/ocr/<имя без расширения>.json`, если такая пара есть; иначе — JSON ошибки в формате Content AI
|
||
(`error.code = INVALID_DOCUMENT`).
|
||
|
||
#### Scenario: Известная пара
|
||
- **WHEN** в `Input/` появляется `3f1c…_aep_5.pdf`
|
||
- **THEN** через ≤ 5 с в `Output/3f1c…/3f1c….json` лежит содержимое `fixtures/ocr/aep_5.json`
|
||
|
||
#### Scenario: Неизвестное имя
|
||
- **WHEN** в `Input/` появляется `…_unknown.pdf`
|
||
- **THEN** в `Output/…/….json` лежит ответ с `error.code = INVALID_DOCUMENT` и пустым `data_ocr`
|
||
|
||
### Requirement: Окружение документировано
|
||
`docs/dev/README.md` SHALL описывать: предварительные требования, команды запуска инфраструктуры и профиля сервисов,
|
||
переменные `.env`, как запустить интеграционные тесты каждого сервиса против compose, как сбросить тома.
|
||
|
||
#### Scenario: Новый разработчик
|
||
- **WHEN** разработчик следует README без помощи
|
||
- **THEN** он получает работающее окружение и зелёные интеграционные тесты `arm-core` за одну сессию
|