# Локальная разработка ## Принцип В Docker запускаем стабильную инфраструктуру. Кодовые сервисы запускаем нодой с hot reload. Сейчас в Docker есть только: - PostgreSQL; - MinIO; - MinIO bucket init; - imgproxy dev instance; - RabbitMQ. `backend` уже умеет регистрировать assets и выполнять internal ensure. `gateway` уже ходит в Backend и держит L1 memory cache. `worker` уже читает RabbitMQ jobs, вызывает imgproxy и пишет variants в S3. Gateway обязателен для Cloudinary-like поведения и интеграции с `next/image`. ## Запуск инфраструктуры ```bash cp .env.example .env pnpm install pnpm infra:up pnpm db:migrate ``` `.env` используется только локально и игнорируется git. Backend, Gateway, Worker и Drizzle scripts автоматически подхватывают его через Node `--env-file-if-exists`; в production эти переменные должны приходить из окружения процесса. Проверить compose config: ```bash pnpm infra:config ``` Остановить: ```bash pnpm infra:down ``` Логи: ```bash pnpm infra:logs ``` ## Порты | Сервис | URL | |---|---| | PostgreSQL | `localhost:5433` | | MinIO API | `http://localhost:9000` | | MinIO Console | `http://localhost:9001` | | imgproxy | `http://localhost:18080` | | RabbitMQ | `amqp://localhost:5672` | | RabbitMQ Management | `http://localhost:15672` | | Backend API | `http://localhost:3001/api` | | Swagger | `http://localhost:3001/docs` | | Admin | `http://localhost:5173` | | Gateway | `http://localhost:8888` | Если `localhost:8888` занят старым `image-gateway`, остановите старый stack или задайте `GATEWAY_PORT=8890` в `.env`. ## Backend Запустить NestJS backend: ```bash pnpm backend:dev ``` Проверки: ```bash curl http://localhost:3001/api/health open http://localhost:3001/docs ``` Зарегистрировать source image в dev mode: ```bash curl -sS -X POST http://localhost:3001/api/assets \ -H 'content-type: application/json' \ -d '{"sourceUrl":"https://storage.yandexcloud.net/shared1318/img/1.jpg","publicId":"asset_demo"}' ``` Посмотреть business API: ```bash curl -sS http://localhost:3001/api/presets curl -sS http://localhost:3001/api/assets curl -sS http://localhost:3001/api/assets/asset_demo curl -sS http://localhost:3001/api/assets/asset_demo/variants ``` Явно поставить jobs на генерацию family variants без Gateway lazy request: ```bash curl -sS -X POST http://localhost:3001/api/assets/asset_demo/variants \ -H 'content-type: application/json' \ -d '{"preset":"card","mode":"family"}' ``` ## Database Drizzle schema живёт в `packages/database/src/schema.ts`, миграции - в `packages/database/drizzle`. Сгенерировать миграцию после изменения schema: ```bash pnpm db:generate ``` Применить миграции к локальному PostgreSQL: ```bash pnpm db:migrate ``` Открыть Drizzle Studio из корня проекта: ```bash pnpm db:studio ``` Проверить database package: ```bash pnpm db:typecheck pnpm db:build ``` ## Admin Запустить React/Vite admin: ```bash pnpm admin:dev ``` Открыть: ```bash open http://localhost:5173 ``` ## Gateway Gateway запускается нодой: ```bash pnpm gateway:dev ``` Проверить gateway health: ```bash curl http://localhost:8888/health ``` Проверить image origin route после запуска Backend и Worker: ```bash curl -i "http://localhost:8888/images/asset_demo/v1/card?w=640&q=80&f=auto" curl -i "http://localhost:8888/images/asset_demo/v1/avatar?f=auto" curl -i "http://localhost:8888/images/asset_demo/v1/custom?w=777&h=333&q=72&fit=fill&f=webp" ``` Первый запрос должен пройти через Backend/RabbitMQ/Worker/imgproxy/S3 и вернуться с `x-image-platform-l1: MISS`. Повторный запрос должен вернуться из gateway L1 с `x-image-platform-l1: HIT`. Статические presets сейчас лежат в `packages/image-config`: - `card` - responsive, widths `320`, `640`, `960`. - `hero` - responsive, widths `1280`, `1920`. - `avatar` - fixed `256x256`. Mock allowlist source hosts задаётся через `SOURCE_ALLOWED_HOSTS`. В dev по умолчанию разрешён `storage.yandexcloud.net`. ## Worker Worker запускается нодой, объявляет RabbitMQ topology, слушает `image.generate-variant`, вызывает `imgproxy` и пишет готовый variant в S3. ```bash pnpm worker:dev ``` Проверить worker package без запуска consumer: ```bash pnpm worker:typecheck pnpm worker:build ``` ## Будущий dev flow Текущая и будущая схема: ```text React/Vite admin localhost:5173 -> NestJS backend localhost:3001 -> PostgreSQL localhost:5433 -> MinIO localhost:9000 -> RabbitMQ localhost:5672 worker node process -> PostgreSQL -> MinIO -> RabbitMQ -> imgproxy localhost:18080 Fastify gateway localhost:8888 -> L1 memory cache -> Backend internal ensure endpoint ``` ## imgproxy для разработки В dev compose поднимается локальный `imgproxy`, опубликованный только на `127.0.0.1:18080`: ```env IMGPROXY_UPSTREAM=http://localhost:18080 ``` Для production `imgproxy` всё равно рассматривается как внешняя зависимость и может жить на отдельном мощном сервере.