48ef7217eb
- added auth - updated structure
300 lines
5.7 KiB
Markdown
300 lines
5.7 KiB
Markdown
# 📘 Финансовый модуль
|
|
|
|
## 1. Общее описание
|
|
|
|
Финансовый модуль предназначен для учёта:
|
|
- доходов
|
|
- расходов
|
|
- категорий
|
|
|
|
Поддерживает два способа ввода расходов:
|
|
1. Ручной ввод
|
|
2. Сканирование чека (QR-код)
|
|
|
|
---
|
|
|
|
## 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 Сканирование чека
|
|
|
|
#### Поток:
|
|
1. Пользователь отправляет QR-код
|
|
2. Backend получает данные чека через внешний сервис
|
|
3. Создаётся запись в `receipts`
|
|
4. Для каждой позиции создаётся запись в `positions`
|
|
|
|
---
|
|
|
|
## 5. Потоки
|
|
|
|
### Ручной ввод
|
|
|
|
```
|
|
User → API → positions
|
|
```
|
|
|
|
### Доход
|
|
|
|
```
|
|
User → API → positions
|
|
```
|
|
|
|
---
|
|
|
|
## 6. API (черновик)
|
|
|
|
### Создание позиции
|
|
|
|
```
|
|
POST /positions
|
|
```
|
|
|
|
```json
|
|
{
|
|
"amount": 1000,
|
|
"category_id": 1,
|
|
"description": "Продукты"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Сканирование чека
|
|
|
|
```
|
|
POST /receipts/scan
|
|
```
|
|
|
|
```json
|
|
{
|
|
"qr_data": "string"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Получение позиций
|
|
|
|
```
|
|
GET /positions
|
|
```
|
|
|
|
Фильтры:
|
|
- дата
|
|
- категория
|
|
- тип
|
|
- family_id
|
|
|
|
---
|
|
|
|
## 7. Задачи для разработки
|
|
|
|
### Этап 1 — База
|
|
|
|
- [ ] Переписать SQL-миграции (positions, receipts, categories)
|
|
|
|
---
|
|
|
|
### Этап 2 — Категории
|
|
|
|
- [ ] CRUD категорий
|
|
- [ ] Валидация типа (income/expense)
|
|
|
|
---
|
|
|
|
### Этап 3 — Позиции
|
|
|
|
- [ ] Endpoint создания позиции
|
|
- [ ] Endpoint получения списка
|
|
- [ ] Фильтрация
|
|
|
|
---
|
|
|
|
### Этап 4 — Доходы/расходы
|
|
|
|
- [ ] Определение типа через категорию
|
|
- [ ] Валидация соответствия
|
|
|
|
---
|
|
|
|
### Этап 5 — Чеки
|
|
|
|
- [ ] Endpoint загрузки QR
|
|
- [ ] Интеграция с сервисом чеков
|
|
- [ ] Создание receipts
|
|
- [ ] Создание positions
|
|
|
|
---
|
|
|
|
### Этап 6 — Telegram интеграция
|
|
|
|
- [ ] Команды добавления дохода/расхода
|
|
- [ ] Обработка QR
|
|
|
|
---
|
|
|
|
### Этап 7 — Дополнительно
|
|
|
|
- [ ] Автокатегоризация
|
|
- [ ] Статистика
|
|
- [ ] Лимиты
|
|
|
|
---
|
|
|
|
## 8. Архитектурные решения
|
|
|
|
- Position — основная сущность финансов
|
|
- Receipt — агрегат для чеков
|
|
- Категории определяют тип операции
|
|
- Поддержка multi-tenant через family_id
|
|
|
|
---
|
|
|
|
## 9. Открытые вопросы
|
|
|
|
- [ ] Нужна ли мультивалютность?
|
|
- [ ] Можно ли редактировать чек?
|
|
- [ ] Как обрабатывать ошибки OCR?
|
|
- [ ] Нужны ли роли внутри семьи?
|
|
|