test_task_crm/README.md

167 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 <registry>/test-task-crm:app .
docker build -f migrations/Dockerfile -t <registry>/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://<host>:6379/0`
- (опционально) `ANALYTICS_CACHE_TTL_SECONDS` и `ANALYTICS_CACHE_BACKOFF_MS`.
3. При недоступности Redis сервис автоматически возвращается к прямым запросам в PostgreSQL и пишет предупреждения в лог.
## Тестирование
Все тесты находятся в каталоге `tests/` (unit на бизнес-правила и интеграционные сценарии API). Запуск:
```bash
uv run 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 рекомендуется запускать команды именно в этом порядке, чтобы быстрее находить проблемы.