Files
fin-tracker/AGENTS.md
T
Dmitry 220f027652 docs: контракт для агентов, архитектура и план фаз
AGENTS.md — индекс, команды и обязательные ограничения (Decimal для денег, не
конвертировать валюту на записи, SDK T-Invest ровно в одном модуле, аналитика
читает только confirmed). docs/ai/ — архитектура, соглашения, эксплуатация и
полный план на шесть фаз с проверками для каждой.
2026-09-18 13:43:31 +03:00

6.5 KiB
Raw Blame History

AGENTS.md

Контракт для AI-агентов в этом репозитории. Подробности — в docs/ai/; этот файл — индекс, команды и ограничения, не описание архитектуры.

Проект одной фразой

Личная аналитика финансов и инвестиций: ZenMoney (повседневные деньги) + брокеры (T-Invest API, отчёты Сбера и ВТБ) → PostgreSQL → FastAPI → Flutter-клиент. Заменяет Snowball Income. Один пользователь, свой VPS.

Команды

nix develop                 # backend toolchain (uv, python 3.12, postgres 17, just, openapi-generator)
nix develop .#app           # + Flutter
just db-start               # локальный Postgres в ./.pgdata на порту 54329
just migrate                # alembic upgrade head
just api                    # FastAPI с reload, http://127.0.0.1:8000/api/v1/docs
just web                    # то же + Flutter web-сборка с того же origin (WEB_DIR=app/build/web)
just worker                 # планировщик синков
just check                  # ruff + pyright + pytest + проверка дрейфа OpenAPI
just openapi                # экспорт openapi/openapi.json (коммитится)
just gen-client             # Dart-клиент в app/packages/api_client (коммитится)
just revision "msg"         # новая alembic-миграция из изменений моделей

Тесты поднимают собственный Postgres через pg_ctl (pytest-postgresql) — Docker не нужен.

Карта задача → контекст

Задача Что читать
Любое изменение docs/ai/README.md, затем нужный раздел architecture.md
Новый источник данных (backend/src/fintracker/sources/) architecture.md §Источники, sources/base.py, worker/runner.py
Модель данных / миграции (models/, alembic/) architecture.md §Домен, conventions.md
Аналитика / метрики architecture.md §Аналитика, conventions.md §Деньги
API / Flutter-клиент architecture.md §API, openapi/openapi.json
Деплой docker-compose.yml, deploy/Caddyfile, ops.md

Обязательные ограничения

  • Деньги — Decimal, в БД NUMERIC(24,10) + колонка валюты рядом. Никаких float в хранении и в API (в JSON — строки). Float допустим только внутри расчёта коэффициентов.
  • Не конвертировать валюту на записи. Конвертация — по курсу на дату операции, в аналитике. Нет курса → NULL и запись в data quality, не подмена.
  • SDK T-Invest (t_tech.invest) импортируется только в sources/tinvest/client.py. Ставится с индекса T-Bank ([tool.uv.index] в backend/pyproject.toml) — не менять на PyPI.
  • Аналитика читает только event.status = confirmed. Snapshot-таблицы — для сверки.
  • Сырые данные (raw_*) append-only и идемпотентны по стабильному id источника.
  • openapi/openapi.json и app/packages/api_client — генерируются, но коммитятся; после изменения роутов запускай just gen-client.
  • Секреты только в .env.gitignore). Реальные отчёты брокеров — в backend/tests/fixtures/reports/raw/.gitignore); в git только обезличенные фикстуры.
  • Коммиты — Conventional Commits на русском (feat(ledger): …), автор — только пользователь.

Состояние

Фазы 0 и 1 завершены и проверены на живых данных (31 счёт, 5575 транзакций ZenMoney, курсы ЦБ, все экраны работают). Правил классификации пока ноль — переводы и сбережения попадают в расходы.

Фаза 2 в работе. Готово и прогнано на живых данных:

  • sources/tinvest — 7 счетов, 2756 операций → event, маппер на все 67 OperationType;
  • ledger/lots.py + rebuild.py — FIFO, 804 лота, 672 закрытия, реализовано +1892 ₽; короткие позиции поддержаны, qty_remaining хранится со знаком;
  • sources/moex — 77 инструментов, 31 154 дневные цены, price_daily / price_last;
  • analytics/valuation — дневная серия стоимости и холдинги по scope (all, account:<id>, portfolio:<id>), сверка со снапшотами брокера; analytics/returns — XIRR и TWR по периодам (1m 3m 6m ytd 1y 3y all) плюс XIRR на инструмент; pricing/prices.py — цена на дату с протяжкой вперёд и порогом устаревания 10 дн.

Осталось: analytics/allocation, корпоративные действия, API и экраны позиций.

Известные расхождения derived vs брокерский снапшот по позициям (5 шт, не ошибки разбора): редомициляция FIVE→X5, MGNT, HEAD, внебиржевая SIBN6P4. Без цен два инструмента — SIBN6P4 и NDM_TBNK-PP-FIXPRCNT-08.25, им нужен price_manual. По кэшу derived выше снапшота на счетах 46, 48 и 52 (+6313, +56447, +146 ₽) — это неполнота леджера T-Invest, а не оценки: счёт 51 сходится точно. История цен тонкая (большинство облигаций — только с апреля 2026, TBRU@ — с 14.09.2026), поэтому TWR пропускает 32 дня и сообщает об этом в metric_data_quality. План фаз — в docs/ai/plan.md.