refactor(api): unify /api contract across frontend, nginx, and backend
Some checks failed
CI / build-and-test (pull_request) Has been cancelled

This commit is contained in:
Anton
2026-04-08 11:59:46 +03:00
parent 9f63b190f1
commit 8eaf006906
17 changed files with 103 additions and 81 deletions

View File

@@ -2,13 +2,10 @@
## 1. Base URL
```
VITE_API_BASE_URL=http://localhost:3001
```
SPA всегда отправляет запросы на относительный префикс `/api` текущего origin.
В коде SPA: `import.meta.env.VITE_API_BASE_URL`.
В Docker-стеке из репозитория образ фронта собирается с **`VITE_API_BASE_URL=/api`**: запросы идут на тот же origin, nginx проксирует `/api` на backend (см. `docker/nginx.frontend.conf`).
- В dev (`npm run dev`): Vite proxy отправляет `/api/*` на `http://localhost:3001/api/*`.
- В Docker/проде: nginx фронта проксирует `/api/*` на backend в той же сети.
## 2. CORS
@@ -22,7 +19,7 @@ CORS_ORIGIN=http://localhost:5173
## 3. Эндпоинты
### `GET /health`
### `GET /api/health`
Liveness-проверка (без обращения к БД).
@@ -34,7 +31,7 @@ Liveness-проверка (без обращения к БД).
---
### `GET /ready`
### `GET /api/ready`
Readiness-проверка (проверяет подключение к БД).
@@ -52,7 +49,7 @@ Readiness-проверка (проверяет подключение к БД).
---
### `GET /races`
### `GET /api/races`
Список забегов, отсортированных по дате.
@@ -70,7 +67,7 @@ Readiness-проверка (проверяет подключение к БД).
**Пример запроса:**
```
GET /races?year=2026&month=5
GET /api/races?year=2026&month=5
```
**Ответ 200:**
@@ -99,7 +96,7 @@ GET /races?year=2026&month=5
---
### `GET /races/:id`
### `GET /api/races/:id`
Одна запись по `id`.
@@ -113,7 +110,7 @@ GET /races?year=2026&month=5
---
### `POST /races`
### `POST /api/races`
Создание забега.
@@ -155,7 +152,7 @@ GET /races?year=2026&month=5
---
### `PATCH /races/:id`
### `PATCH /api/races/:id`
Частичное обновление — передавать **только** изменяемые поля.
@@ -188,7 +185,7 @@ GET /races?year=2026&month=5
---
### `DELETE /races/:id`
### `DELETE /api/races/:id`
Удаление забега.
@@ -220,7 +217,7 @@ GET /races?year=2026&month=5
| `createdAt` | string | — | — | ISO timestamp (read-only) |
| `updatedAt` | string \| null | — | — | ISO timestamp (read-only) |
## 5. Фильтрация списка (`GET /races`)
## 5. Фильтрация списка (`GET /api/races`)
- **`year`** — целое число, фильтрует по `EXTRACT(YEAR FROM race_date)`.
- **`month`** — целое число 112, фильтрует по `EXTRACT(MONTH FROM race_date)`.
@@ -234,7 +231,7 @@ Seed-скрипт (`npm run seed` в `backend/`) выполняет **upsert**
## 7. Поведение при недоступной БД
- `GET /health` — всегда `200` (не проверяет БД).
- `GET /ready` — при недоступной БД: `503 { "error": "database_unavailable", "db": "disconnected" }`. В режиме **`CALENDAR_RUN_MOCK_DB`** (dev/CI без Postgres) readiness возвращает успех без реального подключения — см. `docs/backend.md`.
- `GET /api/health` — всегда `200` (не проверяет БД).
- `GET /api/ready` — при недоступной БД: `503 { "error": "database_unavailable", "db": "disconnected" }`. В режиме **`CALENDAR_RUN_MOCK_DB`** (dev/CI без Postgres) readiness возвращает успех без реального подключения — см. `docs/backend.md`.
- Все остальные маршруты — `503 { "error": "database_unavailable" }`.
- В логах сервера: строка ошибки с контекстом маршрута.