diff --git a/personal/projects/budget-app/index.md b/personal/projects/budget-app/index.md new file mode 100644 index 00000000..80c5fd99 --- /dev/null +++ b/personal/projects/budget-app/index.md @@ -0,0 +1,157 @@ +# Budget App + +Персональный бюджет в виде веб-приложения. Замена Excel-таблицы `~/Downloads/Budget.xlsx`, в которой ведутся транзакции 2020–2024+ по нескольким счетам в разных валютах. + +## Источник: текущая 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. **Учёт транзакций** в любой валюте, с автопересчётом в выбранную валюту отчёта (default — RUB). +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, …) и категоризует автоматически. +4. Даёт мобильный UI для быстрого ввода трат на ходу. +5. Моделирует **FIRE-сценарии**: при текущей норме сбережений и доходности портфеля — когда достигаешь точки пассивного дохода. +6. Прогнозирует траты на N месяцев вперёд по сезонной модели (категории `🧱 Стройка`, `🏖️ Отдых` цикличны). + +### Доменная модель (первая итерация) + +``` +Currency (code, name, symbol) +Account (id, name, currency_id, type {cash, debit, credit, deposit, brokerage}, active, credit_limit, grace_period_days, monthly_payment) +CategoryGroup (id, name, emoji) -- родитель +Category (id, name, group_id) -- подкатегория +ExchangeRate (currency_id, date, rate_to_base) -- история по датам +Transaction ( + id, date, amount, + source_account_id NULL, -- дебет (откуда); NULL = доход извне + dest_account_id NULL, -- кредит (куда); NULL = расход вовне + cross_rate NULL, -- курс при internal transfer + category_id, comment, tax_amount NULL, + imported_from NULL -- метаданные импорта банковской выписки +) +TaxRecord (year, month, type {patent, ндфл, …}, amount, currency_id, paid_date NULL) +FireGoal (id, target_amount, target_currency_id, expected_return_rate, target_date NULL) +InvestmentSnapshot (date, account_id, value, currency_id) -- для отслеживания капитала +``` + +### Архитектура (черновик) + +- **Backend**: Python + FastAPI + SQLAlchemy + Postgres. +- **Frontend**: Vue 3 + Vite + Pinia (либо SvelteKit). Адаптив для мобильного. +- **БД**: Postgres (либо SQLite на старт, мигрировать позже). +- **Деплой**: Docker на Kraken (есть свободный хост, WireGuard + nginx уже настроены). +- **Импорт Excel**: однократный скрипт миграции (`scripts/import-xlsx.py`), читает `Budget.xlsx`, заливает в БД. +- **Импорт банков**: парсеры CSV/XLS на Python (Альфа, Сбер, Demir — у каждого свой формат). +- **Категоризация**: rules-based (regex по комменту) + позже — лёгкая ML-модель (sklearn / LLM-классификатор). +- **Аналитика**: SQL-агрегаты + Recharts/Apache ECharts на фронте. +- **FIRE**: модуль с входами (текущий капитал, ежемесячные сбережения, ожидаемая доходность, инфляция, целевой пассивный доход) → калькулятор и графики. + +### Этапы + +1. **Phase 0 — Discovery & schema**. Полностью разобрать Excel, утвердить доменную модель. *(в процессе — этот док)* +2. **Phase 1 — Import & read-only viewer**. Скрипт миграции из xlsx → Postgres. Простой viewer транзакций + остатков + годовые отчёты. +3. **Phase 2 — Ручной ввод**. Форма добавления транзакции, CRUD категорий/счетов, ведение курсов. +4. **Phase 3 — Импорт банков**. Парсеры CSV для актуальных счетов. Категоризация по правилам. +5. **Phase 4 — Аналитика**. Дашборды: расход по категориям, динамика, бёрндаун по бюджету. +6. **Phase 5 — FIRE-модуль**. Калькулятор, проекции, сценарии «что если». +7. **Phase 6 — Mobile / PWA**. Быстрый ввод с телефона. + +## Открытые вопросы + +- Какой выбрать base currency для отчётов по умолчанию? (В Excel — переменная.) +- Хранить ли курсы Centroбанка/ECB как источник истины + ручные override, или только ручной ввод? +- Нужна ли поддержка инвестиционных портфелей (тикеры, цены, дивиденды) — или это отдельный модуль? +- Multi-user (только Alex, или с возможностью добавить семью)? +- Self-hosted only, или может быть public SaaS позже? + +## Следующий шаг + +Обсудить доменную модель и архитектуру. После апрува — план Phase 1 (миграция Excel → БД, read-only viewer). + +--- + +**Создано:** 2026-06-21 +**Статус:** Phase 0 — Discovery