Andrey Epifancev 0c04127aec docs: OpenSpec change slice-0-skeleton — сквозной скелет Среза 0
openspec init (config с контекстом docs-репозитория) и change slice-0-skeleton: proposal, design
(11 решений без обсуждения, открытые вопросы к человеку), спеки recognition-contract,
dev-environment, ci-template, tasks в порядке зависимостей между репозиториями. 06-test-data.md §6:
справочники продукта — seed arm-core, не фикстуры. 09-delivery-plan.md: Срез 0 по факту (change'и,
compose в docs/dev, контракт копией без общего пакета, seed).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 02:44:14 +04:00

59 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Spec Delta: dev-environment
## Purpose
Локальное окружение разработки всего workspace одной командой: инфраструктура (PostgreSQL, NATS JetStream, MinIO),
эмулятор внешней ИС Сканирование и три сервиса системы, собранные из соседних каталогов workspace.
## ADDED Requirements
### Requirement: Инфраструктура поднимается одной командой
`docker compose -f docs/dev/docker-compose.yml up -d` без профилей SHALL поднять PostgreSQL 15 (БД `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`, `nats stream ls`
отвечает (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/S3; stream
`RECOGNITION` существует
#### Scenario: Запуск из venv против compose
- **WHEN** разработчик поднял только инфраструктуру и запускает `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` за одну сессию