DRRK/ARCHITECTURE.md
Andrey Epifancev b4d49bdab8 docs: описать проект в CLAUDE.md и ARCHITECTURE.md
- CLAUDE.md: что это, стек и ограничения, архитектура, команды, тесты
- ARCHITECTURE.md: карта модулей, границы импортов, открытые вопросы
- .claude/code-paths: app/, alembic/, tests/ для хука require-plan
- .gitignore: .claude/worktrees/

Refs #1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 13:51:22 +04:00

4.7 KiB
Raw Blame History

Архитектура

Streamlit-приложение поверх async SQLAlchemy. Слои: UI/джоба → сервисы → репозитории → БД; сервисы ходят во внешние API через интеграции и в разбор файлов через imports. Потоки данных по шагам — README.md, раздел «Потоки»; решения D… и вопросы Q… — docs/project.md.

Модули

Модуль Ответственность Зависит от
main.py load_dotenv → set_page_config → AuthService().run() → st.navigation по страницам auth, core, ui
run_local.py локальный запуск: LOCATION=local, alembic upgrade head, streamlit run —
app/core Settings (pydantic-settings, префикс OPENBAO__SETTINGS__ приоритетнее .env), логирование —
app/auth Keycloak через raisa-streamlit-oauth, mock-форма при LOCATION=local —
app/db async engine (NullPool), SessionLocal, Base, run_db(); типы колонок (BigInteger PK, JSON/JSONB, Numeric, аудит); ORM-модели core
app/integrations gateway.py — requests-клиент к Gravitee (ключ, таймауты, повторы, классификация ошибок, RequestRecord); moex.py, cbr.py — клиенты и разбор ответов в dataclass'ы core
app/imports quik.py — разбор выгрузки сделок QUIK (.xlsx), ошибки «строка N, колонка» —
app/repositories async-доступ к таблицам, upsert ON CONFLICT (_upsert.py) db, integrations (только dataclass'ы результатов)
app/services сценарии: securities, market_data, fx_rates, quik_import, manual_operations, request_log, dates db, repositories, integrations, imports
app/ui страницы «Бумаги», «Рыночные данные», «Загрузка сделок», «Ручные операции»; common.py services, imports, db (run_db, перечисления моделей)
app/jobs update_market — котировки + курс CNY за дату от пользователя system; коды выхода 0/1/2 core, db, services
alembic/ async env.py со схемой DATABASE_SCHEMA, ревизии, сиды справочников db

Таблицы: currency, portfolio, operation_type (справочники с сидом), security, security_nominal_history, market_data, market_data_manual, exchange_rate, operation, import_batch, external_request_log. Уникальные ключи и смысл колонок — README.md, «БД и event loop».

Границы

  • core, auth, imports не импортируют другие пакеты app.
  • integrations и imports не знают о БД; integrations — единственное место, где есть HTTP.
  • repositories не вызывают внешние API: из integrations берут только dataclass'ы результатов разбора.
  • ui не импортирует repositories и integrations напрямую — только через services; в БД ходит только через run_db().
  • Внешние API вызываются только из сервисов по действию пользователя или из джобы, не при рендере страницы.
  • Каждый запрос к шлюзу пишется в external_request_log без тела ответа и заголовков (кроме X-Gravitee-Transaction-Id).
  • Загрузка сделок QUIK пишет import_batch и операции одной транзакцией; план перед записью пересобирается по БД.

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

  • Бизнес-вопросы Q2–Q28 — в docs/project.md; ключевые для следующей итерации — партии внутри выпуска (Q24), фондирование (Q8, Q19), хранение результатов расчёта (Q20), роль NOM и ADJ в результате (Q6, Q28).
  • Где будут жить расчёты финрезультата и фондирования (новый пакет app/calc/ с чистой логикой или сервисы) — решить на brainstorming первой расчётной итерации.
  • Как запускать джобу по расписанию в Раисе — не решено.