Files
runners-calendar/docs/agent-backend-instruction.md
2026-04-01 13:42:37 +03:00

12 KiB
Raw Permalink Blame History

Инструкция агенту: реализация бэкенда по PLAN.md

Документ для ИИ-агента или разработчика, который создаёт backend монорепозитория «календарь забегов». Продуктовые цели и модель данных — в корневом PLAN.md; здесь — порядок работ, ограничения и обязательные итоговые артефакты для фронтенда.


0. Ограничение: нет возможности проверить подключение к БД

  1. Всё равно реализовать полноценный бэкенд «как для прод»: миграции SQL, пул подключений pg, переменные DB_*, docker-compose.yml с PostgreSQL в корне репозитория.
  2. Не блокировать работу отсутствием живой БД у исполнителя:
    • код миграций и seed должен быть валидным и согласованным с PLAN;
    • при старте API при невозможности подключиться к БД — ясное сообщение в лог и корректный HTTP-ответ на зависящих от БД маршрутах (например 503 с телом {"error":"database_unavailable",...}) или падение процесса на старте с понятной ошибкой (выбрать одну стратегию и описать её в docs/backend.md).
  3. Не выдумывать обход БД (in-memory «режим без Postgres»), если это не согласовано отдельно — фронт и план рассчитаны на PostgreSQL.
  4. Автотесты, требующие Docker/Postgres, помечать как опциональные или давать инструкцию «как прогнать локально», не считая провал из-за отсутствия БД у агента блокером для merge кода.

1. Ветка и расположение в репо

  • Если репозиторий под git: создать ветку feature/backend-api (или аналог по соглашению команды).
  • Каталог backend/ в корне проекта рядом с будущим frontend/.
  • Корневой docker-compose.yml — сервис postgres (порт, пользователь, БД, пароль — согласовать с .env.example).

2. Порядок реализации (обязательный)

Шаг A. Каркас

  • Node LTS, TypeScript, backend/package.json.
  • Фреймворк: Fastify или Express (выбрать один, не смешивать).
  • Загрузка env: dotenv или встроенные средства; валидация наличия DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD при старте (или при первом запросе к БД — но тогда задокументировать).
  • Сервер слушает порт из PORT или API_PORT (значение по умолчанию, напр. 3001, указать в .env.example).

Шаг B. CORS

  • Читать CORS_ORIGIN (например http://localhost:5173 для Vite в dev). В prod — origin фронта.
  • Разрешить методы и заголовки, нужные для GET/POST/PATCH + Content-Type: application/json.

Шаг C. Миграции

  • Каталог миграций, напр. backend/migrations/ с нумерованными SQL-файлами или один миграционный runner (node-pg-migrate, graphile-migrate, собственный скрипт — на выбор, зафиксировать в docs/backend.md).
  • Первая миграция: таблица races со столбцами, соответствующими PLAN (см. раздел 3 ниже).
  • Команда npm run db:migrate (или эквивалент в backend/) — идемпотентное накатывание на чистую БД.

Шаг D. Доступ к данным

  • Клиент pg: Pool с параметрами из DB_*.
  • Слой репозитория или прямые запросы в обработчиках — на усмотрение, без лишних абстракций сверх задачи.

Шаг E. HTTP API

Реализовать минимум:

Метод Путь Назначение
GET /health Liveness: процесс жив; не обязан проверять БД (или опционально — задокументировать).
GET /ready (опционально) Readiness: проверка соединения с БД — полезно для оркестраторов.
GET /races Список забегов; query: year, month (112) — фильтрация для экранов календаря; без параметров — все строки или разумный лимит + документация пагинации если добавите позже.
GET /races/:id Одна запись по id.
POST /races Создание; тело JSON в camelCase как в PLAN.
PATCH /races/:id Частичное обновление; только переданные поля.
DELETE /races/:id Опционально по PLAN; если не нужен фронту — можно не делать, но тогда явно написать в документации «удаление не поддерживается».

Ошибки:

  • 400 — валидация тела/параметров.
  • 404 — нет id.
  • 409 — конфликт уникального id при POST (если клиент прислал уже существующий).
  • 503 или 500 — недоступна БД (согласовать с разделом 0).

Формат ошибки: JSON, единообразно, напр. {"error":"validation_error","details":[...]}.

Шаг F. Seed (разовый скрипт)

  • Команда npm run seed в backend/ (или корне монорепо с workspace — единообразно).
  • Читает import/races_2026_calendar.csv (путь от корня репо); парсинг с учётом кавычек в поле названия.
  • Генерирует id стабильно: например {date}-{slug-from-title}; при коллизии — суффикс или upsert по id.
  • INSERT ... ON CONFLICT (id) DO UPDATE (upsert) — удобно для повторного запуска seed.
  • Seed не вызывается из HTTP handlers.

Шаг G. Корневой .env.example

  • Все переменные: DB_*, PORT/API_PORT, CORS_ORIGIN.
  • Без реальных паролей; комментарии к каждой переменной.

3. Соответствие полей PLAN ↔ SQL ↔ JSON API

В JSON API (запрос/ответ)camelCase, как в PLAN:

id, date, title, distanceKm, status, officialUrl, startTime, clusterSchedule, bibPickup, bibNumber, finishTime, notes.

В PostgreSQLsnake_case, например:

SQL column Тип (рекомендация)
id TEXT PRIMARY KEY
race_date DATE
title TEXT
distance_km NUMERIC(6,3)
status TEXT CHECK (опционально)
official_url TEXT
start_time TEXT
cluster_schedule TEXT
bib_pickup TEXT
bib_number TEXT
finish_time TEXT
notes TEXT
created_at TIMESTAMPTZ DEFAULT now()
updated_at TIMESTAMPTZ

Маппинг строго в одном модуле (например backend/src/mappers/race.ts), чтобы фронт всегда видел camelCase.

Типы date: в API строка YYYY-MM-DD. distanceKm: число. finishTime: строка времени как в PLAN; бэкенд не обязан парсить для бизнес-логики (PR считает фронт), но может валидировать формат по желанию.


4. Обязательный итог для упрощения фронтенда

После того как код бэкенда готов, агент обязан добавить в репозиторий документ:

Файл: docs/backend-api-for-frontend.md

В нём кратко и без пробелов в фактах:

  1. Base URL — что подставлять во фронт (VITE_API_BASE_URL), пример для dev.
  2. CORS — какой CORS_ORIGIN ожидается в dev.
  3. Таблица эндпоинтов — метод, путь, query, тело запроса (пример JSON), пример успешного ответа, коды ошибок.
  4. Модель Race — перечень полей в camelCase с типами и обязательностью для POST vs PATCH.
  5. Фильтр списка — как именно работают year и month на GET /races (включая границы: пустой месяц, только год и т.д.).
  6. Идемпотентность seed — одна фраза: upsert по id, откуда берётся CSV.
  7. Поведение при недоступной БД — что возвращает API / что в логах (как в реализации).

Дополнительно можно дублировать суть в docs/backend.md (общая эксплуатация: docker, migrate, seed, запуск), но backend-api-for-frontend.md — главная «шпаргалка» для разработчика SPA.


5. Критерии готовности (чеклист агента)

  • docker-compose.yml поднимает Postgres с параметрами, совместимыми с .env.example.
  • Миграция создаёт races; есть команда миграции.
  • Реализованы GET /races, GET /races/:id, POST /races, PATCH /races/:id согласно PLAN.
  • Реализован seed из import/races_2026_calendar.csv.
  • GET /health (и при наличии /ready — описано).
  • Корневой .env.example обновлён.
  • Написан docs/backend-api-for-frontend.md (раздел 4).
  • docs/backend.md содержит команды: установка зависимостей, migrate, seed, npm run dev для API.

6. Не входит в объём бэкенда (напоминание)

  • Авторизация, пользователи, сессии.
  • Парсинг сайтов организаторов.
  • Отдача статики фронта с того же процесса (фронт — отдельно Vite/build).

Конец инструкции. Источник требований к продукту — всегда PLAN.md.