docs: контракт для агентов, архитектура и план фаз
AGENTS.md — индекс, команды и обязательные ограничения (Decimal для денег, не конвертировать валюту на записи, SDK T-Invest ровно в одном модуле, аналитика читает только confirmed). docs/ai/ — архитектура, соглашения, эксплуатация и полный план на шесть фаз с проверками для каждой.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# AGENTS.md
|
||||
|
||||
Контракт для AI-агентов в этом репозитории. Подробности — в [`docs/ai/`](docs/ai/README.md);
|
||||
этот файл — индекс, команды и ограничения, не описание архитектуры.
|
||||
|
||||
## Проект одной фразой
|
||||
|
||||
Личная аналитика финансов и инвестиций: ZenMoney (повседневные деньги) + брокеры
|
||||
(T-Invest API, отчёты Сбера и ВТБ) → PostgreSQL → FastAPI → Flutter-клиент. Заменяет
|
||||
Snowball Income. Один пользователь, свой VPS.
|
||||
|
||||
## Команды
|
||||
|
||||
```bash
|
||||
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](docs/ai/README.md), затем нужный раздел [architecture.md](docs/ai/architecture.md) |
|
||||
| Новый источник данных (`backend/src/fintracker/sources/`) | architecture.md §Источники, `sources/base.py`, `worker/runner.py` |
|
||||
| Модель данных / миграции (`models/`, `alembic/`) | architecture.md §Домен, [conventions.md](docs/ai/conventions.md) |
|
||||
| Аналитика / метрики | architecture.md §Аналитика, [conventions.md](docs/ai/conventions.md) §Деньги |
|
||||
| API / Flutter-клиент | architecture.md §API, `openapi/openapi.json` |
|
||||
| Деплой | `docker-compose.yml`, `deploy/Caddyfile`, [ops.md](docs/ai/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`.
|
||||
Reference in New Issue
Block a user