Files
obsidian-vault/personal/projects/budget-app/index.md
T

17 KiB
Raw Blame History

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 Курс на дату операции.
UAB Резерв / служебные.

Семантика двойной записи: одна строка = одно перемещение средств. Если 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 + 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. (отдельное планирование когда бюджетирование готово.)

Multi-tenant readiness (для будущего public SaaS)

Даже в solo-режиме на старте:

  • Все таблицы доменной модели имеют user_id (на solo — захардкожен на одного юзера).
  • Конфиги (домен, секреты, базовая валюта) — в .env / config-файле, не в коде.
  • AI-промпты, парсеры банков, источники курсов — pluggable, через интерфейсы/registry.
  • Никаких личных данных Alex в коде (имена счетов, категорий, комментарии) — всё через миграцию данных в БД.
  • Лицензия — выбрать перед публичным релизом (AGPL/MIT/коммерческая).

Открытые вопросы

Phase 0 закрыт — ключевые решения зафиксированы выше (auth, БД, raw blobs, импорт, multi-tenant readiness). Вопросы Phase 4 (AI-провайдер для резолвера, fallback на локальную LLM) — отложены до старта той фазы.

Следующий шаг

Планирование Phase 1: структура ~/Developer/budget-app/, скелет FastAPI + Postgres + Vue, миграция Excel → БД, базовый auth + nginx/tunnel для budget.qentra.top.


Создано: 2026-06-21 Статус: Phase 0 — Discovery (правки внесены)