# Позиция 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')); ``` Использование в аналитике: - Для выбранного периода (например, текущий месяц) по каждой категории можно: - найти соответствующий бюджет (если задан); - посчитать фактический расход за период; - показать: потрачено / лимит / % выполнения / остаток. Это позволит в будущем реализовать экран "Бюджеты", а также подсветку категорий, где расходы близки к лимиту или превышают его.