Разворот boilerplate и маршрут курса

Перед началом: ничего (стартовый модуль). Инструменты: Docker, Go 1.27+, Node 22+, make, psql. Трудоёмкость: ~3 ч.

🔥 Инцидент: «у меня не запускается»

Первое занятие любого курса по бэкенду умирает на одном и том же месте: пять человек пишут «не работает». У одного JWT_SECRET не задан, у второго порт 5432 занят чужим Postgres, у третьего фронт ходит в :8080, где сидит совсем другое приложение. Никто ещё не написал ни строчки логики — а половина группы уже застряла. В этом модуле мы разворачиваем стек так, чтобы эти грабли были исключены конструкцией, и фиксируем маршрут курса.

📖 Теория

1.1 Что такое boilerplate

Это монорепозиторий из двух частей:

boilerplate/
├── api/openapi.yaml        # контракт: auth, chat, реакции, стикеры, ws
├── backend/                # Go: chi + pgx + JWT + WS + outbox
├── frontend/               # React: Vite + FSD + effector + WS-клиент
├── docker-compose.yml      # postgres (:5433) + redis (:6380)
└── Makefile                # docker-up, migrate-up, seed, serve, test, validate-api

Бэкенд собран по канону production-сервиса: cmd/ (точки входа), internal/ (config, models, security, events, usecase, repository, handlers), миграции SQL, спецификация OpenAPI с тестом «каждый роут задокументирован, каждый путь реализован». Фронтенд — слои FSD (app → pages → widgets → features → entities → shared), модели effector, WS-клиент с переподключением.

Изучите структуру до того, как запускать: где хендлеры, где юзкейсы, где SQL, как связаны слои. Курс будет постоянно дописывать эти места.

1.2 Что умеет версия 1

ЕстьБудет в курсе
Регистрация и вход (bcrypt + JWT)Диалоги вместо общей комнаты
Одна общая комната, сообщенияЛичные диалоги (P2P)
WebSocket на комнатуГруппы: роли, участники, приглашения
Transactional Outbox → in-memory брокерСтрогий порядок (seq) и catch-up после реконнекта
Rest-история сообщенийRead-receipts, typing, presence
Health/ready, request-id, логиWeb Push, метрики, нагрузочный тест
Локальный docker composeВыкат на VM: реестр, релизы, health-гейт, откат

Сверх минимума в версии 1 уже реализованы реакции и стикеры — это рабочий образец того, как фича живёт поверх сообщений, не ломая порядок и непрочитанные: реакция не создаёт сообщение и не двигает seq, а изменение уходит лёгким событием message_reaction_changed через тот же outbox. Разберите их до начала практики: internal/repository/reactions.go и stickers.go на бэке, features/reactions и features/sticker-picker на фронте, миграции 000002–000003. Дальше в курсе мы будем опираться на этот образец (например, системные сообщения в группах — та же идея: данные поверх messages, событие через outbox).

Версия 1 — это «стадия 1» (модульный монолит): auth + чат + WS-хаб в одном процессе. В этом курсе мы остаёмся в стадии 1 и доводим её до продакшена; микросервисная эволюция (вынос ws-gateway, Redis Streams между репликами) — следующий курс трека.

1.3 Почему порты 5433 и 6380

Compose бойлерплейта намеренно не занимает дефолтные порты: локальный Postgres на 5432 и Redis на 6379 почти наверняка уже кем-то заняты (другой проект, дев-стенд). На первом занятии это выглядит как «докер сломался», хотя докер просто честно не смог забиндиться. Если открываете свои БД — используйте эти же порты или переопределите DATABASE_URL.

💻 Практика

  1. Разверните инфраструктуру и накатите схему:
bash
make docker-up     # postgres:16 → :5433, redis:7 → :6380
make migrate-up    # users, rooms, messages, reactions, stickers, outbox
make seed          # alice@example.dev / bob@example.dev, пароль secret123
  1. Поднимите бэкенд (терминал 1):
bash
cp .env.example .env      # JWT_SECRET — обязателен
make serve                # API + WS на :8080
  1. Поднимите фронтенд (терминал 2) и войдите как alice@example.dev:
bash
cd frontend && npm install && npm run dev
  1. Прогоните API-сценарий руками (вместо «поверю, что работает»):
bash
TOKEN=$(curl -s -X POST localhost:8080/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"alice@example.dev","password":"secret123"}' | jq -r .token)

curl -s localhost:8080/api/v1/chat/rooms -H "Authorization: Bearer $TOKEN" | jq
  1. Проверьте контракт и тесты — это ваш «зелёный свет» на весь курс:
bash
make test           # go test ./...
make validate-api   # спека валидна + роуты chi совпадают со спецификацией
  1. Откройте второй браузерный профиль (или инкогнито), войдите как bob, отправьте сообщения с обеих сторон — убедитесь, что доставка по WS работает и лента дедуплицируется.

Чек-лист модуля: /health и /ready отвечают ok; make test и make validate-api зелёные; два пользователя видят сообщения друг друга; вы можете нарисовать по памяти путь сообщения: REST → транзакция с outbox → воркер → брокер → WS-клиенты.

🧩 Quiz

1. Стадия 1 (монолит) в этом курсе — почему не сразу микросервисы?
2. Где живёт «Transactional Outbox» в бойлерплейте?
3. Что произойдёт, если не задать JWT_SECRET?
4. Почему compose использует порты 5433/6380, а не 5432/6379?
5. Что делает make seed?
6. Зачем в бойлерплейте тест «роуты ↔ спека»?

✅ Итоги модуля

  • Развёрнут стек: Postgres, Redis, бэкенд, фронтенд, сид-данные.
  • Зелёные make test и make validate-api — контракт и код синхронны.
  • Понятна структура backend/ (по канону cmd + internal) и фронт-слоёв FSD.
  • Зафиксирован маршрут: v1 — одна общая комната; v2 — диалоги, группы, sync, продакшен.
  • Известны грабли первого запуска: порты, JWT_SECRET, прокси фронта.

🔗 Мостик к Модулю 2

Комната в v1 — одна на всех. Настоящий мессенджер начинается с диалогов: у каждой переписки — свой маленький мир с участниками и своей лентой. В следующем модуле проектируем единую модель conversations для личных диалогов и групп — и идемпотентное создание P2P-переписки, которое не боится гонок.