ff3b76871dde097bbc0ca4dcc54c3da71a5b3ecf
Поток: upload -> raw_report_file (sha256 UNIQUE) -> parse -> raw_report_line,
событий в леджере ещё нет -> preview -> POST /imports/{id}/commit ->
ledger/ingest.py резолвит инструмент, считает dedupe_key, пишет event
confirmed | shadow (plan §1.6 B) — сравнивая account.primary_event_source
с источником отчёта, а не гадая. Нерезолвленный инструмент ждёт в
pending_instrument, никогда не угадывается; POST /instruments/pending/{id}/resolve
привязывает и пересобирает лоты.
ledger/dedupe.py — shadow-матчинг случая B двумя проходами (точная дата, затем
±1 рабочий день, жадно 1:1, |price| ±0,5 %). Шаги shadow_dedupe и
report_reconcile зарегистрированы перед quality: оба говорят через FINDINGS.
/instruments/pending регистрируется в app.py ДО routers/instruments.py:
FastAPI сопоставляет маршруты по порядку, и /instruments/{id} с типом int
отвечает 422 на нечисловой сегмент, а не проваливается дальше.
Контракт — docs/ai/import-contract.md, общий для бэкенда и Flutter.
fin-tracker
Личная аналитика финансов и инвестиций: ZenMoney (повседневные деньги) + брокеры (T-Invest API, отчёты Сбера и ВТБ) в одной базе, с XIRR/TWR, календарём дивидендов и купонов, аллокацией и net worth. Замена Snowball Income.
backend/— Python 3.12, FastAPI, PostgreSQL, worker с расписанием синков.app/— Flutter-клиент (web, Linux, Windows, Android) поверх REST/OpenAPI.deploy/— Caddy и сертификаты;docker-compose.yml— прод на VPS.
Для агентов: AGENTS.md. Команды: just --list.
Languages
Python
46.4%
Dart
40.9%
JavaScript
11%
C++
0.7%
CMake
0.6%
Other
0.2%