8.9 KiB
8.9 KiB
📘 Финансовый модуль
1. Общее описание
Финансовый модуль предназначен для учёта:
- доходов
- расходов
- категорий
Поддерживает три способа ввода расходов:
- Ручной ввод
- Ввод номера и даты чека
- Загрузка фото чека
2. Глоссарий
Доход (Income)
Денежное поступление (зарплата, перевод, подарок и т.д.)
Расход (Expense)
Факт траты денег
Категория (Category)
Классификация доходов и расходов (например: еда, транспорт, зарплата)
Чек (Receipt)
Документ, содержащий информацию о покупке (дата, позиции, сумма)
Позиция (Position)
Отдельная строка в чеке (товар или услуга)
3. Доменная модель
3.1 Positions
positions (
id,
receipt_number,
operation_date,
gtin_code,
product_name,
product_count,
amount,
discount,
name_spd,
category_id,
family_id,
family_member_id,
created_at,
updated_at
)
Описание полей:
receipt_number— номер чека (nullable для ручного ввода)operation_date— дата операцииgtin_code— код товараproduct_name— название товараproduct_count— количествоamount— сумма позицииdiscount— скидкаname_spd— продавецcategory_id— категорияfamily_id— семьяfamily_member_id— участник
3.2 Receipts
receipts (
id,
receipt_number,
ui,
status,
issued_at,
total_amount,
payment_amount,
cash_amount,
another_amount,
clearing_amount,
margin,
currency,
payment_type,
cashbox_number,
cashier,
name_spd,
name_to,
name_np,
type_np,
street_to,
house_to,
kod_soato,
oblast_soato,
rayon_soato,
selsovet_soato,
doc_num,
skno_number,
unp,
success,
family_id,
family_member_id,
created_at
)
Описание:
- хранит агрегированную информацию о чеке
- используется при сканировании QR
- связывается с positions через
receipt_number
3.3 Categories
categories (
id,
name,
type,
family_id,
family_member_id,
created_at
)
Описание полей:
type— income | expense- категория принадлежит семье
4. Бизнес-логика
4.1 Добавление расхода вручную
- пользователь вводит:
- сумму
- описание
- категорию
- создаётся запись в
positions receipt_number = NULL
4.2 Добавление дохода
- аналогично расходу
- используется категория типа
income
4.3 Добавление расхода по номеру и дате чека
Поток:
- Пользователь вводит номер и дату чека
- Backend получает данные чека через внешний сервис
- Создаётся запись в
receipts - Создаётся связанная транзакция в
transactions - Для каждой позиции создаётся запись в
positions
4.4 Добавление расхода по фото чека
Поток:
- Пользователь загружает фото чека
- Backend извлекает текст через OCR
- Backend извлекает из текста номер и дату чека
- Backend получает данные чека через внешний сервис
- Создаётся запись в
receipts - Создаётся связанная транзакция в
transactions - Для каждой позиции создаётся запись в
positions
5. Потоки
Ручной ввод
User → API POST /transactions → transactions
Доход
User → API POST /transactions → transactions
Чек по номеру и дате
User → API POST /transactions → receipt provider → receipts + positions + transactions
Чек по фото
User → API POST /transactions multipart/form-data → OCR → receipt provider → receipts + positions + transactions
6. API (черновик)
Создание транзакции вручную
POST /api/v1/transactions
Content-Type: application/json
{
"family_id": 1,
"created_by": 2,
"type": "expense",
"category": "groceries",
"amount": 1000,
"description": "Продукты",
"datetime": "2026-01-21T10:11:12Z"
}
Создание транзакции по номеру и дате чека
POST /api/v1/transactions
Content-Type: application/json
{
"family_id": 1,
"created_by": 2,
"receipt_number": "0123456789ABCDEFGHIJKLMN",
"receipt_date": "21.01.2026"
}
Создание транзакции по фото чека
POST /api/v1/transactions
Content-Type: multipart/form-data
Поля формы:
photo— файл изображения чека, обязательноfamily_id— ID семьи, обязательноcreated_by— ID пользователя, обязательноtype— тип транзакции, опционально, по умолчаниюexpensecategory— категория, опционально, по умолчаниюreceiptdescription— описание транзакции, опционально
Получение транзакций
GET /api/v1/transactions
Фильтры:
- дата
- категория
- тип
- family_id
Правила для POST /api/v1/transactions
Используется ровно один сценарий создания:
- Ручная транзакция:
обязательны
family_id,created_by,type,category,amount,datetime - Транзакция по чеку:
обязательны
family_id,created_by,receipt_number,receipt_date - Транзакция по фото:
обязательны
photo,family_id,created_by
Нельзя смешивать ручные поля транзакции (amount, datetime, receipt_id) с полями чека (receipt_number, receipt_date) в одном JSON-запросе.
7. Задачи для разработки
Этап 1 — База
- Переписать SQL-миграции (positions, receipts, categories)
Этап 2 — Категории
- CRUD категорий
- Валидация типа (income/expense)
Этап 3 — Транзакции
- Endpoint создания транзакции
- Endpoint получения списка
- Фильтрация
Этап 4 — Доходы/расходы
- Определение типа через категорию
- Валидация соответствия
Этап 5 — Чеки
- Endpoint загрузки фото чека через
POST /transactions - Интеграция с сервисом чеков
- Создание receipts
- Создание транзакции по номеру и дате чека
- Создание транзакции по фото чека
- Создание positions
Этап 6 — Telegram интеграция
- Команды добавления дохода/расхода
- Обработка QR
Этап 7 — Дополнительно
- Автокатегоризация
- Статистика
- Лимиты
8. Архитектурные решения
- Transaction — основная сущность финансов
- Receipt — дополняет транзакцию
- Position - позиции из чека
- Категории определяют тип операции
- Поддержка multi-tenant через family_id
9. Открытые вопросы
- Нужна ли мультивалютность?
- Можно ли редактировать чек?
- Как обрабатывать ошибки OCR?
- Нужен ли отдельный endpoint для повторной привязки чека к существующей транзакции?
- Нужны ли роли внутри семьи?