|
|
@@ -0,0 +1,207 @@
|
|
|
+# 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
|
|
|
+```
|
|
|
+
|
|
|
+### 2. Запустить инфраструктуру (БД, Redis, MinIO)
|
|
|
+
|
|
|
+```bash
|
|
|
+docker compose up -d postgres redis minio
|
|
|
+```
|
|
|
+
|
|
|
+### 3. Инициализировать переменные окружения
|
|
|
+
|
|
|
+```bash
|
|
|
+cp backend/.env.example backend/.env
|
|
|
+cp frontend/.env.local.example frontend/.env.local
|
|
|
+```
|
|
|
+
|
|
|
+### 4. Запустить бэкенд
|
|
|
+
|
|
|
+```bash
|
|
|
+cd backend
|
|
|
+go run ./cmd/api
|
|
|
+```
|
|
|
+
|
|
|
+Бэкенд будет доступен на `http://localhost:8080/api/v1`
|
|
|
+
|
|
|
+### 5. Запустить фронтенд (в другом терминале)
|
|
|
+
|
|
|
+```bash
|
|
|
+cd frontend
|
|
|
+npm install
|
|
|
+npm run dev
|
|
|
+```
|
|
|
+
|
|
|
+Фронтенд будет доступен на `http://localhost:3000`
|
|
|
+
|
|
|
+### Либо через Make
|
|
|
+
|
|
|
+```bash
|
|
|
+make dev # docker compose + go run + npm run dev одной командой
|
|
|
+```
|
|
|
+
|
|
|
+## Структура проекта
|
|
|
+
|
|
|
+```
|
|
|
+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/ # бизнес-логика
|
|
|
+│ ├── migrations/ # SQL-миграции (golang-migrate)
|
|
|
+│ └── docs/ # документация
|
|
|
+│ ├── SPEC.md # техническое задание
|
|
|
+│ ├── API_CONTRACT.md # контракт API
|
|
|
+│ ├── DB_SCHEMA.md # схема базы данных
|
|
|
+│ ├── MAP_PROVIDERS.md # провайдеры карт
|
|
|
+│ └── PAYMENT_INTEGRATION.md
|
|
|
+├── frontend/
|
|
|
+│ ├── src/
|
|
|
+│ │ ├── app/ # страницы и layout (Next.js App Router)
|
|
|
+│ │ ├── components/ # React-компоненты
|
|
|
+│ │ ├── hooks/ # кастомные хуки (useAuth)
|
|
|
+│ │ ├── lib/ # утилиты (api, map)
|
|
|
+│ │ ├── styles/ # глобальные стили
|
|
|
+│ │ └── types/ # TypeScript-типы
|
|
|
+│ └── public/
|
|
|
+├── deploy/ # продакшен-окружение
|
|
|
+│ ├── docker-compose.prod.yml
|
|
|
+│ ├── env.prod
|
|
|
+│ ├── deploy.sh
|
|
|
+│ └── setup.sh
|
|
|
+├── docker-compose.yml # локальное окружение
|
|
|
+└── Makefile # вспомогательные команды
|
|
|
+```
|
|
|
+
|
|
|
+## Доступные команды
|
|
|
+
|
|
|
+```bash
|
|
|
+make dev # локальная разработка
|
|
|
+make prod # продакшен-сборка
|
|
|
+make logs # логи продакшена
|
|
|
+make stop # остановка контейнеров
|
|
|
+make clean # остановка + удаление volume
|
|
|
+make ps # статус контейнеров
|
|
|
+```
|
|
|
+
|
|
|
+## 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 | — |
|
|
|
+| POST | /places | + |
|
|
|
+| PATCH | /places/:id | + |
|
|
|
+| DELETE | /places/:id | + |
|
|
|
+| POST | /places/:id/moderate | moderator+ |
|
|
|
+| GET | /tags | — |
|
|
|
+| GET | /features | — |
|
|
|
+| GET | /services | — |
|
|
|
+| POST | /services | + |
|
|
|
+| PATCH | /services/:id | + |
|
|
|
+| DELETE | /services/:id | + |
|
|
|
+| POST | /bookings | + |
|
|
|
+| GET | /bookings/me | + |
|
|
|
+| PATCH | /bookings/:id/cancel | + |
|
|
|
+| GET | /reviews | — |
|
|
|
+| POST | /reviews | + |
|
|
|
+| GET | /users/:id | — |
|
|
|
+| PATCH | /users/me | + |
|
|
|
+| GET | /admin/users | moderator+ |
|
|
|
+| PATCH | /admin/users/:id | moderator+ |
|
|
|
+| POST | /upload/presigned-url | + |
|
|
|
+| GET | /ws/visitors | — (WebSocket) |
|
|
|
+
|
|
|
+## Переменные окружения
|
|
|
+
|
|
|
+### Бэкенд (`backend/.env`)
|
|
|
+
|
|
|
+| Переменная | По умолчанию | Обязательная |
|
|
|
+|-----------|-------------|-------------|
|
|
|
+| APP_ENV | development | — |
|
|
|
+| SERVER_PORT | 8080 | — |
|
|
|
+| DATABASE_URL | postgres://photoplaces:photoplaces_dev@localhost:5432/photoplaces?sslmode=disable | да |
|
|
|
+| REDIS_URL | redis://localhost:6379/0 | да |
|
|
|
+| S3_ENDPOINT | http://localhost:9000 | да |
|
|
|
+| S3_PUBLIC_ENDPOINT | http://localhost:9000 | да |
|
|
|
+| S3_ACCESS_KEY | photoplaces | да |
|
|
|
+| S3_SECRET_KEY | photoplaces_dev | да |
|
|
|
+| S3_BUCKET | photoplaces | да |
|
|
|
+| JWT_SECRET | dev-secret | да |
|
|
|
+| JWT_REFRESH_SECRET | dev-refresh-secret | да |
|
|
|
+| ALLOWED_ORIGINS | http://localhost:3000 | — |
|
|
|
+
|
|
|
+### Фронтенд (`frontend/.env.local`)
|
|
|
+
|
|
|
+| Переменная | По умолчанию |
|
|
|
+|-----------|-------------|
|
|
|
+| NEXT_PUBLIC_API_URL | http://localhost:8080/api/v1 |
|
|
|
+| NEXT_PUBLIC_MAP_PROVIDER | yandex |
|
|
|
+| NEXT_PUBLIC_YANDEX_MAPS_API_KEY | (пусто) |
|
|
|
+
|
|
|
+## Миграции
|
|
|
+
|
|
|
+Миграции накатываются автоматически в продакшене через `migrate/migrate` (см. `deploy/docker-compose.prod.yml`). Локально можно накатить вручную:
|
|
|
+
|
|
|
+```bash
|
|
|
+docker compose run --rm migrations
|
|
|
+```
|
|
|
+
|
|
|
+Файлы миграций: `backend/migrations/`
|
|
|
+
|
|
|
+## Роли пользователей
|
|
|
+
|
|
|
+| Роль | Описание |
|
|
|
+|------|----------|
|
|
|
+| superadmin | Полный доступ |
|
|
|
+| moderator | Модерация мест, управление пользователями |
|
|
|
+| landlord | Добавление и управление своими студиями |
|
|
|
+| executor | Добавление услуг фото/видеосъёмки |
|
|
|
+| customer | Добавление мест для съёмки |
|
|
|
+
|
|
|
+## Безопасность
|
|
|
+
|
|
|
+- JWT-аутентификация: access token (15 мин) + refresh token (30 дней)
|
|
|
+- Rate limiting: in-memory, 60 запр/мин на IP
|
|
|
+- CORS: настроен для разрешённых доменов
|
|
|
+- Параметризованные SQL-запросы (pgx)
|
|
|
+- Валидация загружаемых файлов (тип, размер)
|
|
|
+- Мягкое удаление (deleted_at)
|
|
|
+- Проверка владельца ресурса при изменении/удалении
|