# LeoCRM v1.0

> Self-hosted CRM for small sales teams (5–25 sales reps).
> Stack: FastAPI + SQLAlchemy (async) + PostgreSQL + Redis + Alpine.js + Tailwind + Docker + Coolify

## Quick Start (Development)

### 1. Clone and Setup

```bash
git clone <repo-url> leocrm
cd leocrm

# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate

# Install dependencies
pip install -r requirements.txt -r requirements-dev.txt
```

### 2. Configure Environment

```bash
cp .env.example .env

# Generate a secure SECRET_KEY (min 32 chars)
python3 -c "import secrets; print('SECRET_KEY=' + secrets.token_urlsafe(48))" >> .env

# Edit .env and set DATABASE_URL, REDIS_URL, SECRET_KEY
nano .env
```

### 3. Initialize Database

```bash
# Apply migrations
alembic upgrade head
```

### 4. Run Server

```bash
# Development with auto-reload
uvicorn app.main:app --reload --port 8000

# Start ARQ worker (for background jobs)
arq app.core.jobs.WorkerSettings
```

Open:
- API: http://localhost:8000
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- Health: http://localhost:8000/api/v1/health
- Metrics: http://localhost:8000/api/v1/metrics (admin-only)

## Production Setup

### Docker Compose

```bash
cp .env.example .env
# Edit .env — set DATABASE_URL, REDIS_URL, SECRET_KEY, CORS_ORIGINS
# Set ENVIRONMENT=production, SESSION_COOKIE_SECURE=true
docker compose up -d

# Run migrations
docker compose exec api alembic upgrade head
```

### Manual (without Docker)

```bash
pip install -r requirements.txt
alembic upgrade head

# Start API server (2 workers)
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 2

# Start ARQ worker (separate process)
arq app.core.jobs.WorkerSettings
```

See [docs/admin-guide.md](docs/admin-guide.md) for detailed deployment, backup, and troubleshooting instructions.

## API

### Key Endpoints

| Endpoint | Method | Auth | Description |
|---|---|---|---|
| `/api/v1/health` | GET | No | Health check (DB, Redis, storage, worker) |
| `/api/v1/metrics` | GET | Admin | Prometheus metrics (text/plain) |
| `/api/v1/auth/login` | POST | No | Login |
| `/api/v1/contacts` | GET | Yes | List contacts (paginated, max page_size=100) |
| `/api/v1/contacts/export` | GET | Yes | Stream contacts as CSV |
| `/api/v1/companies` | GET | Yes | List companies (paginated, max page_size=100) |
| `/api/v1/companies/export` | GET | Yes | Stream companies as CSV |

### Pagination

All list endpoints support pagination with `page` and `page_size` parameters.
`page_size` is capped at **100** — values >100 return HTTP 422.

### CSV Export

Contacts and companies support streaming CSV export via `/export?format=csv`.
Uses `StreamingResponse` — does not buffer the entire file in memory.

### Swagger UI

Interactive API documentation: http://localhost:8000/docs

See [docs/api-overview.md](docs/api-overview.md) for the full endpoint summary.

## Monitoring

### Health Check

```bash
curl http://localhost:8000/api/v1/health
```

Returns JSON with overall status (`healthy`/`degraded`) and individual checks for
`database`, `redis`, `storage`, and `worker`.

### Prometheus Metrics

```bash
# Requires admin authentication
curl -b "leocrm_session=<session>" http://localhost:8000/api/v1/metrics
```

Available metrics:
- `leocrm_http_requests_total` — Total HTTP requests
- `leocrm_http_request_duration_seconds` — Request duration histogram
- `leocrm_db_pool_connections` — Database connection pool size
- `leocrm_arq_jobs_total` — Total ARQ background jobs

### Structured Logging

LeoCRM uses `structlog` for structured JSON logging. All API requests are logged with:
`timestamp`, `level`, `event`, `method`, `path`, `status`, `duration_ms`, `tenant_id`.

## Environment Profiles

| Profile | `ENVIRONMENT` | Use Case |
|---|---|---|
| Development | `development` | Local dev (auto-reload, verbose logging) |
| Testing | `testing` | Test suite (separate test DB, minimal logging) |
| Production | `production` | Docker/Coolify deployment (JSON logging, secure cookies) |

See [docs/admin-guide.md](docs/admin-guide.md#environment-profiles) for profile details.

## Testing

```bash
# Run all tests
pytest -v --tb=short

# Run specific test suites
pytest tests/test_monitoring.py tests/test_performance.py tests/test_health.py -v

# Run with coverage
pytest --cov=app --cov-report=term-missing
```

## Environment Variables

See [.env.example](.env.example) for all variables and [docs/admin-guide.md](docs/admin-guide.md#environment-configuration) for detailed descriptions.

### Key Variables

| Variable | Required | Description |
|---|---|---|
| `DATABASE_URL` | ✅ | PostgreSQL async connection URL |
| `REDIS_URL` | ✅ | Redis connection URL |
| `SECRET_KEY` | ✅ | Secret key for signing (≥32 chars in prod) |
| `CORS_ORIGINS` | ✅ | Comma-separated allowed origins (no wildcards) |
| `ENVIRONMENT` | ❌ | `development` \| `testing` \| `production` |
| `STORAGE_PATH` | ❌ | File storage path (default: `/tmp`) |
| `SMTP_HOST` | ❌ | SMTP server hostname |

## Performance Testing

```bash
# Seed 200k contacts for performance testing
python scripts/seed_perf_data.py --count 200000

# Verify database indexes
python scripts/check_indexes.py

# Test pagination performance
# GET /api/v1/contacts?page=1&page_size=25 — should be <500ms with 200k records
```

## Project Structure

```
leocrm/
├── app/
│   ├── main.py               # FastAPI entry point with logging middleware
│   ├── config.py             # Pydantic settings
│   ├── core/
│   │   ├── monitoring.py      # Prometheus metrics + structured logging + health checks
│   │   ├── db.py             # Async database engine
│   │   ├── middleware.py     # CSRF middleware
│   │   └── ...
│   ├── routes/
│   │   ├── health.py         # Health endpoint
│   │   ├── metrics.py        # Prometheus metrics endpoint (admin-only)
│   │   ├── contacts.py       # Contact CRUD + streaming CSV export
│   │   ├── companies.py      # Company CRUD + streaming CSV export
│   │   └── ...
│   ├── models/               # SQLAlchemy models
│   ├── schemas/              # Pydantic schemas
│   ├── services/             # Business logic
│   └── plugins/              # Plugin system
├── scripts/
│   ├── seed_perf_data.py     # Performance test data seeding
│   └── check_indexes.py      # Database index verification
├── tests/                    # Test suite (pytest + pytest-asyncio)
├── docs/
│   ├── admin-guide.md       # Admin guide (deploy, backup, restore, troubleshooting)
│   └── api-overview.md      # API endpoint summary
├── alembic/                  # Database migrations
├── requirements.txt          # Production dependencies
├── requirements-dev.txt     # Test/lint dependencies
├── .env.example              # Environment template
├── docker-compose.yml        # Docker Compose
└── README.md                # This file
```

## Documentation

- [Admin Guide](docs/admin-guide.md) — Deployment, backup, restore, env vars, troubleshooting
- [API Overview](docs/api-overview.md) — Full endpoint reference
- [Coolify Setup](COOLIFY_SETUP.md) — Coolify deployment instructions
- [Swagger UI](http://localhost:8000/docs) — Interactive API docs (auto-generated)

## License

Internal project – proprietary.
