From fc3ad9e04c5f6aedd1a3b484d52a121ea679f525 Mon Sep 17 00:00:00 2001 From: Leopoldadmin Date: Wed, 3 Jun 2026 23:51:59 +0000 Subject: [PATCH] Upload README.md --- README.md | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..9ffddb1 --- /dev/null +++ b/README.md @@ -0,0 +1,143 @@ +# CRM System v1.0 + +> Self-hosted CRM for small sales teams (5–25 sales reps). +> Stack: FastAPI + SQLAlchemy (async) + Alembic + Pydantic v2 + SQLite/PostgreSQL + Alpine.js + Tailwind + Docker + Coolify + +## Quick Start (Development) + +### 1. Clone and Setup + +```bash +git clone crm-system +cd crm-system + +# 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 +# Copy template +cp .env.example .env + +# Generate a secure AUTH_SECRET (min 32 chars) +python3 -c "import secrets; print('AUTH_SECRET=' + secrets.token_urlsafe(48))" >> .env + +# Edit .env and set AUTH_SECRET (remove the placeholder line first) +``` + +### 3. Initialize Database + +```bash +# Apply migrations +alembic upgrade head + +# (Optional) Create migration after model changes +# alembic revision --autogenerate -m "description" +``` + +### 4. Run Server + +```bash +# Development with auto-reload +uvicorn app.main:app --reload --port 8000 + +# Production-like +uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 2 +``` + +Open: +- API: http://localhost:8000 +- Swagger UI: http://localhost:8000/docs +- ReDoc: http://localhost:8000/redoc +- Health: http://localhost:8000/health + +### 5. Bootstrap First User + +```bash +curl -X POST http://localhost:8000/api/v1/auth/register \ + -H "Content-Type: application/json" \ + -d '{ + "email": "admin@example.com", + "password": "secure-password-123", + "name": "First Admin" + }' +``` + +This creates the first user + a default org. After that, registration is disabled (use admin invite flow in v1.1). + +## Project Structure + +``` +crm-system/ +├── app/ # Application package +│ ├── main.py # FastAPI entry point +│ ├── core/ # Core modules (config, db, security, deps) +│ ├── models/ # SQLAlchemy models +│ ├── schemas/ # Pydantic schemas (request/response) +│ ├── services/ # Business logic layer +│ ├── api/v1/ # API routers (versioned) +│ └── webui/ # Static frontend (Phase 4c) +├── alembic/ # Database migrations +│ ├── env.py # Async migration environment +│ └── versions/ # Migration scripts +├── tests/ # Test suite (pytest + pytest-asyncio) +├── requirements.txt # Production dependencies +├── requirements-dev.txt # Test/lint dependencies +├── pyproject.toml # Tool configuration +├── alembic.ini # Alembic configuration +├── .env.example # Environment template +└── README.md +``` + +## Testing + +```bash +# Run all tests +pytest -v --tb=short + +# Run with coverage +pytest --cov=app --cov-report=term-missing + +# Run specific test file +pytest tests/test_auth.py -v + +# Stop on first failure (for debugging) +pytest -x +``` + +## Environment Variables + +| Variable | Required | Default | Description | +|---|---|---|---| +| `AUTH_SECRET` | ✅ | – | JWT signing secret (≥32 chars). Hard-fail if missing. | +| `DATABASE_URL` | ❌ | `sqlite+aiosqlite:///./dev.db` | Async DB URL (aiosqlite or asyncpg) | +| `JWT_ALGORITHM` | ❌ | `HS256` | JWT algorithm | +| `JWT_EXPIRY_HOURS` | ❌ | `24` | Token lifetime | +| `BCRYPT_ROUNDS` | ❌ | `12` | Password hashing cost | +| `CORS_ORIGINS` | ❌ | `http://localhost:5500,http://localhost:8000` | Allowed origins (comma-separated, NO wildcards) | +| `ENVIRONMENT` | ❌ | `development` | `development` or `production` | +| `LOG_LEVEL` | ❌ | `INFO` | Python log level | + +## Architecture Decisions (ADR) + +- **JWT Library**: `python-jose[cryptography]==3.3.0` (pattern reuse from wochenplaner) +- **Database**: SQLite (aiosqlite) for dev, PostgreSQL (asyncpg) for prod +- **Auth**: Stateless JWT in localStorage, bcrypt password hashing (12 rounds) +- **Security**: CORS whitelist (no wildcard), CSP middleware, no default admin user +- **Async**: All routers/services/DB operations are async (SQLAlchemy 2.0 + aiosqlite) + +See `/a0/.a0/02-architecture.md` Section 13 for full lockdown decisions. + +## Deployment + +See `/a0/.a0/03-task-graph.json` Phase 4d for Docker + Coolify setup (out of scope for Phase 4a). + +## License + +Internal project – proprietary.