Files
family_budget/backend/README.md

141 lines
8.6 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
```
Для Docker Compose production-переменные передаются из `backend/.env`. Файл не хранится в Git и не копируется в Docker image; перед запуском создайте его из `.env.example` и заполните секреты.
Сервер стартует на `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** — серверные сессии с таймаутом по бездействию