From 050f59a384615098207871d68cad656916f90748 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 4 Oct 2026 07:17:21 +0400 Subject: [PATCH] =?UTF-8?q?docs:=20=D1=81=D1=86=D0=B5=D0=BD=D0=B0=D1=80?= =?UTF-8?q?=D0=B8=D0=B9=20venv=20=D0=BF=D1=80=D0=BE=D1=82=D0=B8=D0=B2=20co?= =?UTF-8?q?mpose=20=D0=BD=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=20=E2=80=94=20design=20#43/#44,=20OQ-84,=20README?= =?UTF-8?q?=20=D0=B8=20.env.example=20=D0=B1=D0=B5=D0=B7=20=D1=83=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D0=B5=D0=B2=D1=88=D0=B5=D0=B9=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8=20SMB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5.5 --- context/07-open-questions.md | 1 + dev/.env.example | 3 ++- dev/README.md | 16 +++++++++------- openspec/changes/slice-0-skeleton/design.md | 4 +++- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/context/07-open-questions.md b/context/07-open-questions.md index b7140fa..526c9a4 100644 --- a/context/07-open-questions.md +++ b/context/07-open-questions.md @@ -89,6 +89,7 @@ | OQ-81 | Переменные `ARM_KA_DOCS` / `ARM_KA_FIXTURES` поддержаны неравномерно: `arm-core` — обе; `tabular-parser` — только `ARM_KA_DOCS`; `scan-gateway` — ни одной (жёстко `../docs`, `../../fixtures/ocr`). Текст причины skip («fixtures недоступен: положите репозиторий…») не содержит строки «ARM_KA_FIXTURES недоступен» из сценария «Нет фикстур» spec `quality-checks`; для docs-теста текст тоже без `ARM_KA_DOCS`. Нарушение spec — править сервисы? | scan-gateway и tabular-parser (тесты, Makefile); docs: O-3 (задача 1 фазы 2), `dev/checks.md`; spec `quality-checks` | срез 0 (процесс), все сервисы | допущение принято: расхождение описано в `dev/checks.md`; правка тестов и Makefile в scan-gateway и tabular-parser — follow-up человеку (сервисы не правились) | | OQ-82 | `.dockerignore` в `arm-core` не исключает `api/.env.test`: файл попадает в образ (у `tabular-parser` и `scan-gateway` исключён). Исправлять? | arm-core `.dockerignore`; docs: T3.2 (задача 3 фазы 2) | срез 0 (образы), прод-сборка | допущение принято: безвредно (в файле стандартные dev-учётные данные compose, не секреты), в Срезе 0 не правилось; добавить исключение в arm-core — follow-up | | OQ-83 | Контейнеры профиля `services` подписаны на те же subject и queue group общего NATS, что и экземпляры в интеграционных тестах сервисов (`recognition.result` / `arm-core`, `*.request`): NATS может отдать сообщение теста контейнеру и наоборот; интеграционные тесты `scan-gateway` и `arm-core` одновременно тоже делят NATS. Сделать queue group и subject-префикс настраиваемыми для тестов (например `NATS_TEST_PREFIX`) или поднимать отдельный NATS на тесты? | scan-gateway: п. 11 таблицы предложений (T14.1, T11.8); docs: O-11 (задача 3 фазы 2; подтверждено ревью для tabular-parser и scan-gateway), `dev/README.md` | срез 0 (процесс), интеграционные тесты | допущение принято: в `dev/README.md` предупреждение и команда `stop` для контейнеров профиля; не гонять `make test-integration` двух сервисов одновременно | +| OQ-84 | Запуск сервисов из venv без Nexus (`make venv` + `python run_server.py` из `api/` с `.env` из `docs/dev/.env.example`, healthcheck по `localhost`) в Срезе 0 не проверялся ни в одном из трёх сервисов. Известно по чтению конфигов (design #44): `.env.example` в нынешнем виде отвергнет `tabular-parser` (`OPENBAO__DATABASE__*`, `OPENBAO__SMB__*` — `extra_forbidden`), в нём нет `OPENBAO__MINIO__MINIO_SECURE=false` (по умолчанию `true` — https к http-MinIO). Прогнать сценарий, зафиксировать набор переменных и портов (`SERVER__PORT`, `SCAN_HOTFOLDER_PATH` для `scan-gateway`), решить, нужен ли отдельный `.env.example` на сервис, и снять пометку «черновик» с раздела `dev/README.md`? | spec `dev-environment`, сценарий «Запуск из venv против compose без Nexus»; docs: design #43, `dev/README.md` («Запуск сервисов из venv без Nexus»); финальное ревью фазы 2: I-1 | срез 0 (процесс, окружение разработки); кандидат в follow-up issue | вопрос: допущение Среза 0 — раздел README остаётся черновиком, сценарий не подтверждён (проверка требовала `.venv` внутри сервисных репозиториев, в фазе 2 доступных только для чтения) | Служебные идентификаторы в DBML/аналитике: `ANL-nnn` — замечания аналитика к макету; `ARCH-nnn` — архитектурные решения; `DECISION-n` — решения по модели; `FIX-nn` — исправления дефектов v4. diff --git a/dev/.env.example b/dev/.env.example index 271708d..79a296c 100644 --- a/dev/.env.example +++ b/dev/.env.example @@ -48,7 +48,8 @@ OPENBAO__NATS__NATS_URL=nats://localhost:4222 OPENBAO__NATS__NATS_SEED= OPENBAO__NATS__NATS_JWT= -# SMB — заглушки (в Срезе 0 не используется); блок обязателен для Settings arm-core +# SMB — заглушки (в Срезе 0 не используется); блок необязателен для arm-core и scan-gateway (режим local). +# tabular-parser неизвестные ключи OPENBAO__* отвергает: для него удалите блоки DATABASE и SMB (см. dev/README.md) OPENBAO__SMB__SMB_HOST=localhost OPENBAO__SMB__SMB_PATH=share OPENBAO__SMB__SMB_LOGIN=user diff --git a/dev/README.md b/dev/README.md index ca8b601..630f05a 100644 --- a/dev/README.md +++ b/dev/README.md @@ -293,7 +293,7 @@ docker compose --profile services up -d --wait tabular-parser # вернут | `OPENBAO__NATS__NATS_URL` | `nats://localhost:4222` | адрес NATS | | `OPENBAO__NATS__NATS_SEED` | пусто | nkey seed; пусто — подключение без nkeys | | `OPENBAO__NATS__NATS_JWT` | пусто | JWT NATS; пусто — подключение без nkeys | -| `OPENBAO__SMB__SMB_HOST` | `localhost` | заглушка SMB (в Срезе 0 не используется); блок обязателен для `Settings` arm-core | +| `OPENBAO__SMB__SMB_HOST` | `localhost` | заглушка SMB (в Срезе 0 не используется); блок необязателен для `arm-core` и для `scan-gateway` в режиме `SCAN_HOTFOLDER_MODE=local` (по умолчанию); `tabular-parser` его не знает и отвергнет (см. ниже) | | `OPENBAO__SMB__SMB_PATH` | `share` | заглушка SMB | | `OPENBAO__SMB__SMB_LOGIN` | `user` | заглушка SMB | | `OPENBAO__SMB__SMB_PASSWORD` | `password` | заглушка SMB | @@ -318,9 +318,10 @@ docker compose --profile services down -v # полный сброс: тома ## Запуск сервисов из venv без Nexus (черновик) -> Черновик: запуск сервисов из venv в Срезе 0 не проверялся (сквозная проверка задачи 5.4 шла на профиле `services`); -> шаги ниже не прогонялись целиком. Проверка из venv вынесена за пределы Среза 0 (фаза 2), отдельного вопроса в -> `07-open-questions.md` нет. `make venv` и `make test-integration` есть во всех трёх сервисах. +> Черновик: запуск сервисов из venv в Срезе 0 не проверялся (сквозная проверка шла на профиле `services`); шаги ниже +> не прогонялись целиком. Сценарий spec `dev-environment` остаётся неподтверждённым — вопрос +> [OQ-84](../context/07-open-questions.md), решение design #43. `make venv` и `make test-integration` есть во всех трёх +> сервисах. Пакеты `raisa_*` из Nexus банка вне банка недоступны (D-10). Поэтому `make venv` ставит `requirements.txt` без строк `raisa_*` (фильтр `grep -v '^raisa_'`), код импортирует `raisa_*` условно (при `DEBUG=true`), а npm-пакеты `raisa-*` @@ -343,11 +344,12 @@ curl -s localhost:<порт сервиса>/healthcheck одновременно или сервис из venv рядом с профилем `services` требуют разных `SERVER__PORT`. Для `arm-core` в ответе `/healthcheck` ожидаются `version` и `nats = ok` — при `NATS_ENABLED=true` (задан в `.env.example`; без него `nats = off`). Поля `/healthcheck` в контейнерах: `tabular-parser` — `uptime`, `version`, `nats`; `scan-gateway` — ещё -`hotfolder` (шлюзу нужен `SCAN_HOTFOLDER_PATH`). Набор переменных сервисов для запуска из venv не проверялся (см. черновик выше). +`hotfolder` (шлюзу нужен `SCAN_HOTFOLDER_PATH`). Набор переменных сервисов для запуска из venv не проверялся (см. черновик выше и OQ-84). По чтению конфигов: `tabular-parser` отвергает неизвестные ключи `OPENBAO__*`, поэтому в его `.env` нужно удалить строки `OPENBAO__DATABASE__*` и `OPENBAO__SMB__*`; для MinIO по `http` нужен `OPENBAO__MINIO__MINIO_SECURE=false` (в `.env.example` его нет, по умолчанию `true`). ## Интеграционные тесты сервисов против compose (черновик) -> Черновик: уточняется после задач 3.x и 5.x. +> Черновик: состав целей и порядок проверок описаны в [`checks.md`](checks.md); открытые вопросы — OQ-83 (общий NATS +> у контейнеров и тестов) и OQ-84. Общий набор целей (`up`, `test`, `test-integration`, `lint`, `check`, `check-full`) есть во всех сервисных репозиториях (`arm-core`, `tabular-parser`, `scan-gateway`); семантика, состав `check-full`, порядок перед PR и пропуск тестов без @@ -386,7 +388,7 @@ postgres nats minio`, затем `make test-integration` (или `make check-ful - **Образы MinIO неофициальные.** Официальные `minio/minio` и `minio/mc` недоступны (Docker Hub — denied, на quay.io нет нужных тегов), поэтому в compose стоят `alpine/minio:RELEASE.2025-10-15T17-29-55Z` и `bitnamilegacy/minio-client:2025.7.21`, а сервис `minio` запущен с `user: "0:0"` (иначе образ не пишет в свежий том) — - только для dev. Решения R-5/R-6: [`design.md`](../openspec/changes/slice-0-skeleton/design.md), раздел + только для dev. Решения: [`design.md`](../openspec/changes/slice-0-skeleton/design.md), раздел «Decisions made without discussion», решения №16–17. Замена на официальные образы — две строки `image:` в `docker-compose.yml` (и удаление `user: "0:0"`). - **Безопасность.** По умолчанию порты публикуются только на `127.0.0.1` (`BIND_ADDR`), снаружи машины они недоступны. diff --git a/openspec/changes/slice-0-skeleton/design.md b/openspec/changes/slice-0-skeleton/design.md index 75d5aea..9b3cdc9 100644 --- a/openspec/changes/slice-0-skeleton/design.md +++ b/openspec/changes/slice-0-skeleton/design.md @@ -149,7 +149,7 @@ PostgreSQL 16, схемы создавать можно. Остаются (не | 15 | 2026-10-03 | Чекбоксы плана и `tasks.md` отмечает контроллер SDD отдельным коммитом после чистого ревью задачи | исполнитель не должен отмечать выполненным то, что ещё не прошло ревью | отметки правятся вручную | | 16 | 2026-10-03 | Compose: MinIO берётся из неофициальных образов `alpine/minio:RELEASE.2025-10-15T17-29-55Z` и `bitnamilegacy/minio-client:2025.7.21` | `minio/minio` и `minio/mc` недоступны на Docker Hub (denied), на quay.io нужных тегов нет; для dev достаточно любого S3-совместимого MinIO нужной версии API | образы сторонние: при появлении доступа к банковскому реестру/официальным образам — заменить две строки `image:` в `dev/docker-compose.yml`; в прод эти образы не попадают | | 17 | 2026-10-03 | Compose: сервис `minio` запускается от `user: "0:0"` | образ `alpine/minio` по умолчанию работает от пользователя `minio` и падает на свежем именованном томе | только dev; удалить строку, когда образ/том позволят писать без root | -| 18 | 2026-10-03 | `dev/.env.example` дополнен заглушками `OPENBAO__SMB__*` и `NATS_ENABLED=true` | `Settings` шаблона (arm-core) требует блок `OPENBAO.SMB`, без него сервис из venv не стартует; `NATS_ENABLED` по умолчанию `false`, и `/healthcheck` показывает `nats = off`; spec велит копировать именно `docs/dev/.env.example` | убрать две группы строк; сервисы с другим набором обязательных настроек получат лишние (игнорируемые) переменные | +| 18 | 2026-10-03 | `dev/.env.example` дополнен заглушками `OPENBAO__SMB__*` и `NATS_ENABLED=true` | `Settings` шаблона (arm-core) требует блок `OPENBAO.SMB`, без него сервис из venv не стартует; `NATS_ENABLED` по умолчанию `false`, и `/healthcheck` показывает `nats = off`; spec велит копировать именно `docs/dev/.env.example` | убрать две группы строк; сервисы с другим набором обязательных настроек получат лишние (игнорируемые) переменные Примечание: часть про обязательность SMB устарела, см. №44. | | 19 | 2026-10-03 | `schema_version` во всех трёх схемах: `const "1.0"` заменён на `type: string, pattern: ^1\.\d+$` (производитель v1.0 пишет `"1.0"`); в `$comment` и в 03-architecture.md добавлено правило «новый MINOR раскатывается сначала на потребителей» | spec «Версионирование контракта»: потребитель принимает тот же MAJOR и любой MINOR, сервис «поддерживающий 1.x» принимает 1.1 и отвергает только 2.0; с `const` это неисполнимо, а копии схем уйдут в сервисы побайтно (финальное ревью I-1) | вернуть `const "1.0"` и пересобрать копии схем в сервисах; побочный риск — копии в `arm-core`/`tabular-parser`/`scan-gateway` нужно обновить (тест идентичности контракта упадёт, пока копии не обновлены) | | 20 | 2026-10-03 | Compose: порты хоста публикуются на `${BIND_ADDR:-127.0.0.1}`, а не на 0.0.0.0 | пароли по умолчанию (`armka`, `minioadmin`); все сценарии идут через localhost; spec bind-адрес не оговаривает (финальное ревью M-6) | если нужен доступ с другой машины — `BIND_ADDR=0.0.0.0` в `.env`; для запуска профиля `services` порты хоста не нужны | | 21 | 2026-10-04 | В корне репозитория `docs` добавлен `Makefile` с целями `venv`, `validate-contracts`, `validate-openspec`, `check` (сервисных целей нет); `jsonschema` ставится в `.venv` (в `.gitignore`) | дополнение контроллера к задаче 4.1: проверки контракта и спеки должны запускаться одной командой, как в сервисах; `check` = `scripts/validate_contracts.py` + `openspec validate slice-0-skeleton --strict` | удалить `Makefile` и строку `.venv/` в `.gitignore`; команды из `dev/checks.md` останутся запускаемыми вручную | @@ -174,3 +174,5 @@ PostgreSQL 16, схемы создавать можно. Остаются (не | 40 | 2026-10-04 | Статусы OQ-45/46/47 обновлены в существующих строках, не продублированы: все три — «допущение принято и применено в Срезе 0» с фактами (NU: контракт оставляет, ORM `OsvDataType` 1:1 с DBML v5.13, `NoopMapper`; OQ-46: 27 строк EXTENDED + 10 BASIC в seed, `is_mandatory = true`; OQ-47: 122 строки плана счетов, названия нестандартных субсчетов выведены по роли в §4). Кандидаты DBML v5.14 (`NU`, `NULLS NOT DISTINCT`, note `article_2_line`, действие `audit_action`, счётчик republish, `lower(email)`) внесены только строками реестра, файл `data-model-v5.13.dbml` не менялся | факты проверены чтением `arm-core/api/seed/core/`, `api/src/models/enums.py` и `contract/common.py`; создание DBML-версии — отдельное решение человека (CLAUDE.md: версия не меняется задним числом) | если человек решит иначе (например, хранить НУ), статус строки меняется правкой реестра, код Среза 0 не затронут | | 41 | 2026-10-04 | В реестр **не** внесены, а оставлены в отчёте задачи 6 (кандидаты в follow-up issue при закрытии): scan-gateway п. 7 (рестарт NATS не автоматизирован), п. 8 (`stop()` не публикует конверты принятым заданиям), п. 9 (`/healthcheck` всегда 200), п. 13 (`DEBUG` не используется), п. 14 (`ResourceWarning` aiohttp), п. 15 (SMB без `connection_timeout`); tabular P-4, scan-gateway п. 10 и 16 (порты, `SCAN_GATEWAY_PORT`, устаревший README) — закрыты задачами 3–5 и `dev/README.md`; O-22 и T3.7/O-20 — процессные пункты задачи 7 | это инженерные доработки или уже исправленные расхождения документов, вопроса к человеку/аналитикам в них нет; реестр остаётся списком решений, которые принимает человек | пункты могут потеряться, если follow-up issue не будет заведена (чеклист закрытия, п. 6): они перечислены в отчёте с маркерами | | 42 | 2026-10-04 | Формулировка статусов в новых строках: «допущение принято: …» — в коде/спеке Среза 0 действует рабочее допущение, вопрос открыт для подтверждения; «вопрос: …» — человек должен принять решение, допущение Среза 0 указано после двоеточия (аудит на уровне БД, `attempt + 1`, образцы ответов ИС, формат `data_ocr`, имя файла ответа, `.part` в `Input`) | правило файла: агент вопросы не закрывает, а помечает допущение; слово «закрыт» нигде не использовано | различение статусов — рекомендация, не контракт; при несогласии префикс правится в реестре | +| 43 | 2026-10-04 | Сценарий spec `dev-environment` «Запуск из venv против compose без Nexus» (`make venv` + `python run_server.py` + healthcheck) в Срезе 0 **не прогонялся**; раздел «Запуск сервисов из venv без Nexus» в `dev/README.md` остаётся черновиком, вопрос вынесен в OQ-84 (кандидат в follow-up issue) | проверка требует создать `.venv` внутри сервисных репозиториев (`make venv` пишет в `api/.venv`), а в фазе 2 они были доступны только для чтения (их worktree с открытыми PR не правятся); сквозная проверка шла на профиле `services` (контейнеры из тех же исходников) | сценарий spec может оказаться неработоспособным (набор переменных, `requirements.txt` без `raisa_*`, порты) — разработчик без Docker для сервисов узнает об этом при первом запуске; правится README или `.env.example` | +| 44 | 2026-10-04 | Уточнение к №18: блок `OPENBAO__SMB__*` **не обязателен**. В `arm-core` `OpenBAOSettings.SMB = SMBSettings()` с пустыми значениями по умолчанию (`api/src/core/config.py`), в `scan-gateway` блок необязателен в режиме `SCAN_HOTFOLDER_MODE=local` (по умолчанию) и обязателен целиком при `smb`, в `tabular-parser` блока нет, и `OpenBAOSettings` отвергает неизвестные ключи (`extra_forbidden`; проверено на копии его `config.py` с `.env` из `dev/.env.example`: падает на `OPENBAO.smb`, так же упадёт на `OPENBAO__DATABASE__*`) — `extra="ignore"` относится только к верхнему уровню `Settings`. Заглушки в `dev/.env.example` оставлены; комментарий и README исправлены и говорят, что `.env.example` годится для `arm-core` и `scan-gateway`, а для `tabular-parser` из него нужно убрать блоки `DATABASE` и `SMB` | в момент решения №18 `Settings` arm-core требовал блок; затем в arm-core блок сделан необязательным (в Срезе 0 SMB ядру не нужен), а формулировка осталась в `.env.example` и README | ложное утверждение «обязателен» заставляло бы переносить заглушки в окружение, где они не нужны; цена низкая — у `arm-core` и `scan-gateway` заглушки безвредны, а `tabular-parser` с неотредактированным `.env.example` не стартует (описано в README, часть OQ-84) |