- 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
139 lines
8.3 KiB
Markdown
139 lines
8.3 KiB
Markdown
# 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** — серверные сессии с таймаутом по бездействию
|