# Budget App Персональный бюджет в виде веб-приложения. Замена Excel-таблицы `~/Downloads/Budget.xlsx`, в которой ведутся транзакции 2020–2024+ по нескольким счетам в разных валютах. **Solo на старте** (только Alex), но код пишем generic — с прицелом на public SaaS позже (multi-tenant, конфиги отделены). ## Источник: текущая Excel-таблица Файл: `~/Downloads/Budget.xlsx` (3.6 MB, 13 листов). ### Листы | Лист | Назначение | |------|------------| | `транзакции` | **Главное хранилище**. ~34 462 строки, 28 колонок (A–AB). Все дебеты/кредиты по всем счетам подряд. | | `курсы` | Справочник курсов: `Currency`, `Rate`, `Date`, computed-курс к выбранной валюте отчёта. До 9 467 строк (история по датам). | | `категории` | Иерархия категорий: подкатегория → родитель с эмодзи (например `Аренда` → `🏢 Аренда`). | | `счета` | Справочник счетов: имя, валюта, активный (bool), льготный период, месячный платёж, курс к выбранной, `name in form`. | | `2020 отчет`…`2024 отчет` | Годовые сводки: план/факт по доходам, расходам, инвестициям, разнице, накопленному капиталу. | | `налоги 22-24` | Учёт ИП-патентов, НДФЛ и пр. | | `сводная` | Сводная таблица по годам. | | `Наличные (форма)` | Hidden — форма быстрого ввода. | | `test` | Песочница. | ### Схема листа «транзакции» Колонки (расшифрованы из shared strings + формул): | Кол | Имя | Тип | Описание | |-----|-----|-----|----------| | A | дата | date | Дата операции. | | B | сумма | number | Сумма в валюте счёта-источника. | | C | дебет | ref→счета | Счёт, **с которого** ушло (источник). Пусто = доход извне. | | D | кредит | ref→счета | Счёт, **на который** пришло (получатель). Пусто = расход вовне. | | E | категория | ref→категории | Подкатегория (см. лист `категории`). | | F | комментарий | text | Свободный комментарий. | | G | курс | number | Кросс-курс дебет→кредит, если перевод между валютами. | | H | входящ деб | number | Остаток на дебете до операции. | | I | остаток деб | number | Остаток на дебете после. | | J | входящ кред | formula | `=IF(D<>"", B*IF(C<>"", G, 1), "")` — сумма в валюте кредита. | | K | остаток кред | number | Остаток на кредите до. | | L | остаток кред | formula | `=IF(D<>"", K+J, "")` — остаток на кредите после. | | M | вал. счёта | formula | `VLOOKUP(C, счета, 2)` — валюта дебета. | | N | деб: курс к тек | number | Курс валюты дебета к выбранной валюте отчёта. | | O | сумма в тек вал | number | Сумма в валюте отчёта (по курсу дебета). | | P | — | — | Скрытая. | | Q | крд: курс к тек | number | Курс валюты кредита к выбранной валюте отчёта. | | R | сумма в тек | number | Сумма в валюте отчёта (по курсу кредита). | | S | Налог | number | Сумма налога по этой операции. | | T | Курс | number | Курс на дату операции. | | U–AB | — | — | Резерв / служебные. | **Семантика двойной записи:** одна строка = одно перемещение средств. Если `C` (дебет) пуст — это вход денег извне (доход). Если `D` (кредит) пуст — это выход вовне (расход). Если оба заполнены — внутренний перевод (между своими счетами, возможно с конверсией валют через `G`). ### Категории (примеры родительских групп) `💰 Salary`, `💸 Комиссии`, `📟 Квартплата/Связь`, `🧸 Дети`, `🏢 Аренда`, `⛽️ Транспорт/АЗС`, `💊 Медицина`, `🛒 Grocery`, `🍣 Рестораны`, `🧱 Стройка`, `💷 Кредиты`, `🏖️ Отдых`, `💸 Налоги`, `🛠️ Быт/Техника`, `🚙 Авто`, `👚 Одежда`, `💰 Дивиденды`, `💰 Депозиты`. Подкатегории — конкретные траты (`Кафе и рестораны`, `АЗС`, `Кровля материалы`, `Salary 88 05.11`, ...). ### Счета (примеры) `Demir KGS` (Сом), `Нал USD` (Доллар), `Альфа` (Рубль), `Нал RUB` (Рубль), `Альфа Кредитка`, `Сбер`, `Demir ИП USD`, `Нал EUR` (Евро), и т.д. Валюты в обращении: **RUB, USD, EUR, KGS, KZT, UZS, AED, CNY**. ## Что таблица умеет уже сейчас 1. **Учёт транзакций** в любой валюте, с автопересчётом в выбранную валюту отчёта. 2. **Остатки по счетам** в реальном времени (через `остаток деб` / `остаток кред`). 3. **Категоризация** в иерархии (родитель/подкатегория) с эмодзи. 4. **Годовые отчёты**: план vs факт, доход/расход/инвестиции, % отложено, накопленный капитал, долг. 5. **Курсы валют с историей** (за каждую дату — свой курс). 6. **Налоговый учёт** (отдельный лист `налоги 22-24`). 7. **Сводная** — динамика по годам. ## Болевые точки таблицы - Excel на 34k+ строк уже тормозит на пересчёте формул (`VLOOKUP` на массивы, `IF`-цепочки в каждой строке). - Ввод транзакций — ручной, через скрытую форму «Наличные», нет автоимпорта банковских выписок. - Категоризация — ручная. - Невозможно нормально работать с мобильного. - Анализ ограничен сводными в Excel: нет нормальных графиков по подкатегориям, кросс-фильтрации, прогнозов. - Нет ничего про FIRE: проекций пенсии, моделирования инвестиций, целевых процентов нормы сбережений. - История курсов хранится в строках листа `курсы` — это не нормализованная таблица. - Нет API: нельзя интегрировать с банковскими экспортами, нельзя автоматически тянуть в дашборд. ## Концепция веб-приложения ### Цель Заменить Excel приложением, которое: 1. Принимает все те же транзакции (multi-currency, multi-account, double-entry). 2. Считает аналитику и сводки **на лету** через SQL, а не через `VLOOKUP`. 3. Импортирует банковские выписки (Альфа, Сбер, Demir, …) автоматически + AI-резолвер для неоднозначных случаев. 4. Даёт мобильный UI для быстрого ввода трат на ходу. 5. Моделирует **FIRE-сценарии** (отдельная фаза после готового бюджетирования). 6. Прогнозирует траты на N месяцев вперёд по сезонной модели (категории `🧱 Стройка`, `🏖️ Отдых` цикличны). ### Доменная модель (первая итерация) ``` User (id, email, ...) -- для будущего multi-tenant SaaS Settings (user_id, base_currency_id, ...) -- base currency выбирается в настройках Currency (code, name, symbol) Account (id, user_id, name, currency_id, type {cash, debit, credit, deposit, brokerage}, active, credit_limit, grace_period_days, monthly_payment) CategoryGroup (id, user_id, name, emoji) -- родитель Category (id, user_id, name, group_id) -- подкатегория ExchangeRate (currency_id, date, rate_to_base, source {nbkr, manual, ...}) -- история по датам Transaction ( id, user_id, date, amount, source_account_id NULL, -- дебет (откуда); NULL = доход извне dest_account_id NULL, -- кредит (куда); NULL = расход вовне cross_rate NULL, -- курс при internal transfer category_id, comment, tax_amount NULL, import_id NULL -- ссылка на BankImport ) TaxRecord (year, month, type {patent, ндфл, …}, amount, currency_id, paid_date NULL) BankImport (id, user_id, account_id, source {alfa, sber, demir, ...}, fetched_at, raw_blob, status {pending, parsed, resolved, manual}) Alert (id, user_id, type {manual_resolve_needed, parse_failed, ...}, payload, sent_at, ack_at NULL) -- TG-уведомления FireGoal (id, user_id, target_amount, target_currency_id, expected_return_rate, target_date NULL) InvestmentSnapshot (date, account_id, value, currency_id) ``` Base currency не хардкодится — выбирается в `Settings`, и все пересчёты (остатки, отчёты, графики) автоматически приводятся к ней по `ExchangeRate.rate_to_base` на дату. ### Архитектура - **Backend**: Python + FastAPI + SQLAlchemy + Postgres. - **Frontend**: Vue 3 + Vite + Pinia. Адаптив для мобильного (PWA). - **БД**: отдельная БД `budget_app` в существующем кластере Postgres на Eagle (тот же инстанс, что и `personal_os` — не отдельный контейнер). - **Деплой**: Docker Compose на Mac (Eagle). Конфиги в `~/docker/budget-app/` (по конвенции остальных сервисов). Код проекта — `~/Developer/budget-app/` с git. - **Внешний доступ**: `budget.qentra.top` через Cloudflare Tunnel (или существующий nginx-reverse-proxy). Auth — login/password + долгоживущий JWT-токен в localStorage/cookie. Один пользователь на старте, но схема готова под multi-tenant. - **Импорт Excel**: однократный скрипт миграции (`scripts/import-xlsx.py`), читает `Budget.xlsx`, заливает в БД. - **Курсы валют**: cron-джоб тянет курсы с НБ Кыргызстана (`nbkr.kg` XML feed) по расписанию (раз в день). Если на какую-то дату курса нет — автоматически дозаполняет (back-fill ближайшего рабочего дня). Источник по умолчанию для KGS-базы; для других валют — ручной override или дополнительные источники (ЦБ РФ, ECB). - **Импорт банков**: автоматический fetch выписок (где есть API/HTML-парсинг) + парсеры CSV/XLS на Python (Альфа, Сбер, Demir — у каждого свой формат). После парсинга — прогон через AI-агента (LLM) для резолва неоднозначных строк: категоризация, merge дубликатов, идентификация контрагентов. - **Telegram-бот для алертов**: оповещение, когда нужно ручное вмешательство (AI не смог однозначно категоризировать, парсер сломался на новом формате выписки, обнаружен дубль). Подтверждение/правка через инлайн-кнопки в TG → апдейт в БД. - **HTTP MCP-интеграция**: приложение экспонирует MCP-сервер (HTTP transport), чтобы Eagle/Hermes мог запрашивать сводки, добавлять транзакции голосом, дёргать прогнозы из чата. - **Аналитика**: SQL-агрегаты + Apache ECharts на фронте. - **FIRE / Инвестпортфели**: отдельная фаза после того, как бюджетирование готово. Не в MVP. ### Этапы 1. **Phase 0 — Discovery & schema**. Полностью разобрать Excel, утвердить доменную модель. *(в процессе — этот док)* 2. **Phase 1 — Skeleton + import**. Создать `~/Developer/budget-app/` (git init), FastAPI + Postgres в Docker Compose в `~/docker/budget-app/`, миграция xlsx → БД. Read-only viewer транзакций + остатков + годовые отчёты. Внешний доступ через `budget.qentra.top` с auth. 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. *(отдельное планирование когда бюджетирование готово.)* ### Multi-tenant readiness (для будущего public SaaS) Даже в solo-режиме на старте: - Все таблицы доменной модели имеют `user_id` (на solo — захардкожен на одного юзера). - Конфиги (домен, секреты, базовая валюта) — в `.env` / config-файле, не в коде. - AI-промпты, парсеры банков, источники курсов — pluggable, через интерфейсы/registry. - Никаких личных данных Alex в коде (имена счетов, категорий, комментарии) — всё через миграцию данных в БД. - Лицензия — выбрать перед публичным релизом (AGPL/MIT/коммерческая). ## Открытые вопросы - Какой именно auth: самописный JWT, готовый Authlib, или Authelia/Authentik как внешний провайдер? (С прицелом на multi-tenant.) - AI-резолвер: какой провайдер по умолчанию? (Claude через openclaw / локальная LLM?) - Хранить ли raw blob банковской выписки навсегда (audit) или только парсенные транзакции? - Какой парсер xlsx использовать (openpyxl сейчас вызывал approval timeout — возможно perl/node-вариант)? ## Следующий шаг Планирование Phase 1: структура `~/Developer/budget-app/`, скелет FastAPI + Postgres + Vue, миграция Excel → БД, базовый auth + nginx/tunnel для `budget.qentra.top`. --- **Создано:** 2026-06-21 **Статус:** Phase 0 — Discovery (правки внесены)