@hexlet/frontend-flight-booking-server
v0.2.0
Published
Hexlet-provided backend for the flight booking diploma project. Implements the contract/ OpenAPI in-memory.
Readme
@hexlet/frontend-flight-booking-server
Готовый бэкенд для дипломного проекта «Бронирование авиабилетов». Студент не пишет его, а
подключает к своему фронтенду как npm-пакет (@hexlet/frontend-flight-booking-server) или поднимает локально.
- Fastify 5 (TypeScript), запуск через Fastify CLI (
fastify start). - In-memory хранилище: города/рейсы сидятся при старте, брони в
Map(эфемерно). - Реализует контракт
contract/(openapi.yaml). Типы реквестов/ответов генерируются из контракта черезopenapi-typescript(src/generated/api.ts), рантайм-валидация — Zod.
Команды
npm install
npm run gen:types # contract/openapi.yaml → src/generated/api.ts
npm run build # tsc → dist
npm run dev # fastify start -w -i tsx src/app.ts (:8080)
npm start # fastify start dist/src/app.js (:8080)
npm test # vitestЗапуск установленного пакета (как делает студент):
npx frontend-flight-booking-server start -p 8080 # API на :8080
npx frontend-flight-booking-server start -s ./dist -p 8080 # + отдавать собранный SPA из ./distКонтракт API в пакете
Контракт (TypeSpec main.tsp + сгенерированный openapi.yaml) живёт в каталоге contract/ пакета и
едет вместе с ним в npm. Студенту он нужен, чтобы знать форму API. Получить его в свой проект:
npx frontend-flight-booking-server contract # скопирует openapi.yaml + main.tsp в ./contract
npx frontend-flight-booking-server contract api-spec # в указанный каталогЛибо прочитать напрямую: node_modules/@hexlet/frontend-flight-booking-server/contract/openapi.yaml.
openapi.yaml — источник правды по эндпоинтам, телам запросов/ответов и кодам.
Релиз новой версии (npm)
Пакет публикуется утилитой release-it (ориентир — go_url_shortener_project/frontend).
Релиз одной командой из каталога server/:
make release # = npx release-itЧто делает make release (см. .release-it.json):
before:init— собираетdist(npm run build); требует чистого рабочего дерева (git.requireCleanWorkingDir) — незакоммиченных изменений быть не должно.- Спрашивает тип инкремента версии — patch / minor / major (или ввести конкретную) и поднимает
её в
package.json+package-lock.json. - Делает коммит
Release x.y.z, проставляет git-тегvx.y.zи пушит коммит с тегом. npm publish— публикует пакет (prepublishOnlyпересобираетdist; контрактcontract/openapi.yamlcontract/main.tspуезжают в пакет согласноfiles). Scope@hexlet, публичный (publishConfig.access=public).
Перед первым релизом / разово
- Авторизоваться в npm:
npm login(или положить токен в~/.npmrc://registry.npmjs.org/:_authToken=<TOKEN>). Нужны права на публикацию в scope@hexlet. - Текущая версия —
0.1.0(первый публичный релиз можно выпустить как есть либо сразу1.0.0).
Пошагово
# 1. Если менялся API — синхронизировать контракт и типы (см. «Связь с контрактом» ниже),
# закоммитить изменения. Рабочее дерево должно быть чистым.
git status # ничего не должно висеть
cd server
make release # интерактивно: выбрать patch/minor/major
# Не интерактивно (CI / без вопросов):
npx release-it patch --ci # или minor / major / конкретная версия: npx release-it 1.0.0 --ciПосле публикации проверить: npm view @hexlet/frontend-flight-booking-server version и страницу пакета на npmjs.
Студент обновляется обычным npm install @hexlet/frontend-flight-booking-server@latest (или ^<версия>).
Альтернатива — автопубликация по git-тегу через CI: см. закомментированную джобу
server_deployв корневом.gitlab-ci.yml.
Эндпоинты (/api)
| Метод | Путь | |
|---|---|---|
| GET | /api/cities | справочник городов |
| GET | /api/flights?origin=&destination=&date=&passengers= | поиск рейсов (нет совпадений → 200 [], невалидно → 400) |
| GET | /api/flights/{id} | рейс по id (404, если нет) |
| POST | /api/bookings | создать бронь → 201 + code; пустой passengers/неизвестный flightId → 400 |
| GET | /api/bookings/{code}?lastName= | просмотр (неверная фамилия → 404) |
| DELETE | /api/bookings/{code}?lastName= | отмена → бронь со status:"cancelled" |
Ошибки — { "code": "validation_error" | "not_found", "message": "..." }. totalPrice считается на сервере
(price × passengers). Идентификация брони — код + фамилия любого пассажира (case-insensitive).
Связь с контрактом
contract/main.tsp — источник правды (TypeSpec + сгенерированный openapi.yaml, лежит здесь же в contract/).
Цикл при изменении API: правка contract/main.tsp → npm --prefix contract run compile (перегенерит openapi.yaml) →
npm run gen:types здесь → npm run build (tsc подсветит рассинхрон хендлеров/сида с контрактом) → починить.
