Files
runners-calendar/docs/backend.md
Vaka.pro 007d899721
Some checks failed
CI / build-and-test (pull_request) Has been cancelled
chore: drop agent/plan docs, unify .env for Docker stack
- Remove PLAN/agent instruction files; single root .env.example for DB + API
- Stack compose uses env_file .env; delete stack env example duplicate
- Refresh README, backend docs, API doc; trim gitignore/dockerignore

Made-with: Cursor
2026-04-07 00:30:29 +03:00

122 lines
5.9 KiB
Markdown
Raw Permalink 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.
# Backend — эксплуатация
## Стек
- **Node.js LTS** + TypeScript
- **Express** (HTTP-фреймворк)
- **pg** (PostgreSQL клиент)
- **csv-parse** (парсинг CSV для seed)
## Быстрый старт
### 1. Поднять PostgreSQL
```bash
# из корня проекта
docker-compose up -d
```
Параметры подключения берутся из `.env` (см. `.env.example` в корне).
### 2. Установить зависимости
```bash
cd backend
npm install
```
### 3. Создать `.env`
Скопировать `.env.example` из корня проекта и при необходимости отредактировать:
```bash
cp ../.env.example ../.env
```
### 4. Миграции
```bash
npm run db:migrate
```
Миграционный раннер — собственный скрипт `src/migrate.ts`:
- хранит историю применённых файлов в таблице `_migrations`;
- идемпотентный — повторный запуск не применяет уже выполненные миграции;
- файлы миграций: `backend/migrations/*.sql`, применяются в алфавитном порядке.
### 5. Seed (начальный набор данных)
```bash
npm run seed
```
- Читает `import/races_2026_calendar.csv` из корня репо.
- Генерирует стабильный `id` в формате `{date}-{slug}`.
- Выполняет **upsert** (`INSERT … ON CONFLICT DO UPDATE`) — безопасно для повторного запуска.
### 6. Запуск API
```bash
npm run dev # dev-режим через ts-node
npm run build # компиляция в dist/
npm start # запуск из dist/
```
API слушает порт: **`PORT`** (если задан), иначе **`API_PORT`**, иначе **`3001`**.
## Переменные окружения
| Переменная | Описание | По умолчанию |
|---|---|---|
| `DB_HOST` | Хост PostgreSQL | — (обязательна без mock, см. ниже) |
| `DB_PORT` | Порт PostgreSQL | — (обязательна без mock) |
| `DB_NAME` | Имя базы данных | — (обязательна без mock) |
| `DB_USER` | Пользователь БД | — (обязательна без mock) |
| `DB_PASSWORD` | Пароль БД | — (обязательна без mock) |
| `CALENDAR_RUN_MOCK_DB` | `1` или `true` — режим без PostgreSQL для HTTP API (dev/CI) | выкл. |
| `PORT` | Порт API (приоритетнее `API_PORT`) | — |
| `API_PORT` | Порт API-сервера | `3001` |
| `CORS_ORIGIN` | Разрешённый origin для CORS | `http://localhost:5173` |
Для локального Vite в корневом `.env.example` также указан **`VITE_API_BASE_URL`** (читает только фронт из `frontend/`). В Docker-стеке базовый URL API задаётся при **сборке** образа фронта (`/api`), не через этот файл.
**Без mock:** при отсутствии любой из `DB_*` процесс падает при старте: `Missing required environment variable: <NAME>`.
**С `CALENDAR_RUN_MOCK_DB=1`:** переменные `DB_*` не обязательны; реальный пул не поднимается. **Не использовать** mock для `npm run db:migrate` и `npm run seed` — нужен настоящий Postgres и корректные `DB_*`.
## Поведение при недоступной БД
- **Старт сервера** — проходит успешно (env валидирован, Express слушает порт).
- **`GET /health`** — всегда `200 { "status": "ok" }` (liveness, без обращения к БД).
- **`GET /ready`** — при обычном режиме пробует подключиться к БД; `200` если ОК, `503 { "error": "database_unavailable", ... }` если нет. В режиме **`CALENDAR_RUN_MOCK_DB`** readiness считается успешным без реального подключения (удобно для CI/smoke API).
- **Все остальные маршруты** при ошибке БД возвращают `503 { "error": "database_unavailable" }`.
## Структура каталога
```
backend/
├── migrations/
│ ├── 001_create_races.sql
│ └── 002_finish_place_and_registered_status.sql
├── src/
│ ├── app.ts # фабрика Express (тесты)
│ ├── config.ts # загрузка и валидация env
│ ├── db.ts # pg Pool или mock
│ ├── index.ts # запуск сервера
│ ├── migrate.ts # раннер миграций
│ ├── seed.ts # разовый импорт CSV
│ ├── mappers/
│ │ └── race.ts # snake_case ↔ camelCase
│ └── routes/
│ ├── health.ts # /health, /ready
│ └── races.ts # CRUD /races
├── package.json
└── tsconfig.json
```
## Docker: стек backend + frontend
Файл [`docker-compose.stack.yml`](../docker-compose.stack.yml) поднимает API и nginx со статикой SPA в **внешней** сети Docker (рядом с уже запущенным Postgres). Переменные — в **корневом** `.env` (шаблон [`.env.example`](../.env.example)): как минимум `DB_*`, `CORS_ORIGIN` (для выдачи фронта на порту 3033 задайте `http://localhost:3033`). Перед первым `up` файл `.env` должен существовать.
Порядок после старта контейнеров: `node dist/migrate.js` и `node dist/seed.js` внутри контейнера `backend` (см. комментарии в compose-файле).