# PhotoPlaces Маркетплейс фотолокаций: находите места и студии для фотосъёмок, бронируйте, общайтесь с фотографами. ## Стек | Компонент | Технология | |-----------|-----------| | Фронтенд | Next.js 14, React 18, TypeScript, Tailwind CSS | | Бэкенд | Go 1.22, Chi router, pgx | | База данных | PostgreSQL 16 + PostGIS | | Кэш | Redis 7 | | Файлы | MinIO (S3-совместимое хранилище) | | Авторизация | JWT (access + refresh токены) | | Инфраструктура | Docker, docker-compose | ## Быстрый старт (локальная разработка) ### 1. Клонирование и запуск зависимостей ```bash git clone http://192.168.88.96:10880/foxtime/photoplaces.git cd photoplaces docker compose up -d postgres redis minio ``` ### 2. Настройка окружения ```bash cp backend/.env.example backend/.env cp frontend/.env.local.example frontend/.env.local ``` ### 3. Запуск бэкенда ```bash cd backend go run ./cmd/api ``` Бэкенд будет доступен на `http://localhost:8080/api/v1` ### 4. Запуск фронтенда (в отдельном терминале) ```bash cd frontend npm install npm run dev ``` Фронтенд будет доступен на `http://localhost:3000` ### Через Make ```bash make dev # docker compose + go run + npm run dev одновременно ``` ## Развёртывание на сервере (192.168.88.128) ### Первичная настройка сервера Заходим на сервер по SSH и запускаем: ```bash ssh foxtime@192.168.88.128 curl -fsSL http://192.168.88.96:10880/foxtime/photoplaces/raw/main/deploy/deploy-remote.sh | bash ``` Скрипт автоматически: 1. Проверит/установит Docker, Git, curl, openssl 2. Склонирует репозиторий 3. Сгенерирует секреты (пароли БД, JWT, S3) 4. Запросит Yandex Maps API Key и домен 5. Запустит docker-compose в production режиме ### Ручной деплой (если автоматический не подошёл) ```bash ssh foxtime@192.168.88.128 cd /home/foxtime/photoplaces docker compose --env-file deploy/env.prod -f deploy/docker-compose.prod.yml up -d --build ``` ### Просмотр логов ```bash ssh foxtime@192.168.88.128 cd /home/foxtime/photoplaces docker compose -f deploy/docker-compose.prod.yml logs -f ``` ### Обновление после изменений в репозитории ```bash ssh foxtime@192.168.88.128 cd /home/foxtime/photoplaces git pull origin main docker compose --env-file deploy/env.prod -f deploy/docker-compose.prod.yml up -d --build --remove-orphans ``` ## Структура проекта ``` photoplaces/ ├── backend/ │ ├── cmd/api/main.go # Точка входа API │ ├── internal/ │ │ ├── config/ # Загрузка конфига из env │ │ ├── handlers/ # HTTP-обработчики (auth, places, services...) │ │ ├── middleware/ # JWT-аутентификация, rate limiter │ │ ├── models/ # Модели данных (User, Place, Booking...) │ │ ├── repository/ # Запросы к PostgreSQL │ │ ├── services/ # Бизнес-логика │ │ ├── validator/ # Валидация (go-playground/validator) │ │ ├── pointer/ # Утилиты для указателей │ │ └── log/ # Структурированное логирование (slog) │ ├── migrations/ # SQL-миграции (golang-migrate) │ └── docs/ # Документация ├── frontend/ │ ├── src/ │ │ ├── app/ # Страницы (Next.js App Router) │ │ ├── components/ # React-компоненты │ │ ├── hooks/ # Пользовательские хуки (useAuth) │ │ ├── lib/ # Утилиты (api, map) │ │ ├── styles/ # Глобальные стили │ │ └── types/ # TypeScript-типы │ └── public/ ├── deploy/ # Инфраструктура продакшена │ ├── docker-compose.prod.yml │ ├── env.prod │ ├── deploy.sh │ ├── deploy-remote.sh │ └── setup.sh ├── docker-compose.yml # Локальная разработка └── Makefile # Автоматизация команд ``` ## Команды Make ```bash make dev # Локальная разработка make prod # Продакшен-сборка make test # Запуск всех тестов make test-backend # Тесты бэкенда make test-frontend # Тесты фронтенда make logs # Просмотр логов make stop # Остановка контейнеров make migrate # Запуск миграций ``` ## API Полная спецификация: `backend/docs/API_CONTRACT.md` Базовый URL: `http://localhost:8080/api/v1` ### Основные эндпоинты | Метод | Путь | Авторизация | |-------|------|-------------| | POST | /auth/register | Нет | | POST | /auth/login | Нет | | POST | /auth/refresh | Нет | | POST | /auth/logout | + | | GET | /auth/me | + | | GET | /places | Нет | | GET | /places/:id | Нет | | GET | /places/my | + | | POST | /places | + | | PATCH | /places/:id | + | | DELETE | /places/:id | + | | POST | /places/:id/moderate | moderator+ | | POST | /places/:id/restore | moderator+ | | GET | /tags | Нет | | GET | /features | Нет | | GET | /services | Нет | | GET | /services/:id | Нет | | POST | /services | + | | PATCH | /services/:id | + | | DELETE | /services/:id | + | | POST | /bookings | + | | GET | /bookings/me | + | | PATCH | /bookings/:id/cancel | + | | PATCH | /bookings/:id/confirm | moderator+ | | GET | /reviews | Нет | | POST | /reviews | + | | GET | /users/:id | Нет | | PATCH | /users/me | + | | GET | /admin/users | moderator+ | | POST | /admin/users | moderator+ | | PATCH | /admin/users/:id | moderator+ | | POST | /admin/tags | moderator+ | | DELETE | /admin/tags | moderator+ | | POST | /admin/features | moderator+ | | DELETE | /admin/features | moderator+ | | DELETE | /admin/places/:id | moderator+ (hard delete) | | POST | /upload | + | | POST | /upload/presigned-url | + | | GET | /ws/visitors | Нет (WebSocket) | | GET | /admin/setup-status | Нет | | POST | /admin/setup | Нет | | GET | /health | Нет | ## Конфигурация ### Бэкенд (`backend/.env`) | Переменная | По умолчанию | Описание | |-----------|-------------|---------| | APP_ENV | development | Среда | | SERVER_PORT | 8080 | Порт | | DATABASE_URL | postgres://... | Подключение к БД | | REDIS_URL | redis://... | Подключение к Redis | | S3_ENDPOINT | http://localhost:9000 | MinIO endpoint | | S3_PUBLIC_ENDPOINT | http://localhost:9000 | Публичный S3 endpoint | | S3_ACCESS_KEY | photoplaces | S3 Access Key | | S3_SECRET_KEY | photoplaces_dev | S3 Secret Key | | S3_BUCKET | photoplaces | S3 Bucket | | JWT_SECRET | dev-secret | JWT Secret | | JWT_REFRESH_SECRET | dev-refresh-secret | JWT Refresh Secret | | ALLOWED_ORIGINS | http://localhost:3000 | CORS origins | ### Фронтенд (`frontend/.env.local`) | Переменная | По умолчанию | |-----------|-------------| | NEXT_PUBLIC_API_URL | http://localhost:8080/api/v1 | | NEXT_PUBLIC_MAP_PROVIDER | leaflet | ## Миграции Миграции запускаются автоматически через `backend/docker-entrypoint.sh` при старте бэкенда. Отдельно (локально): ```bash make migrate # или docker compose run --rm migrate ``` Файлы миграций: `backend/migrations/` (11 миграций) ## Роли пользователей | Роль | Права | |------|-------| | superadmin | Полный доступ | | moderator | Модерация мест, управление пользователями | | landlord | Создание и управление студиями | | executor | Создание и управление услугами | | customer | Поиск и бронирование | ## Безопасность - JWT-аутентификация: access token (15 мин) + refresh token (30 дней) - Rate limiting: Redis-based, настраивается для каждой группы эндпоинтов - CORS: только разрешённые origins - Защита от SQL-инъекций: pgx с параметризованными запросами - Валидация ввода: go-playground/validator - Мягкое удаление (soft delete: deleted_at) - Content Security Policy (CSP) через Caddy (в production) - WebSocket origin check: только разрешённые домены - Проверка сигнатуры файлов (magic bytes) при загрузке изображений - Rate limiter: Redis (sliding window) + in-memory fallback с fail-open/closed