Files
family_budget/backend/README.md
Anton 975f2c4fd2 feat: adds PDF import with conversion to JSON 1.0
- Accept only PDF and JSON files in import modal and API
- Convert PDF statements to JSON 1.0 via LLM (OpenAI-compatible)
- Use multipart/form-data for file upload (multer, 15 MB limit)
- Add LLM_API_KEY and LLM_API_BASE_URL for configurable LLM endpoint
- Update ImportModal to validate type and send FormData
- Add postFormData to API client for file upload
2026-03-13 13:38:02 +03:00

139 lines
8.3 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.
# Family Budget — Backend
API-сервер на Express + TypeScript + PostgreSQL.
## Запуск
```bash
# 1. Установить зависимости (из корня монорепо)
npm install
# 2. Собрать shared-типы
npm run build -w shared
# 3. Скопировать и заполнить .env
cp .env.example .env
# 4. Создать БД PostgreSQL
createdb family_budget
# 5. Запустить в dev-режиме (миграции применяются автоматически при старте)
npm run dev -w backend
```
Сервер стартует на `http://localhost:3000` (или на порту из `PORT`).
## Скрипты
| Скрипт | Команда | Описание |
|--------------|--------------------------------|--------------------------------------------|
| `dev` | `npm run dev -w backend` | Запуск с hot-reload (tsx watch) |
| `build` | `npm run build -w backend` | Компиляция TypeScript → `dist/` |
| `start` | `npm run start -w backend` | Запуск скомпилированного сервера |
| `migrate` | `npm run migrate -w backend` | Применить миграции вручную (без старта) |
## Переменные окружения
| Переменная | По умолчанию | Описание |
|----------------------|----------------|---------------------------------------------|
| `DB_HOST` | `localhost` | Хост PostgreSQL |
| `DB_PORT` | `5432` | Порт PostgreSQL |
| `DB_NAME` | `family_budget`| Имя базы данных |
| `DB_USER` | `postgres` | Пользователь БД |
| `DB_PASSWORD` | `postgres` | Пароль БД |
| `APP_USER_LOGIN` | `admin` | Логин для входа в приложение |
| `APP_USER_PASSWORD` | `changeme` | Пароль для входа в приложение |
| `SESSION_TIMEOUT_MS` | `10800000` | Таймаут сессии по бездействию (3 часа) |
| `PORT` | `3000` | Порт HTTP-сервера |
| `LLM_API_KEY` | — | Ключ OpenAI API для конвертации PDF в JSON; без него импорт PDF возвращает 503 |
| `LLM_API_BASE_URL` | `https://api.openai.com/v1` | Адрес LLM API (OpenAI-совместимый); для локальной модели, напр. Ollama: `http://localhost:11434/v1` |
## Структура проекта
```text
backend/src/
├── app.ts — точка входа: Express, миграции, монтирование роутов
├── config.ts — чтение переменных окружения
├── utils.ts — утилиты (maskAccountNumber, asyncHandler)
├── db/
│ ├── pool.ts — пул подключений pg
│ └── migrate.ts — миграции (встроенный SQL) + seed 23 категорий
├── middleware/
│ └── auth.ts — проверка сессии, таймаут 3 ч, обновление last_activity_at
├── services/
│ ├── auth.ts — login / logout / me
│ ├── import.ts — валидация, fingerprint, direction, атомарный импорт
│ ├── pdfToStatement.ts — конвертация PDF → JSON 1.0 через LLM (OpenAI)
│ ├── transactions.ts — список с фильтрами + обновление (categoryId, comment)
│ ├── accounts.ts — список счетов, обновление алиаса
│ ├── categories.ts — список категорий (фильтр isActive)
│ ├── categoryRules.ts — CRUD правил + apply к прошлым транзакциям
│ └── analytics.ts — summary, by-category, timeseries
└── routes/
├── auth.ts — POST login/logout, GET me
├── import.ts — POST /api/import/statement
├── transactions.ts — GET /api/transactions, PUT /api/transactions/:id
├── accounts.ts — GET /api/accounts, PUT /api/accounts/:id
├── categories.ts — GET /api/categories
├── categoryRules.ts — GET/POST/PATCH /api/category-rules, POST :id/apply
└── analytics.ts — GET summary, by-category, timeseries
```
## API-эндпоинты
### Авторизация
| Метод | URL | Описание |
|--------|----------------------|------------------------------|
| POST | `/api/auth/login` | Вход (login + password) |
| POST | `/api/auth/logout` | Выход (инвалидация сессии) |
| GET | `/api/auth/me` | Текущий пользователь |
### Импорт
| Метод | URL | Описание |
|--------|----------------------------|-----------------------------------------|
| POST | `/api/import/statement` | Импорт банковской выписки (PDF или JSON 1.0; PDF конвертируется через LLM) |
### Транзакции
| Метод | URL | Описание |
|--------|----------------------------|-----------------------------------------|
| GET | `/api/transactions` | Список с фильтрами и пагинацией |
| PUT | `/api/transactions/:id` | Обновить категорию / комментарий |
### Справочники
| Метод | URL | Описание |
|--------|----------------------------|-----------------------------------------|
| GET | `/api/accounts` | Список счетов |
| PUT | `/api/accounts/:id` | Обновить алиас счёта |
| GET | `/api/categories` | Список категорий |
### Правила категоризации
| Метод | URL | Описание |
|--------|----------------------------------|--------------------------------------|
| GET | `/api/category-rules` | Список правил |
| POST | `/api/category-rules` | Создать правило |
| PATCH | `/api/category-rules/:id` | Частичное обновление / деактивация |
| POST | `/api/category-rules/:id/apply` | Применить к прошлым транзакциям |
### Аналитика
| Метод | URL | Описание |
|--------|----------------------------------|-------------------------------------|
| GET | `/api/analytics/summary` | Сводка: расходы, доходы, топ-5 |
| GET | `/api/analytics/by-category` | Расходы по категориям |
| GET | `/api/analytics/timeseries` | Динамика (day / week / month) |
## База данных
Миграции применяются автоматически при старте сервера. Таблицы:
- **accounts** — банковские счета (bank, account_number, currency, alias)
- **categories** — 23 категории с типами expense / income / transfer (seed)
- **transactions** — операции с fingerprint-дедупликацией, привязкой к счёту и категории
- **category_rules** — правила авто-категоризации (pattern, match_type, priority)
- **sessions** — серверные сессии с таймаутом по бездействию