Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
34 lines
3.8 KiB
Markdown
34 lines
3.8 KiB
Markdown
# Tasks: Срез 3a — горячие папки и нормализатор OCR
|
||
|
||
Репозиторий — scan-gateway; команды `make` — из корня, `pytest` — из `api/`. Нумерация и состав задач — как в плане
|
||
`docs/superpowers/plans/2026-10-06-slice-3a-ocr-normalizer.md` (Task 0–17); пошаговый код и проверки — там. Исполнение —
|
||
subagent-driven-development: один коммит на задачу плюс правки ревью. CI нет — проверки локальные (`make check`,
|
||
`make test-integration`, `make check-full`).
|
||
|
||
- [x] 0 Контракт v1.2 в ветке и окружение: `origin/main` влит, схемы байт-в-байт равны `../docs/contracts`, `make venv`,
|
||
`make check` зелёный; `CONTRACT_VERSION` остаётся `1.0` (решение №14)
|
||
- [x] 1 Настройки и справочники: `SCAN_CLEANUP`, `SCAN_RULES_DIR`; `api/rules/` (`statement_lines.yaml` с редакциями `66n`
|
||
и пустой `fsbu4`, `ocr_lookalikes.yaml`, `statement_labels.yaml`); `src/normalizer/rules.py` (`load_rules`, `OcrRules`)
|
||
- [x] 2 Очистка текста (`src/normalizer/ocr/text.py`): двойники вплотную к цифре, `|` как разделитель клеток, `clean_value`
|
||
- [x] 3 Разбор дат (`ocr/dates.py`): `parse_date`, дословный перенос `date_utils` старого ядра
|
||
- [x] 4 Суммы (`ocr/amounts.py`): `parse_amount`, `is_blank` (решения №12, №13)
|
||
- [x] 5 Раскладка колонок (`ocr/layout.py`): `build_layout` по шапке «Код», `infer_layout` по данным
|
||
- [x] 6 Строки таблицы (`ocr/rows.py`): шапка настоящая или синтетическая, классы строк, тип по кодам
|
||
- [x] 7 Шапка файла (`ocr/header.py`): организация, ИНН, единицы, дата отчёта
|
||
- [x] 8 Сборка документа (`ocr/document.py`): тип, колонки, строки, значения с `is_recognized`, редакции
|
||
(решения №15, №16, №19, №21–25)
|
||
- [x] 9 `OcrNormalizer`: статусы `done` / `needs_check` / `error RECOGNITION_FAILED`, предупреждения, `metrics.rows`,
|
||
подключение в `create_app`
|
||
- [x] 10 Golden на реальных ответах `../fixtures/ocr/*.json` (эталоны `expected_normalize/` — в fixtures), `make golden-update`
|
||
- [x] 11 Горячая папка `local`: имя `<job_id>.<ext>`, `.part` в `Tmp`, запись без замены (`os.link`), `cleanup` под
|
||
`SCAN_CLEANUP` (решения №17, №26, №27)
|
||
- [x] 12 Горячая папка `smb`: `smbclient.rename` без замены, `cleanup` под флагом
|
||
- [x] 13 Воркер и приложение: очистка после сохранения `raw/` (под флагом), `RECOGNITION_FAILED` без расширения,
|
||
`OcrNormalizer` в lifespan
|
||
- [x] 14 Эмулятор: пара по sha256 содержимого, `SCAN_EMULATOR_DEFAULT`, входящий `<uuid>.<ext>`, игнор `.part`/`.tmp`/`.done`
|
||
- [x] 15 Сквозной сценарий, README и CLAUDE.md сервиса: `test_roundtrip.py` (документы, `ok_doc`, неизвестное содержимое,
|
||
`SCAN_CLEANUP=true`, файл результата по схеме), README, CLAUDE.md, этот файл
|
||
- [ ] 16 Документы workspace (репозиторий docs, bounded-PR): `03-architecture.md`, `05-domain-rules.md` §11.1, OQ,
|
||
`09-delivery-plan.md`, dev-compose и `qa-guide.md`
|
||
- [ ] 17 Завершение: синхронизация с `main`, `make check-full`, `openspec validate --strict`, PR fixtures с эталонами, PR scan-gateway
|