[2026-06-25] taiga-vault: family/how-to/htpc-emulators-setup.md family/how-to/htpc-gaming-plans.md family/how-to/kraken-access.md family/how-to/openmediavault-rpi5.md family/how-to/time-machine.md family/how-to/wireguard-vpn.md personal/documents/todo-list.md personal/plans/extract-stable-prompt-blocks.md personal/plans/hermes-whale-system-prompt.md personal/plans/thread-scoped-memory.md
This commit is contained in:
@@ -81,7 +81,7 @@
|
||||
- Категоризация — ручная.
|
||||
- Невозможно нормально работать с мобильного.
|
||||
- Анализ ограничен сводными в Excel: нет нормальных графиков по подкатегориям, кросс-фильтрации, прогнозов.
|
||||
- Нет ничего про FIRE: проекций пенсии, моделирования инвестиций, целевых процентов нормы сбережений.
|
||||
- Нет ничего про Freedom Gap / инвестиции: нет трекинга портфеля, нормы сбережений, проекции "когда аренда + проекты покроют расходы".
|
||||
- История курсов хранится в строках листа `курсы` — это не нормализованная таблица.
|
||||
- Нет API: нельзя интегрировать с банковскими экспортами, нельзя автоматически тянуть в дашборд.
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
2. Считает аналитику и сводки **на лету** через SQL, а не через `VLOOKUP`.
|
||||
3. Импортирует банковские выписки (Альфа, Сбер, Demir, …) автоматически + AI-резолвер для неоднозначных случаев.
|
||||
4. Даёт мобильный UI для быстрого ввода трат на ходу.
|
||||
5. Моделирует **FIRE-сценарии** (отдельная фаза после готового бюджетирования).
|
||||
5. **Freedom Gap** — разница между расходами и пассивным/полупассивным доходом (аренда, дивиденды, проекты). График прогресса к нулевому gap. What-if сценарии: "если проект даёт X, аренда Y — через N лет свобода".
|
||||
6. Прогнозирует траты на N месяцев вперёд по сезонной модели (категории `🧱 Стройка`, `🏖️ Отдых` цикличны).
|
||||
|
||||
### Доменная модель (первая итерация)
|
||||
@@ -144,13 +144,34 @@ Base currency не хардкодится — выбирается в `Settings`
|
||||
|
||||
1. **Phase 0 — Discovery & schema**. Полностью разобрать Excel, утвердить доменную модель. *(в процессе — этот док)*
|
||||
2. **Phase 1 — Skeleton + import**. Создать `~/Developer/budget-app/` (git init), FastAPI + Vue в Docker Compose в `~/docker/budget-app/` с подключением к существующему Postgres-кластеру на хосте (новая БД `budget_app`). Миграция xlsx → БД. Read-only viewer транзакций + остатков + годовые отчёты. Внешний доступ через `budget.qentra.top` с auth (FastAPI Users + JWT).
|
||||
3. **Phase 2 — Курсы и настройки**. Cron-джоб для НБ КР с back-fill. Базовая валюта в настройках. Все пересчёты привязаны к ней.
|
||||
4. **Phase 3 — Ручной ввод**. Форма добавления транзакции, CRUD категорий/счетов, ручная правка курсов.
|
||||
5. **Phase 4 — Импорт банков + AI-резолвер**. Автофетч/парсеры (Альфа, Сбер, Demir). LLM-резолвер. TG-бот для ручных подтверждений.
|
||||
6. **Phase 5 — Аналитика**. Дашборды: расход по категориям, динамика, бёрндаун по бюджету. Прогнозы.
|
||||
7. **Phase 6 — Mobile / PWA**. Быстрый ввод с телефона.
|
||||
8. **Phase 7 — MCP HTTP**. Экспонировать MCP-эндпоинт для Hermes.
|
||||
9. **Phase 8 — Инвестпортфели + FIRE**. Тикеры/цены/дивы. Калькулятор FIRE. *(отдельное планирование когда бюджетирование готово.)*
|
||||
3. **Phase 2 — Полноценный Viewer + CRUD**. Довести до уровня Excel по функциональности:
|
||||
- Валюта у счетов (символ)
|
||||
- Категории с иерархией (группа → подкатегория)
|
||||
- Свёртка по годам/месяцам (drill-down как в Excel)
|
||||
- Dynamic scrolling (infinite scroll вместо кнопок пагинации)
|
||||
- CRUD транзакций: добавление, редактирование, удаление
|
||||
- CRUD категорий
|
||||
- CRUD счетов
|
||||
- Ручная правка курсов
|
||||
- Дашборды: расход по категориям, динамика, бёрндаун по бюджету
|
||||
- Прогнозы (сезонная модель по категориям)
|
||||
- Multi-currency: отображение балансов в валюте счёта + в base currency
|
||||
- Сводная таблица по годам (как лист `сводная` в Excel)
|
||||
- Налоговый учёт (как лист `налоги 22-24` в Excel)
|
||||
4. **Phase 3 — Импорт банков + AI-резолвер**. Автофетч/парсеры (Альфа, Сбер, Demir). LLM-резолвер. TG-бот для ручных подтверждений.
|
||||
5. **Phase 4 — Mobile / PWA**. Быстрый ввод с телефона.
|
||||
6. **Phase 5 — MCP HTTP**. Экспонировать MCP-эндпоинт для Hermes.
|
||||
7. **Phase 6 — Freedom / Инвестиции**. Замена классического FIRE на Freedom Gap — разница между расходами и пассивным доходом.
|
||||
- P0: Savings Rate Dashboard (норма сбережений из транзакций)
|
||||
- P0: Multi-Currency Net Worth (общий капитал USD/KGS)
|
||||
- P1: Investment Snapshots (ручной ввод раз в месяц, таблица + график)
|
||||
- P1: Freedom Gap Dashboard (доход-расход-аренда-проект = gap)
|
||||
- P1: Passive Income Tracker (аренда + дивиденды + депозиты)
|
||||
- P2: Freedom Goal with Projection Engine (what-if сценарии)
|
||||
- P3: What-if Simulator (слайдеры: курс, аренда, проект, норма сбережений)
|
||||
- Новые таблицы: `investment_snapshot`, `freedom_goal`
|
||||
- Новые страницы: `/freedom`, `/finances`
|
||||
- *Не делать:* Monte Carlo, Withdrawal Strategy Planner, Roth Conversion Ladder — не применимы
|
||||
|
||||
### Multi-tenant readiness (для будущего public SaaS)
|
||||
|
||||
@@ -340,6 +361,12 @@ CLOUDFLARE_TUNNEL_TOKEN=...
|
||||
- `echarts` (скаффолд под Phase 5, не используем активно)
|
||||
- dev: `vite`, `typescript`, `eslint`, `prettier`
|
||||
|
||||
### Правила работы
|
||||
|
||||
1. **Тесты — обязательны** для каждого нового API-роута или изменения. Если код не покрыт тестом — он не готов.
|
||||
2. **Обновление доку** — после каждой завершённой задачи обновлять таблицу прогресса и Acceptance criteria в этом доке.
|
||||
3. **Комит** — после каждой логически завершённой задачи (не раз в 10 шагов).
|
||||
|
||||
### Acceptance criteria Phase 1
|
||||
|
||||
- [ ] `https://budget.qentra.top` открывается, login работает.
|
||||
@@ -364,4 +391,156 @@ CLOUDFLARE_TUNNEL_TOKEN=...
|
||||
---
|
||||
|
||||
**Создано:** 2026-06-21
|
||||
**Статус:** Phase 0 закрыт, Phase 1 спланирован
|
||||
**Статус:** Phase 1 — в работе
|
||||
|
||||
## Phase 1 progress
|
||||
|
||||
| Шаг | Статус | Кем |
|
||||
| -------------------------------------- | ------ | ---- |
|
||||
| Init репо | ✅ | Орёл |
|
||||
| Backend skeleton | ✅ | Орёл |
|
||||
| Postgres bootstrap — роль + БД | ✅ | Кит |
|
||||
| Alembic initial migration | ✅ | Кит |
|
||||
| FastAPI Users + auth routes | ✅ | Кит |
|
||||
| Bootstrap первого юзера | ✅ | Кит |
|
||||
| XLSX импортёр (6 045 транзакций) | ✅ | Кит |
|
||||
| Read-only API (12 тестов) | ✅ | Кит |
|
||||
| Frontend skeleton + read-only страницы | ✅ | Кит |
|
||||
| Docker Compose (2 сервиса, работает) | ✅ | Кит |
|
||||
| Cloudflare Tunnel budget.qentra.top | ✅ | Alex |
|
||||
| Сверка данных | ✅ | Кит |
|
||||
| | | |
|
||||
|
||||
## Disaster recovery: CASCADE data loss
|
||||
|
||||
**Сценарий:** Удалён пользователь (A-click → user delete). Из-за `ON DELETE CASCADE` на `transaction_user_id_fkey` все транзакции этого пользователя удалены мгновенно (6 045 строк). Балансы обнулены.
|
||||
|
||||
### Recovery шаги (на будущее)
|
||||
|
||||
```bash
|
||||
# 1. Пересоздать пользователя с тем же email (admin123)
|
||||
curl -XPOST .../api/auth/register -H... -d'{"email":"alex@qentra.top","password":"admin123"}'
|
||||
|
||||
# 2. Переимпортировать транзакции из xlsx
|
||||
cd ~/Developer/budget-app
|
||||
uv run python src/budget/importers/__init__.py
|
||||
|
||||
# 3. Проверить балансы — все 18 счетов должны совпасть с excel-balances.md
|
||||
# 4. Пересобрать и передеплоить backend (дата формат) + frontend (любые изменения)
|
||||
docker-compose build backend && docker-compose up -d backend
|
||||
cd frontend && npm run build && cd .. && docker-compose build --no-cache frontend && docker-compose up -d frontend
|
||||
```
|
||||
|
||||
### Формат даты на фронте (актуальный)
|
||||
|
||||
API возвращает `t.date.isoformat()` → `2026-05-29T17:00:00`.
|
||||
Фронт режет: `{{ t.date.slice(0, 10) }} {{ t.date.slice(11, 16) }}` → `2026-05-29 17:00`.
|
||||
|
||||
Если время = `00:00` — в Excel не было времени для этой транзакции. Это корректно.
|
||||
|
||||
### Символы валют вместо колонки
|
||||
|
||||
Колонка "Валюта" убрана из таблиц Transactions, Accounts, TaxRecords.
|
||||
Вместо неё символ валюты показывается непосредственно перед суммой (Transactions, TaxRecords) или в ячейке (Accounts).
|
||||
|
||||
Маппинг на фронте (постоянный, не из БД):
|
||||
|
||||
| Код | Символ | Валюта |
|
||||
|-----|--------|--------|
|
||||
| USD | $ | Доллар |
|
||||
| EUR | € | Евро |
|
||||
| RUB | ₽ | Рубль |
|
||||
| KGS | С̲ | Сом (с с нижней чертой) |
|
||||
| KZT | ₸ | Тенге (уже есть в Unicode) |
|
||||
|
||||
Файлы: `frontend/src/pages/Transactions.vue`, `Accounts.vue`, `TaxRecords.vue` — каждая содержит `CURRENCY_SYMBOLS` маппинг и функцию `getCurrencySymbol`/`currencySymbol`.
|
||||
|
||||
### Пароль
|
||||
|
||||
- `admin123` — совпадает с `ADMIN_PASSWORD` в `.env`
|
||||
|
||||
## Phase 2 progress
|
||||
|
||||
| Шаг | Статус | Кем |
|
||||
| ---------------------------------------------------------------------------- | ------ | -------- |
|
||||
| Валюта у счетов (символ) | ✅ | Кит |
|
||||
| Категории с иерархией (API + фронт) | ✅ | Кит |
|
||||
| Фронт: формы CRUD (транзакции, категории, счета) | ✅ | Кит |
|
||||
| Свёртка по годам/месяцам (drill-down) | ✅ | Кит |
|
||||
| Dynamic scrolling (infinite scroll) | ✅ | Кит |
|
||||
| CRUD транзакций (API + тесты) | ✅ | Кит |
|
||||
| CRUD категорий (API + тесты) | ✅ | Кит |
|
||||
| CRUD счетов (API + тесты) | ✅ | Кит |
|
||||
| Ручная правка курсов + API | ✅ | Кит |
|
||||
| Дашборды (расход по категориям, динамика, сводная) | ✅ | Кит |
|
||||
| Multi-currency отображение (баланс в валюте счёта + base currency) | ✅ | Кит |
|
||||
| Сводная по годам | ✅ | Кит |
|
||||
| Налоговый учёт | ✅ | Кит |
|
||||
| DateTime в транзакциях (date → DateTime, datetime-local на фронте, миграция) | ✅ | Кит |
|
||||
| Символ валюты вместо колонки (Transactions, Accounts, TaxRecords) | ✅ | Кит |
|
||||
|
||||
|
||||
### Phase 2 — что сделано (подробно)
|
||||
|
||||
**API (новые эндпоинты):**
|
||||
- `GET /api/reports/monthly?year=` — помесячная разбивка доходов/расходов
|
||||
- `GET /api/reports/summary` — сводная по годам
|
||||
- `GET /api/reports/category-breakdown?year=&month=` — расходы по группам категорий (данные для дашборда)
|
||||
- `GET/POST/PUT/DELETE /api/exchange-rates` — CRUD курсов валют
|
||||
- `GET /api/exchange-rates/summary` — группировка по типу налога
|
||||
- `GET/POST/PUT/DELETE /api/tax-records` — CRUD налоговых записей
|
||||
- Accounts API теперь возвращает `balance_in_base` и `base_currency` (мультивалютность)
|
||||
|
||||
**БД:**
|
||||
- Новая таблица `tax_record` (alembic migration)
|
||||
|
||||
**Фронтенд (новые страницы):**
|
||||
- `/dashboard` — дашборд с помесячной динамикой (CSS-chart), расходами по категориям, сводной по годам
|
||||
- `/exchange-rates` — таблица курсов с фильтрами, CRUD через модалку
|
||||
- `/tax-records` — таблица налогов с фильтрами и сводкой по типам
|
||||
|
||||
**Фронтенд (доработки):**
|
||||
- `/transactions` — infinite scroll вместо пагинации (scroll-based)
|
||||
- `/accounts` — отображение баланса в валюте счёта + в базовой валюте
|
||||
- Навигация обновлена — добавлены ссылки на Дашборд, Курсы, Налоги
|
||||
|
||||
## Тесты
|
||||
|
||||
Запуск всех тестов одной командой (из `backend/`):
|
||||
|
||||
```bash
|
||||
cd backend && uv run pytest
|
||||
```
|
||||
|
||||
Verbose: `cd backend && uv run pytest -v`
|
||||
|
||||
### Фикстуры
|
||||
|
||||
Общий `conftest.py` в `tests/` предоставляет:
|
||||
- `engine` — Postgres test DB (`budget_app_test`) с `create_all`/`drop_all` на каждый тест + seed валют
|
||||
- `client` — ASGI клиент с зарегистрированным тестовым юзером
|
||||
- `auth_headers` — JWT Bearer token
|
||||
|
||||
Все тесты используют **Postgres** (не sqlite). Настройка через `settings.test_database_url`.
|
||||
|
||||
### Покрытие
|
||||
|
||||
**37 тестов + 1 skipped**:
|
||||
|
||||
| Файл | Тестов | Что проверяет |
|
||||
|------|--------|---------------|
|
||||
| `test_health.py` | 1 | Health endpoint |
|
||||
| `test_models.py` | 3 | Импорт моделей, метаданные, create_all в sqlite |
|
||||
| `test_auth.py` | 2 | Auth flow (register→login→me), unauthorized |
|
||||
| `test_api.py` | 6 | Транзакции (list, filter, search), accounts, reports, unauthorized |
|
||||
| `test_crud.py` | 6 | CRUD транзакций |
|
||||
| `test_categories.py` | 8 | CRUD групп и категорий |
|
||||
| `test_accounts.py` | 6 | CRUD счетов, удаление с транзакциями |
|
||||
| `test_account_balances.py` | 6 | **Баланс: доход+расход, переводы, cross_rate, initial_balance** |
|
||||
|
||||
### Вычисление баланса
|
||||
|
||||
`balance = initial_balance + incoming - outgoing`
|
||||
|
||||
- `incoming` = SUM(amount) if cross_rate IS NULL, SUM(amount * cross_rate) если перевод между валютами (для dest_account)
|
||||
- `outgoing` = SUM(amount) — всегда в валюте источника
|
||||
|
||||
Reference in New Issue
Block a user