# Test Task CRM Многопользовательская mini-CRM на FastAPI + PostgreSQL c сервисно-репозиторной архитектурой, JWT-аутентификацией, Alembic-миграциями и готовым React/Vite фронтендом. ## Стек и особенности - Python 3.14, FastAPI, SQLAlchemy Async ORM, Alembic. - Pydantic Settings для конфигурации, JWT access/refresh токены, кеш аналитики в Redis. - Frontend: Vite + React + TypeScript (см. `frontend/`). - Докер-окружение для разработки (`docker-compose-dev.yml`) и деплоя (`docker-compose-ci.yml`). ## Структура проекта ```text app/ api/ # FastAPI-роуты и зависимости core/ # Настройки, база, безопасность models/ # SQLAlchemy-модели repositories/ # Работа с БД services/ # Бизнес-правила и сценарии frontend/ # Vite + React SPA migrations/ # Alembic-миграции tests/ # Pytest (unit + интеграции) ``` ## Переменные окружения 1. Скопируйте шаблон: `cp .env.example .env`. 2. Обновите секреты (`DB_PASSWORD`, `JWT_SECRET_KEY`, и т.д.) перед запуском. 3. Все переменные описаны в `app/core/config.py`; Vite читает только ключи с префиксом `VITE_`. ### Backend | Переменная | Значение по умолчанию | Назначение | | --- | --- | --- | | `PROJECT_NAME` | `"Test Task CRM"` | Заголовки/метаданные API | | `VERSION` | `"0.1.0"` | Версия приложения | | `API_V1_PREFIX` | `/api/v1` | Базовый префикс REST | | `DB_HOST` | `localhost` | Хост PostgreSQL | | `DB_PORT` | `5432` | Порт PostgreSQL | | `DB_NAME` | `test_task_crm` | Имя БД | | `DB_USER` | `postgres` | Пользователь БД | | `DB_PASSWORD` | `postgres` | Пароль пользователя | | `DATABASE_URL` | — | Полный DSN (перекрывает `DB_*`), формат `postgresql+asyncpg://user:pass@host:port/db` | | `SQLALCHEMY_ECHO` | `false` | Логирование SQL | | `JWT_SECRET_KEY` | `change-me` | Секрет для подписи JWT | | `JWT_ALGORITHM` | `HS256` | Алгоритм JWT | | `ACCESS_TOKEN_EXPIRE_MINUTES` | `30` | TTL access-токена | | `REFRESH_TOKEN_EXPIRE_DAYS` | `7` | TTL refresh-токена | | `REDIS_ENABLED` | `false` | Включить кеш аналитики | | `REDIS_URL` | `redis://localhost:6379/0` | Строка подключения к Redis | | `ANALYTICS_CACHE_TTL_SECONDS` | `120` | TTL кэша аналитики | | `ANALYTICS_CACHE_BACKOFF_MS` | `200` | max задержка при ретраях записи в кеш | ### Frontend (Vite) | Переменная | Значение по умолчанию | Назначение | | --- | --- | --- | | `VITE_API_URL` | `http://localhost:8000` (в `.env.example`), в `src/config/env.ts` дефолт `https://kitchen-crm.k1nq.tech` | Базовый URL бекенда (без завершающего `/`) | | `VITE_APP_URL` | `http://localhost:5173` | URL SPA, используется для deeplink'ов и редиректов | ⚠️ В `frontend/src/config/env.ts` зашит production URL (`https://kitchen-crm.k1nq.tech`). При деплое в другое место обязательно обновите `VITE_API_URL`/`VITE_APP_URL` в `.env` или настройте переменные окружения на уровне хостинга. ## Локальный запуск без Docker ### Предварительные требования - Python 3.10+ и [uv](https://github.com/astral-sh/uv). - PostgreSQL 16+ (локально или через Docker). - (Опционально) Redis 7+ для кеша аналитики. ### Backend (API) ```bash # 1. Готовим окружение cp .env.example .env # отредактируйте .env: базы, секреты, VITE_* (если нужен фронтенд) # 2. Устанавливаем зависимости uv sync # 3. Применяем миграции uvx alembic upgrade head # 4. Запускаем API uvx uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 ``` PostgreSQL/Redis можно поднять вручную или командой `docker compose -f docker-compose-dev.yml up postgres redis -d`. ### Frontend ```bash cd frontend npm install npm run dev -- --host ``` Фронтенд ожидает, что `VITE_API_URL` указывает на работающий бекенд (например, `http://localhost:8000`). ## Запуск через Docker Compose ### Локальная разработка (`docker-compose-dev.yml`) - Собирает бекенд из `app/Dockerfile`, поднимает `postgres:16-alpine` и `redis:7-alpine`. - Порты по умолчанию: API `8000`, Postgres `5432`, Redis `6379`. - Все переменные берутся из `.env`. ```bash docker compose -f docker-compose-dev.yml up --build # или в фоне docker compose -f docker-compose-dev.yml up --build -d ``` ### Прод/CI стек (`docker-compose-ci.yml`) 1. Соберите образы и статику: ```bash docker build -f app/Dockerfile -t /test-task-crm:app . docker build -f migrations/Dockerfile -t /test-task-crm:migrations . cd frontend && npm install && npm run build && cd .. ``` 2. Залейте `frontend/dist` (используется как read-only volume) и задайте `GIT_HOST`, `GIT_USER`, `GIT_REPO` в `.env`. 3. Запустите стек: ```bash docker compose -f docker-compose-ci.yml up -d ``` В этом режиме `migrations` прогоняется один раз, `app` слушает порт `80`, Postgres хранит данные на `/mnt/data/postgres` (смонтируйте хостовую директорию заранее). ## Redis для аналитики Кеш аналитики выключен по умолчанию. Чтобы включить: 1. Поднимите Redis (`docker compose ... redis` или любым другим способом). 2. В `.env` выставьте: - `REDIS_ENABLED=true` - `REDIS_URL=redis://:6379/0` - (опционально) `ANALYTICS_CACHE_TTL_SECONDS` и `ANALYTICS_CACHE_BACKOFF_MS`. 3. При недоступности Redis сервис автоматически возвращается к прямым запросам в PostgreSQL и пишет предупреждения в лог. ## Тестирование Все тесты находятся в каталоге `tests/` (unit на бизнес-правила и интеграционные сценарии API). Запуск: ```bash uvx pytest ``` Полезные варианты: - Запустить только юнит-тесты сервисов: `uvx pytest tests/services -k service`. - Запустить конкретный сценарий API: `uvx pytest tests/api/v1/test_deals.py -k won`. Перед деплоем рекомендуется прогонять миграции на чистой БД и выполнять `uvx pytest` для проверки правил ролей/стадий. ## Линтинг и статический анализ - `uv run ruff check app tests` — основной линтер (PEP8, сортировка импортов, дополнительные правила). - `uv run ruff format app tests` — автоформатирование (аналог black) для единообразного стиля. - `uv run mypy app services tests` — статическая проверка типов (строгий режим + плагин pydantic). В CI/PR рекомендуется запускать команды именно в этом порядке, чтобы быстрее находить проблемы.