- Rewrite db.md as canonical schema: add categories, sessions tables; add alias to accounts, is_category_confirmed/comment to transactions, FK references to categories(id); mark budgets as post-MVP - Fix account masking to use fixed 6 asterisks (code + docs) - Remove budgets from MVP requirements in agent_backend.md - Add explicit 'not in MVP' note to analytics.md budgets section - Fix test_Statement.json: convert amounts to kopecks (integers), remove fingerprint fields (computed by backend) Made-with: Cursor
184 lines
6.6 KiB
Markdown
184 lines
6.6 KiB
Markdown
# Позиция 5: Аналитика расходов и доходов
|
||
|
||
## 5.1. Периоды и навигация
|
||
|
||
Поддерживаются следующие режимы выбора периода:
|
||
|
||
- Быстрый выбор:
|
||
- Неделя — от начала текущей недели (с понедельника) до текущей даты.
|
||
- Месяц — от 1-го числа текущего месяца до текущей даты.
|
||
- Год — от 1 января текущего года до текущей даты.
|
||
- Произвольный диапазон:
|
||
- Пользователь задаёт `from` и `to` вручную.
|
||
|
||
Навигация:
|
||
|
||
- Для режимов Неделя/Месяц/Год доступны кнопки переключения периода:
|
||
- "предыдущая" / "следующая" неделя;
|
||
- "предыдущий" / "следующий" месяц;
|
||
- "предыдущий" / "следующий" год.
|
||
- При произвольном диапазоне навигация стрелками не используется (только ручная смена дат).
|
||
|
||
Фильтры, общие для всех отчётов:
|
||
|
||
- `accountId` (или несколько) — фильтр по счёту/счетам.
|
||
- Флаг "только подтверждённые категории" (`onlyConfirmed`) — учитывать только транзакции с `is_category_confirmed = TRUE`.
|
||
|
||
## 5.2. Основные аналитические блоки
|
||
|
||
### 1) Сводка периода (Summary)
|
||
|
||
Цель: дать быстрый обзор финансов за выбранный период.
|
||
|
||
Показатели:
|
||
|
||
- Общий расход (`totalExpense`).
|
||
- Общий доход (`totalIncome`).
|
||
- Чистый результат (`net = totalIncome - totalExpense`).
|
||
- Топ-3–5 категорий по расходам (сумма, доля).
|
||
|
||
Реализуется через эндпоинт `GET /api/analytics/summary`.
|
||
|
||
Параметры:
|
||
|
||
- `from`, `to` — границы периода;
|
||
- `accountId?` — фильтр по счёту (опционально);
|
||
- `onlyConfirmed?` — учитывать только подтверждённые категории.
|
||
|
||
Ответ (идея):
|
||
|
||
```json
|
||
{
|
||
"totalExpense": 12345600,
|
||
"totalIncome": 20000000,
|
||
"net": 7654400,
|
||
"topCategories": [
|
||
{ "categoryId": 1, "categoryName": "Продукты", "amount": 4500000, "share": 0.36 },
|
||
{ "categoryId": 2, "categoryName": "ЖКХ", "amount": 2500000, "share": 0.20 }
|
||
]
|
||
}
|
||
```
|
||
|
||
### 2) Расходы по категориям
|
||
|
||
Цель: понять структуру расходов, какие категории занимают основную долю.
|
||
|
||
Реализуется через эндпоинт `GET /api/analytics/by-category`.
|
||
|
||
Параметры:
|
||
|
||
- `from`, `to`;
|
||
- `accountId?`;
|
||
- `onlyConfirmed?`.
|
||
|
||
Ответ (идея):
|
||
|
||
```json
|
||
[
|
||
{
|
||
"categoryId": 1,
|
||
"categoryName": "Продукты",
|
||
"amount": 4500000,
|
||
"txCount": 32,
|
||
"share": 0.36
|
||
},
|
||
{
|
||
"categoryId": 2,
|
||
"categoryName": "ЖКХ",
|
||
"amount": 2500000,
|
||
"txCount": 5,
|
||
"share": 0.20
|
||
}
|
||
]
|
||
```
|
||
|
||
Использование на фронтенде:
|
||
|
||
- круговая диаграмма или bar-chart по категориям;
|
||
- таблица под диаграммой с суммами, долями и количеством операций.
|
||
|
||
### 3) Динамика во времени
|
||
|
||
Цель: увидеть изменение доходов/расходов по времени.
|
||
|
||
Реализуется через эндпоинт `GET /api/analytics/timeseries`.
|
||
|
||
Параметры:
|
||
|
||
- `from`, `to`;
|
||
- `accountId?`;
|
||
- `categoryId?` — при необходимости анализировать конкретную категорию;
|
||
- `onlyConfirmed?`;
|
||
- `granularity=day|week|month` — шаг агрегации.
|
||
|
||
Ответ (идея):
|
||
|
||
```json
|
||
[
|
||
{
|
||
"periodStart": "2026-02-01",
|
||
"periodEnd": "2026-02-07",
|
||
"expenseAmount": 3500000,
|
||
"incomeAmount": 0
|
||
},
|
||
{
|
||
"periodStart": "2026-02-08",
|
||
"periodEnd": "2026-02-14",
|
||
"expenseAmount": 4200000,
|
||
"incomeAmount": 0
|
||
}
|
||
]
|
||
```
|
||
|
||
Использование на фронтенде:
|
||
|
||
- линейный или столбиковый график: расходы и (опционально) доходы по периодам.
|
||
|
||
## 5.3. Задел под бюджеты (лимиты)
|
||
|
||
> **Не входит в MVP.** Этот раздел описывает будущую функциональность; таблица `budgets` и связанная логика реализуются после MVP.
|
||
|
||
Для поддержки бюджетов по категориям на будущих этапах вводится сущность `budgets`.
|
||
|
||
### Таблица `budgets` (идея)
|
||
|
||
Поля:
|
||
|
||
- `id BIGSERIAL PRIMARY KEY` — идентификатор бюджета.
|
||
- `category_id BIGINT` — ссылка на категорию (`categories.id`) или `NULL` для общего бюджета по всем категориям.
|
||
- `period_type TEXT NOT NULL` — тип периода:
|
||
- `"month"` — месячный бюджет;
|
||
- `"year"` — годовой бюджет.
|
||
- `year INT NOT NULL` — год действия бюджета.
|
||
- `month INT` — номер месяца (1–12), используется если `period_type = 'month'`.
|
||
- `amount_limit BIGINT NOT NULL` — лимит по расходам в копейках.
|
||
- `is_active BOOLEAN NOT NULL DEFAULT TRUE` — активен ли бюджет.
|
||
|
||
Пример DDL (базовый):
|
||
|
||
```sql
|
||
CREATE TABLE budgets (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
category_id BIGINT,
|
||
period_type TEXT NOT NULL,
|
||
year INT NOT NULL,
|
||
month INT,
|
||
amount_limit BIGINT NOT NULL,
|
||
is_active BOOLEAN NOT NULL DEFAULT TRUE
|
||
);
|
||
|
||
ALTER TABLE budgets
|
||
ADD CONSTRAINT chk_budgets_period_type
|
||
CHECK (period_type IN ('month', 'year'));
|
||
```
|
||
|
||
Использование в аналитике:
|
||
|
||
- Для выбранного периода (например, текущий месяц) по каждой категории можно:
|
||
- найти соответствующий бюджет (если задан);
|
||
- посчитать фактический расход за период;
|
||
- показать: потрачено / лимит / % выполнения / остаток.
|
||
|
||
Это позволит в будущем реализовать экран "Бюджеты", а также подсветку категорий,
|
||
где расходы близки к лимиту или превышают его.
|