10 KiB
| name | description | metadata | ||
|---|---|---|---|---|
| budget-current-plan | Актуальный бизнес-процесс фичи «Бюджет» — версия после полного сброса проекта (см. ниже "Второй урок"); не путать со старым бюджет_проект_план.md (2006 год, источник идей, не требований) |
|
Старый файл бюджет_проект_план.md — заметки 2006 года, источник идей, не требований. Этот файл —
то, что реально подтверждено в разговоре. Актуальна только эта версия — предыдущая версия этого
же файла (обсуждение копилок/целей ДО того, как весь проект снесли и начали заново) частично устарела,
см. "Второй урок" ниже про то, почему.
Продукт
Личный (не мульти-пользовательский) трекер бюджета — один человек ведёт свой бюджет. users всё же
нужна (не совсем однопользовательский в смысле схемы БД) — счета/категории/транзакции ссылаются на
user_id, без этого пришлось бы возвращаться к вопросу при первом же втором пользователе.
Users
id, login, password, name, email, date_add, last_login. Пока достаточно.
Accounts (счета)
Три типа type_acc:
cash— кошелёк (наличные).bank— счёт в банке; карта просто привязана к нему, сама по себе денег не хранит (это сознательное упрощение — раньше в модели были отдельные "дебетовая карта"/"кредитная карта"/ "е-money" и т.п., это НЕ подтверждено заново после сброса, убрано).savings— копилка: тот же счёт, но с процентом на остаток (история ставок — отдельная таблица, привязанная кaccount_id). Опционально может иметь цель (см.goalsниже) — если записи вgoalsнет, это просто копилка "без цели", копишь под процент без конкретной суммы/даты.
Поля: id, user_id, type_acc, title, summa (баланс), is_delete (архивация вместо удаления),
order.
Categories (статьи) — с подкатегориями
id, user_id, parent_id (null — категория верхнего уровня; иначе — id родителя), title, type
(income/expense), order.
Пример: «Продукты» — родительская категория, «Алкоголь» — подкатегория внутри неё. Транзакция привязывается к конкретной (под)категории. В отчёте можно смотреть по родителю целиком (сумма всех подкатегорий) или провалиться в конкретную подкатегорию отдельно.
Transactions
id, user_id, categorie_id, account_f_id (откуда), account_in_id (куда), date, summa,
type (income/expense/transfer). Для дохода — только account_in_id, для расхода — только
account_f_id, для перевода — оба.
Обычный transfer между обычными счетами — без категории (пример: переложил 3000 ₽ с карты в кошелёк — деньги не потрачены и не заработаны, просто переехали, категория тут не имеет смысла).
⚠️ ОТКРЫТЫЙ ВОПРОС — transfer на savings-счёт (пополнение копилки/цели) МОЖЕТ иметь категорию, и пользователь хочет, чтобы такой transfer засчитывался как "потрачено" по этой категории в план/факт бюджета — то есть отложил 10 000 ₽ в копилку «Отпуск» в январе → сразу считается "потрачено 10 000 на Отпуск" в январском бюджете, ещё до самой поездки.
Нерешённая проблема с этим: когда деньги реально тратятся (сама поездка — гостиница, билеты), если те траты ТОЖЕ пометить категорией «Отпуск» — сумма задвоится (одни и те же деньги посчитаны и при откладывании, и при реальной трате). Пользователь сказал «я подумаю» — решение пока не принято, не проектировать/не кодировать эту часть, пока не будет ответа. Варианты, которые обсуждались (но не выбраны): (а) реальные траты в момент поездки НЕ помечать той же категорией, раз уже засчитано при откладывании; (б) какой-то другой механизм анти-задвоения.
Budgets (план/факт)
id, categorie_id, plan_summ, year, month, type. План — вручную на месяц по категории; факт
— не хранится, считается на лету как сумма transactions по этой категории за месяц (с учётом
открытого вопроса выше — возможно, включая помеченные transfer на копилки).
Account_rates (история ставок)
id, account_id, rate_percent, valid_from, valid_to (null = текущая). Общая механика для
savings, с расчётом на будущее переиспользование для кредита (там % работает в другую сторону —
не начисление, а долг — но структура «ставка + период» та же). Кредит сейчас вне скоупа.
Goals (цель для копилки)
id, account_id, target_summa, deadline. Необязательная надстройка над savings-счётом.
Прогноз «сколько класть в месяц» считается на лету по ТЕКУЩЕЙ ставке (не хранится), в предположении,
что она не изменится до дедлайна; пересчитывается при просмотре/смене ставки.
Проценты, начисленные на копилку — income-транзакция на счёт-копилку с одной системной
категорией «Проценты по вкладам/целям» (одна на все копилки, не по одной на каждую) — заводится
пользователю автоматически при первом использовании.
Приоритет фич
- Цели (план/факт) + анализ бюджета — сейчас.
- Инвестиции (вклады/акции/облигации) — следующий слой, схему делать с запасом.
- Кредиты — отложены, но
account_ratesнамеренно универсальна для переиспользования позже.
Второй урок (почему эта версия файла переписана)
После того как весь код/схема домена бюджета были снесены "с нуля" по прямому требованию пользователя, я в следующем же заходе молча притащил старые выводы из ПРЕДЫДУЩЕЙ версии этого файла (users, accounts, categories, transactions, budgets) как будто они уже согласованы — хотя после сброса заново обсуждались только копилки/цели. Пользователь: «про пользователя мы ничего не обсуждали, про бюджет мы ничего не обсуждали... ОТКУДА БЛЯДЬ???». Урок: "сохранено в памяти" ≠ "можно молча переиспользовать после полного сброса" — если проект/фичу explicitly снесли и просили начать заново, каждое решение переподтверждается в текущем разговоре заново, даже если оно дословно совпадёт с тем, что уже было записано. Ссылаться на память можно только явно и открыто ("вот что записано, актуально ли?"), не молча вставлять в предложение как решённое.
How to apply: перед тем как писать schema.sql/контроллеры/репозитории — свериться с этим файлом
и убедиться, что каждый пункт был реально произнесён в текущем контексте разговора, а не просто
существует здесь с прошлого раза. Новые уточнения — дописывать сюда сразу.