DFiP_Budget_planing/ARCHITECTURE.md
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

5.4 KiB
Raw Blame History

Архитектура

Монорепозиторий: api/ (FastAPI) отдаёт REST, WebSocket и собранный фронт; web/ — SPA на React. Основная бизнес-логика — PL/pgSQL-функции схемы v3 в Postgres. Python-слой проверяет роли, валидирует запрос, вызывает функцию и маппит её ошибки.

Поток редактирования ячейки: RealtimeTable → WebSocket /api/v1/ws/form/{id}/sheet/{sheet} (cell_edit_start — блокировка, cell_updated) → SheetService → v3.upd_form_cell(s). Функция проверяет роль и окно этапа и пишет аудит v3.log_event, после чего изменение рассылается остальным подключённым.

Модули

Модуль Ответственность Зависит от
api/src/api/v1/ Роутеры: auth, users, admin, audit, forms, projects, form_phases (/stages), phase_template, export, websocket, org_unit, vsp (/dict/info), expense_item, summary (/svod) services, deps
api/src/api/v1/deps.py Текущий пользователь из JWT, гарды ролей repository.user_repository, core.security
api/src/api/v1/websocket.py ConnectionManager, блокировки ячеек в памяти, события форм и FORM_4/проектов, синхронизация сателлитов AHR services
api/src/services/ Сервисы по сущностям, контроль доступа (access_control_service.py) repository
api/src/services/export_service/ Фоновые выгрузки в Excel: ProcessPool, таблица export_job, файлы в tmp/exports, маппинг колонок export_mappings.py repository, openpyxl/XlsxWriter
api/src/repository/ SQLAlchemy-запросы и вызовы SQL-функций v3.*, SET LOCAL app.user_id db
api/src/db/ engine, Base, сессия, ORM-модели (36) core.config
api/src/domain/ pydantic-схемы API, enums —
api/src/core/ Настройки, JWT/argon2, исключения и маппинг ошибок Postgres в HTTP —
api/alembic/ Миграции (около 49 ревизий); versions/sql/*.sql — DDL, функции, сиды, около 43 тыс. строк Postgres
web/src/app/ Роуты, AuthProvider (токены в localStorage) pages
web/src/pages/ Задачи (формы), карточка формы или проекта, проекты и их своды, свод 1 и 2, админка, справочники components, api
web/src/components/RealtimeTable/ Редактируемая таблица листа: WebSocket, блокировки, конфиги колонок constants/FORM_* api
web/src/api/ axios-клиент /api/v1, модули по сущностям, WebSocket выгрузок —

Границы

  • Роутеры не ходят в БД напрямую, только через сервисы и репозитории. Сейчас нарушают admin.py, main.py (engine) и websocket.py (бизнес-логика в слое API).
  • Проверка прав на ячейки и окна этапов — в SQL. Python её не дублирует, только маппит ошибки.
  • Изменения схемы и функций — только новой миграцией alembic; старые миграции не правятся.
  • Фронт обращается только к /api/v1 через web/src/api/.

Открытые вопросы

  • Prod-авторизация через Keycloak (raisa_fastapi_protected_api) закомментирована в main.py, deps.py, auth.py; сейчас всегда работает локальный JWT. Как будет устроен prod?
  • websocket.py:333, :357: условие form_key != form_key всегда ложно, поэтому блокировки сравниваются по line_id между всеми формами; release_locks_for_row ничего не возвращает.
  • Раскладка колонок дублируется: web/.../constants/FORM_1|2|4/*.js (около 4 тыс. строк каждый) и api/.../export_mappings.py. Источник правды не определён.
  • Названия форм в БД и UI расходятся (FORM_2, FORM_4).
  • Мёртвый код фронта: pages/TablePage.jsx, FormsPage.jsx, TablesTest.jsx, TableTempPage/, api/tables.js, api/client_form.js, api/ws.js, constants/FORM_1/*_NO_LOCAL.js.
  • В package.json не объявлены @mui/x-date-pickers, @mui/icons-material; tailwind/daisyui не используются.
  • Settings.CORS_ORIGINS не применяется (в main.py allow_origins=["*"]), APP_ENV не читается, JWT_SECRET по умолчанию небезопасный.
  • / монтируется дважды в api/src/main.py:289 и :291.
  • Интеграционные тесты зависят от данных в общей БД и не изолированы; downgrade() в миграциях пустые.
  • Python-линтеров и проверок CI в репозитории нет.