API для бронирования мест на мероприятия с авторизацией пользователей.
Перед началом работы убедитесь, что установлены следующие инструменты:
-
Docker - для работы с контейнерами
-
Docker Compose - для управления контейнерами
- Установка Docker Compose
- Проверка:
docker compose version
-
Tilt - для локальной разработки с hot-reload
- Установка Tilt
- Проверка:
tilt version
Проект построен на базе:
- NestJS
- PostgreSQL
- DDD (Domain-Driven Design) - архитектурный подход
- Чистая архитектура - разделение на слои
- users - управление пользователями и авторизация
- events - управление событиями
- booking - бронирование мест на события
docker network create eventioПерейдите в директорию проекта и запустите Tilt:
cd <project folder>
tilt upНажмите пробел, чтобы открыть контрольную панель Tilt в браузере.
Tilt автоматически:
- Соберет Docker образ приложения
- Запустит контейнеры (приложение и PostgreSQL)
- Настроит hot-reload для разработки
После запуска контейнеров выполните инициализацию БД:
docker exec -i eventio-postgres psql -U postgres -d postgres < ./db/init/init.sqlWARNING: Инициализация должна выполнится автоматически, команда дана "для подстраховки". Результат в виде:
ERROR: role "eventio" already exists
ERROR: database "eventio" already exists
говорит о том, что база ранее успешно создана.
# Основные миграции (создание таблиц)
docker exec -i eventio-main pnpm migrate:up
# Seed миграции (тестовые данные)
docker exec -i eventio-main pnpm migrate:seed:upПосле выполнения инициализации приложение будет доступно по адресу:
- API: http://localhost:4001
- Tilt UI: http://localhost:10350
API доступен на порту 4001:
curl http://localhost:4001/api/eventsБД доступна на порту 5434:
# Подключение через psql
psql -h localhost -p 5434 -U eventio -d eventio
# Пароль: eventioИли через Docker:
docker exec -it eventio-postgres psql -U eventio -d eventioУчетные данные БД:
- Host:
localhost - Port:
5434 - User:
eventio - Password:
eventio - Database:
eventio
curl -X POST http://localhost:4001/api/users/login \
-H "Content-Type: application/json" \
-d '{
"name": "UserOne",
"password": "111"
}'Ответ:
{
"success": true,
"token": "uuid-токен",
"userId": 1
}Важно: Сохраните полученный токен для использования в последующих запросах.
curl -X POST http://localhost:4001/api/users/logout \
-H "Authorization: Bearer YOUR_TOKEN_HERE"curl -X GET http://localhost:4001/api/eventscurl -X GET http://localhost:4001/api/events/1curl -X POST http://localhost:4001/api/events \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"name": "Концерт джаз-группы",
"total_seats": 150
}'curl -X POST http://localhost:4001/api/bookings/reserve \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"eventId": 1
}'Примечание: userId автоматически берется из токена авторизации, в теле запроса передается только eventId.
# 1. Авторизация и сохранение токена
TOKEN=$(curl -s -X POST http://localhost:4001/api/users/login \
-H "Content-Type: application/json" \
-d '{"name": "UserOne", "password": "111"}' | jq -r '.token')
echo "Token: $TOKEN"
# 2. Получение списка событий
curl -X GET http://localhost:4001/api/events
# 3. Создание нового события
curl -X POST http://localhost:4001/api/events \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"name": "Концерт джаз-группы", "total_seats": 150}'
# 4. Резервация места
curl -X POST http://localhost:4001/api/bookings/reserve \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"eventId": 1}'
# 5. Выход
curl -X POST http://localhost:4001/api/users/logout \
-H "Authorization: Bearer $TOKEN"После выполнения seed миграций в системе будут доступны:
Пользователи:
UserOne/111UserTwo/222UserThree/333
События:
- Концерт рок-группы (100 мест)
- Театральная постановка (50 мест)
- Спортивное мероприятие (200 мест)
- Используется простейшая система авторизации через Bearer токены
- Токены хранятся в памяти приложения
- Все токены сбрасываются при перезапуске контейнера
- В проекте используется минимальная типизация для упрощения разработки
- API сервис:
4001(внешний) →3000(внутри контейнера) - PostgreSQL:
5434(внешний) →5432(внутри контейнера)
Все доменные ошибки автоматически преобразуются в JSON ответы с соответствующими HTTP кодами:
BusinessRuleError→400 Bad RequestValidationError→400 Bad RequestEntityNotFoundError→404 Not FoundDuplicateEntityError→409 Conflict
Для остановки всех сервисов:
tilt downИли через Docker Compose:
docker compose downsrc/
├── app/ # Инфраструктурные модули
│ ├── database/ # Настройки БД и миграции
│ └── main.ts # Точка входа
├── domains/ # Домены приложения
│ ├── users/ # Домен пользователей
│ ├── events/ # Домен событий
│ └── booking/ # Домен бронирования
└── shared/ # Общий код
└── common/ # Базовые классы DDD
# Запуск в режиме разработки (через Tilt)
tilt up
# Применение миграций
docker exec -i eventio-main pnpm migrate:up
# Откат миграций
docker exec -i eventio-main pnpm migrate:down
# Применение seed миграций
docker exec -i eventio-main pnpm migrate:seed:up
# Откат seed миграций
docker exec -i eventio-main pnpm migrate:seed:down