Срез 0 (issue #1): раздел «Соглашения шаблона» (что оставлено от шаблона команды, что вырезается, что добавляется); change openspec/changes/slice-0-skeleton — proposal, design с таблицей «Decisions made without discussion», спеки и tasks; в openspec/config.yaml строки с двоеточием взяты в кавычки (YAML разбирал их как словари). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
7.9 KiB
7.9 KiB
Proposal: Срез 0 — скелет ядра arm-core
Срез: 0 «Скелет» (../docs/context/09-delivery-plan.md). Репозиторий: arm-core. Issue: RSHB/arm-core#1.
Родительский change: ../docs/openspec/changes/slice-0-skeleton (контракт v1.0, compose, CI-шаблон).
Соседние: ../tabular-parser/openspec/changes/slice-0-skeleton, ../scan-gateway/openspec/changes/slice-0-skeleton.
Why
Ядро — единственный писатель в PostgreSQL и единственная точка обмена с сервисами распознавания. Пока нет схемы БД по DBML v5.13, прав как данных и работающего outbox/inbox, ни один следующий срез (справочники, загрузка файлов, парсер) не может начаться: каждому нужны таблицы, пользователь с правами и канал в NATS. Срез 0 делает всё это один раз, без бизнес-логики, и доказывает end-to-end тестом на пустых обработчиках.
What Changes
- Инструменты шаблона:
api/pyproject.toml(ruff — формат, совместимый с black, и lint; mypy),requirements-dev.txtпереписан как-r requirements.txt+ dev-инструменты (пины шаблона были рассинхронизированы),Dockerfileв корне (строкаDockerfileубрана из.gitignore),Makefileс целямиup / migrate / test / lint / seed,.env.example,.env.test;Settingsчитает путь к env-файлу изENV_FILE(шаблонныйpytest.iniуже задаёт его, ноconfig.pyигнорировал). - Модель данных: ORM 1:1 с
../docs/model/data-model-v5.13.dbml— 43 таблицы, 27 enum'ов, все FK, уникальные и частичные индексы (related_group_memberWHERE is_current,consolidation_lockWHERE released_at IS NULL,documentNULLS NOT DISTINCT), схемаdkb. Миграция0001_dbml_v5_13создаёт всё с нуля и полностью откатывается.api/scripts/check_dbml_vs_orm.pyсравнивает DBML и ORM-метаданные; расхождение — ошибка CI. - Seed (
api/seed/, идемпотентныйpython -m scripts.seed):regional_office(ГО),role(7 ролей ТЗ 8.1),permission(16 сочетаний объект × действие из §10),role_permissionпо §10 (ASSUMPTION(OQ-16)),chart_of_account(План счетов 94н + субсчета типовой 1С, упомянутые в §4/§6),elimination_rulev1 для ББ (§4, 8 правил) сelimination_rule_account,required_document_ruleдля BASIC и EXTENDED (ASSUMPTION(OQ-46));--dev: примеры РФ и по одномуapp_userна роль. - Аутентификация и права:
core/auth.py— проверка JWT (TokenVerifier: dev HS256-эмитент за флагомAUTH_DEV_ISSUER; каркасRaisaVerifierпод JWKS/публичный ключ, параметры — вопрос к человеку), поискapp_userпо email, зависимостиcurrent_userиrequire(permission_code),GET /api/v1/me,POST /api/v1/dev/token(только при включённом флаге). Policy-слой (филиал/ЗО/статус) — не здесь (Срез 1+). - Обмен через
recognition_job(DECISION-4): вендоренные схемы контрактаapi/contracts/+ pydantic-моделиsrc/contract/; outbox-паблишер (queued→ NATS →published,Nats-Msg-Id = <job_id>:<attempt>), durable consumerrecognition.result(дедуп поresult_msg_id, обновление статуса/метрик, регистрация файла результата вs3_object,dlqпослеmax_deliver), вахтёрreply_deadline→timeout. Маппинг документов — точка расширения, реализуется в Срезе 2. - Аудит:
services/audit.py— единственный способ записатьaudit_event(append-only,before/afterjsonb). - CI:
.gitea/workflows/ci.ymlиз шаблона docs: ruff, mypy, pytest на PostgreSQL/NATS/MinIO, миграции upgrade → downgrade → upgrade,check_dbml_vs_orm, сборка образа; jobweb: biome, tsc, rsbuild build. - Документация репозитория:
README.mdзаменяется описанием сервиса (команды, env, как поднять),CLAUDE.md— раздел «Соглашения шаблона» (уже в ветке).
Capabilities
New Capabilities
data-model: схема БД = DBML v5.13; миграции применяются с нуля и откатываются; сверка ORM ↔ DBML.reference-data-seed: идемпотентная загрузка справочников продукта (роли, права, матрица, план счетов, правила элиминации, чек-лист) и dev-данных.authn-authz: вход по JWT, пользователь по email, эффективные права, зависимостьrequire(permission),/api/v1/me.recognition-job-exchange: outbox/inbox черезrecognition_job, идемпотентность, таймауты, DLQ, регистрация результата вs3_object.audit-trail: append-only запись событийaudit_eventчерез единый сервис.
Modified Capabilities
Impact
- Таблицы DBML v5.13: все 43 (ORM и миграция); данными заполняются
regional_office,role,permission,role_permission,chart_of_account,elimination_rule,elimination_rule_account,required_document_rule,app_user(dev),user_role(dev); в рантайме Среза 0 изменяютсяrecognition_job,s3_object,audit_event. Новых полей и таблиц нет. - Параграфы правил: §4 (seed правил элиминации), §9.4 (жизненный цикл
recognition_status), §10 (матрица прав). - Зависимости (новые):
PyJWT[crypto],pydbml(dev, сверка DBML),ruff,mypy,pytest-cov,types-*;nats-pyуже есть (JetStream API),miniopy-asyncуже есть. - Внешние системы: NATS JetStream (stream
RECOGNITION), MinIO/S3 (бакетarm-ka), PostgreSQL 15 (CREATE SCHEMA dkb,CREATE TYPE). - Фронт: без изменений кода; добавляется только CI-job.
Non-goals
- Загрузка файлов,
stored_file/documentжизненный цикл и маппинг результата вosv_entry/financial_statement_*(Срез 2). - CRUD справочников и экраны администратора (Срез 1); policy-слой по филиалу/ЗО/статусу (Срез 1+).
- Реальная проверка JWT РАИСА (нужны параметры — Open Questions родительского change'а); в Срезе 0 — только dev-эмитент и конфигурируемый каркас.
- Авто-элиминация ОФР (OQ-09) — правила ОФР в seed не входят.
- Полный план счетов конкретного клиента — только стандартный 94н + типовые субсчета 1С; остальное добавляет администратор (ARCH-004).
- Любые экраны фронта.