Bicycle/.claude/memory/бюджет_текущий_план.md
2026-08-10 23:24:41 +03:00

110 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: budget-current-plan
description: Актуальный бизнес-процесс фичи «Бюджет» — версия после полного сброса проекта (см. ниже "Второй урок"); не путать со старым бюджет_проект_план.md (2006 год, источник идей, не требований)
metadata:
type: project
---
Старый файл `бюджет_проект_план.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`-транзакция на счёт-копилку с одной системной
категорией «Проценты по вкладам/целям» (одна на все копилки, не по одной на каждую) — заводится
пользователю автоматически при первом использовании.
## Приоритет фич
1. **Цели (план/факт) + анализ бюджета** — сейчас.
2. **Инвестиции** (вклады/акции/облигации) — следующий слой, схему делать с запасом.
3. **Кредиты** — отложены, но `account_rates` намеренно универсальна для переиспользования позже.
## Второй урок (почему эта версия файла переписана)
После того как весь код/схема домена бюджета были снесены "с нуля" по прямому требованию пользователя,
я в следующем же заходе молча притащил старые выводы из ПРЕДЫДУЩЕЙ версии этого файла (users, accounts,
categories, transactions, budgets) как будто они уже согласованы — хотя после сброса заново обсуждались
только копилки/цели. Пользователь: «про пользователя мы ничего не обсуждали, про бюджет мы ничего не
обсуждали... ОТКУДА БЛЯДЬ???». **Урок: "сохранено в памяти" ≠ "можно молча переиспользовать после
полного сброса"** — если проект/фичу explicitly снесли и просили начать заново, каждое решение
переподтверждается в текущем разговоре заново, даже если оно дословно совпадёт с тем, что уже было
записано. Ссылаться на память можно только явно и открыто ("вот что записано, актуально ли?"), не
молча вставлять в предложение как решённое.
**How to apply**: перед тем как писать `schema.sql`/контроллеры/репозитории — свериться с этим файлом
**и убедиться, что каждый пункт был реально произнесён в текущем контексте разговора**, а не просто
существует здесь с прошлого раза. Новые уточнения — дописывать сюда сразу.