feat: add .env.example file with environment variable configurations
This commit is contained in:
parent
dcd8bd30f6
commit
eecb74c523
|
|
@ -0,0 +1,31 @@
|
||||||
|
# --- Core metadata --------------------------------------------------------
|
||||||
|
PROJECT_NAME="Test Task CRM"
|
||||||
|
VERSION="0.1.0"
|
||||||
|
API_V1_PREFIX="/api/v1"
|
||||||
|
|
||||||
|
# --- Database (used when DATABASE_URL не задан) ---------------------------
|
||||||
|
DB_HOST="localhost"
|
||||||
|
DB_PORT="5432"
|
||||||
|
DB_NAME="test_task_crm"
|
||||||
|
DB_USER="postgres"
|
||||||
|
DB_PASSWORD="postgres"
|
||||||
|
# DATABASE_URL="postgresql+asyncpg://postgres:postgres@localhost:5432/test_task_crm"
|
||||||
|
|
||||||
|
# --- SQLAlchemy -----------------------------------------------------------
|
||||||
|
SQLALCHEMY_ECHO="false"
|
||||||
|
|
||||||
|
# --- JWT -----------------------------------------------------------------
|
||||||
|
JWT_SECRET_KEY="change-me"
|
||||||
|
JWT_ALGORITHM="HS256"
|
||||||
|
ACCESS_TOKEN_EXPIRE_MINUTES="30"
|
||||||
|
REFRESH_TOKEN_EXPIRE_DAYS="7"
|
||||||
|
|
||||||
|
# --- Redis cache for analytics -------------------------------------------
|
||||||
|
REDIS_ENABLED="false"
|
||||||
|
REDIS_URL="redis://localhost:6379/0"
|
||||||
|
ANALYTICS_CACHE_TTL_SECONDS="120"
|
||||||
|
ANALYTICS_CACHE_BACKOFF_MS="200"
|
||||||
|
|
||||||
|
# --- Frontend (Vite exposes только VITE_*) --------------------------------
|
||||||
|
VITE_API_URL="http://localhost:8000"
|
||||||
|
VITE_APP_URL="http://localhost:5173"
|
||||||
174
README.md
174
README.md
|
|
@ -1,40 +1,160 @@
|
||||||
# Test Task CRM
|
# Test Task CRM
|
||||||
|
|
||||||
FastAPI backend template that follows the architecture described in the system prompt: async SQLAlchemy ORM, Alembic-ready models, service/repository layers, JWT auth helpers, and Pydantic v2 schemas.
|
Многопользовательская mini-CRM на FastAPI + PostgreSQL c сервисно-репозиторной архитектурой, JWT-аутентификацией, Alembic-миграциями и готовым React/Vite фронтендом.
|
||||||
|
|
||||||
## Quick start
|
## Стек и особенности
|
||||||
|
|
||||||
1. Create a `.env` file based on variables in `app/core/config.py`.
|
- Python 3.10+, FastAPI, SQLAlchemy Async ORM, Alembic.
|
||||||
2. Install dependencies:
|
- Pydantic Settings для конфигурации, JWT access/refresh токены, кеш аналитики в Redis.
|
||||||
```bash
|
- Frontend: Vite + React + TypeScript (см. `frontend/`).
|
||||||
uv sync
|
- Докер-окружение для разработки (`docker-compose-dev.yml`) и деплоя (`docker-compose-ci.yml`).
|
||||||
```
|
|
||||||
3. Run the development server:
|
|
||||||
```bash
|
|
||||||
uv run python main.py
|
|
||||||
```
|
|
||||||
|
|
||||||
## Project layout
|
## Структура проекта
|
||||||
|
|
||||||
```
|
```text
|
||||||
app/
|
app/
|
||||||
api/ # FastAPI routers and dependencies
|
api/ # FastAPI-роуты и зависимости
|
||||||
core/ # Settings, database, security helpers
|
core/ # Настройки, база, безопасность
|
||||||
models/ # SQLAlchemy models and Pydantic schemas
|
models/ # SQLAlchemy-модели
|
||||||
repositories/ # Data access layer (SQLAlchemy ORM usage)
|
repositories/ # Работа с БД
|
||||||
services/ # Business logic (auth, users, etc.)
|
services/ # Бизнес-правила и сценарии
|
||||||
|
frontend/ # Vite + React SPA
|
||||||
|
migrations/ # Alembic-миграции
|
||||||
|
tests/ # Pytest (unit + интеграции)
|
||||||
```
|
```
|
||||||
|
|
||||||
Add new routers under `app/api/v1`, repositories under `app/repositories`, and keep business rules inside `app/services`.
|
## Переменные окружения
|
||||||
|
|
||||||
## Redis analytics cache
|
1. Скопируйте шаблон: `cp .env.example .env`.
|
||||||
|
2. Обновите секреты (`DB_PASSWORD`, `JWT_SECRET_KEY`, и т.д.) перед запуском.
|
||||||
|
3. Все переменные описаны в `app/core/config.py`; Vite читает только ключи с префиксом `VITE_`.
|
||||||
|
|
||||||
Analytics endpoints can use a Redis cache (TTL 120 seconds). The cache is disabled by default, so the service falls back to the database.
|
### 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. Применяем миграции
|
||||||
|
uv run alembic upgrade head
|
||||||
|
|
||||||
|
# 4. Запускаем API
|
||||||
|
uv run 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
|
||||||
|
```
|
||||||
|
|
||||||
|
Полезные варианты:
|
||||||
|
|
||||||
|
- Запустить только юнит-тесты сервисов: `uv run pytest tests/services -k service`.
|
||||||
|
- Запустить конкретный сценарий API: `uv run pytest tests/api/v1/test_deals.py -k won`.
|
||||||
|
|
||||||
|
Перед деплоем рекомендуется прогонять миграции на чистой БД и выполнять `uv run pytest` для проверки правил ролей/стадий.
|
||||||
|
|
||||||
1. Start Redis and set the following variables:
|
|
||||||
- `REDIS_ENABLED=true`
|
|
||||||
- `REDIS_URL=redis://localhost:6379/0`
|
|
||||||
- `ANALYTICS_CACHE_TTL_SECONDS` (optional, defaults to 120)
|
|
||||||
- `ANALYTICS_CACHE_BACKOFF_MS` (max delay for write/delete retries, defaults to 200)
|
|
||||||
2. When Redis becomes unavailable, middleware logs the degradation and responses transparently fall back to database queries until connectivity is restored.
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue