Andrey Epifancev 5190e5ef13 docs: описать проект в CLAUDE.md и ARCHITECTURE.md
Домен, стек, слои, команды, тесты, базовая ветка test.
.claude/code-paths: api/src/, api/alembic/, web/src/.

Refs #198

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 20:24:22 +04:00

8.6 KiB
Raw Permalink Blame History

DFiP_Budget_planing

Что это

Система бюджетного планирования ДФиП РСХБ (платформа raisa). Исполнители ССП и региональных филиалов (РФ) совместно, в реальном времени заполняют бюджетные формы (сметы) по листам, статьям расходов и кварталам. Что и когда может править каждая роль, задают этапы (окна редактирования колонок). ДФиП и ДУРРС корректируют (секвестр), администратор ведёт пользователей, оргструктуру, шаблоны этапов и журнал аудита. Поверх форм строятся своды 1 и 2, реестр проектов РФ (открытие, закрытие и переезд ВСП и т.п.) с отчётами по годам, справочник ВСП и фоновая выгрузка в Excel.

Формы (v3.form_type): FORM_1 «Смета ГО» (AHR/CAP/OPER/SMETA, AHR и CAP делятся по direction Support/Development), FORM_2 «ПД» (плюс сателлиты AHR_LIMIT/RENT/UTILITY/SECURITY, OTCH9F), FORM_3 «Отчёт РФ развитие» (хранится в project → rf_project_year → rf_project_report), FORM_4 «Смета РФ поддержка» (плюс STRUCTURE — программы и проекты). Названия на фронте (web/src/constants/constants.jsx) расходятся с БД, источник истины — БД.

Роли (api/src/db/models/role.py): 1 ADMIN; 2 EXECUTOR_DFIP (несколько ССП/РФ); 3 EXECUTOR_RF (одна оргединица); 4 EXECUTOR_DURRS.

Стек и ограничения

  • Backend api/: Python, FastAPI 0.111, SQLAlchemy 2 async + asyncpg, Alembic, pydantic-settings, JWT (python-jose, HS256) + argon2.
  • БД — только PostgreSQL, всё в схеме v3. Бизнес-логика в основном в PL/pgSQL-функциях v3.add_*/upd_*/del_*/v_*, их зовут через text("SELECT ... FROM v3.fn(...)") из api/src/repository/. Функции живут в api/alembic/versions/sql/*.sql и переопределяются CREATE OR REPLACE в последующих миграциях: актуальна последняя версия. SQLite в DATABASE_URL по умолчанию — ловушка, на нём приложение не работает.
  • Frontend web/: React 18 на Rsbuild, JavaScript (JSX), хотя есть tsconfig. UI — MUI и material-react-table. Основная таблица — собственный components/RealtimeTable/. Состояние в React Context, роутинг react-router-dom 6, axios. Biome для линта. Tailwind/daisyui остались от шаблона и не используются.
  • Платформа raisa: обязателен api/run_server.py; хост и порт из SERVER__HOST/SERVER__PORT. CI — внешний шаблон cicd/ci/fastapi-app.yml (.gitlab-ci.yml), ресурсы в raisa_config.yml. Собранный фронт отдаёт сам API из api/web (StaticFiles).
  • Зависимости ставятся из корпоративного Nexus (setup/pip.conf, setup/.npmrc). raisa-fastapi-protected-api есть только там.
  • cwd процессов API, тестов и alembic — api/: пути alembic.ini, .env, web, back_static, tmp/exports относительные.
  • Состояние WebSocket-блокировок ячеек и менеджер выгрузок живут в памяти процесса: один процесс, без нескольких воркеров.
  • Настройки (api/src/core/config.py): OPENBAO__SETTINGS__* или короткое имя (DATABASE_URL, DEBUG, DATABASE_SCHEMA). DEBUG по умолчанию true. При false на старте выполняются alembic upgrade head и цикл чистки аудита.

Архитектура

Подробная карта — в ARCHITECTURE.md.

  • api/src/api/v1/ — роутеры (/api/v1/...) и deps.py (текущий пользователь, гарды require_admin/require_executor*). websocket.py — realtime-редактирование и блокировки ячеек.
  • api/src/services/ — сервисы *Service(db); export_service/ — Excel-выгрузки в ProcessPool.
  • api/src/repository/ — *Repository(db): SQLAlchemy и вызовы SQL-функций. Текущий пользователь передаётся в SQL через SET LOCAL app.user_id (для аудита v3.log_event).
  • api/src/db/models/ — ORM (36 моделей), api/src/domain/schemas.py — pydantic-схемы, api/src/core/ — конфиг, безопасность, ошибки.
  • Права на ячейки проверяет SQL (role_not_allowed:, window_closed:). core/exception_handlers.py по тексту ошибки Postgres превращает их в 403/409/400/404/422.
  • web/src/app/Routes.jsx — страницы, web/src/api/*.js — клиент API, web/src/components/RealtimeTable/ — редактируемая таблица, конфиги колонок по формам в constants/FORM_*.

Команды

  • Установка: cd setup && ./setup.sh (venv в api/.venv, npm i в web/). Для тестов дополнительно pip install -r api/requirements-dev.txt.
  • API: cd api && python run_server.py (нужен Postgres в DATABASE_URL). Миграции: cd api && alembic upgrade head.
  • Web: cd web && npm run start (dev), npm run build (результат в web/dist). Линт: cd web && npx biome check src.
  • Тесты backend: cd api && pytest — весь набор. Зелёным считается только весь набор. pytest tests/unit — без БД. pytest tests/integration — нужен живой Postgres; --init_db накатывает миграции и сид tests/sqls/fixture.sql.
  • Тесты frontend: cd web && node --test src/components/RealtimeTable/utils/*.test.js.

Тесты

  • api/tests/unit/ — моки сессии и репозиториев (AsyncMock, monkeypatch), БД не нужна.
  • api/tests/integration/ — TestClient(app) с полным lifespan, сессия с rollback. Фикстуры admin_tokens/isp_tokens (api/tests/conftest.py, tests/integration/conftest.py). Тестовое окружение — Postgres из DATABASE_URL, пароли OPENBAO__TEST_ADMIN_PASSWORD/OPENBAO__TEST_EXECUTOR_PASSWORD. Часть тестов делает skip при отсутствии данных.
  • Новая логика в SQL-функциях покрывается интеграционными тестами через API. Логику без БД выносить в сервисы и покрывать unit-тестами.

Ветки и PR

  • Базовая ветка — test, не main: в неё идут все PR, main — устаревший шаблон. Везде, где процесс обвязки говорит «main» (база worktree, PR, openspec archive, git pull --ff-only в основном checkout), читать test.
  • Хук guard-main защищает только main/master, test он не охраняет. Прямые коммиты в test запрещены так же, как в main; исключение — только коммит openspec archive.
  • PR создаётся с --base test.

OpenSpec и superpowers

  • Вход в любую задачу — superpowers:brainstorming. Skills openspec-propose и openspec-explore сами по себе не запускать.
  • Когда brainstorming классифицировал задачу как architectural, структуру change создать через openspec new change <id> (или /opsx:propose <id>), а содержимое proposal.md, specs/ и design.md написать по итогам brainstorming. tasks.md из OpenSpec не заполнять — задачи живут в плане superpowers.
  • /opsx:apply не использовать: исполнение идёт через writing-plans и SDD/executing-plans.
  • openspec archive <id> — после merge PR, как часть чеклиста закрытия.
  • Хук require-plan защищает каталоги из .claude/code-paths: api/src/, api/alembic/ (SQL-логика), web/src/.