# SmoothSchedule - Multi-Tenant Scheduling Platform

A production-ready multi-tenant SaaS platform for resource scheduling, appointments, and business management.

## Features

- **Multi-Tenancy**: PostgreSQL schema-per-tenant using django-tenants
- **8-Tier Role Hierarchy**: SUPERUSER, PLATFORM_MANAGER, PLATFORM_SALES, PLATFORM_SUPPORT, TENANT_OWNER, TENANT_MANAGER, TENANT_STAFF, CUSTOMER
- **Modern Stack**: Django 5.2 + React 19 + TypeScript + Vite
- **Real-time Updates**: Django Channels + WebSockets
- **Background Tasks**: Celery + Redis
- **Auto SSL**: Let's Encrypt certificates via Traefik
- **Cloud Storage**: DigitalOcean Spaces (S3-compatible)
- **Docker Ready**: Complete Docker Compose setup for dev and production

## Project Structure

```
smoothschedule2/
├── frontend/                    # React + Vite + TypeScript
│   ├── src/
│   │   ├── api/                 # API client and hooks
│   │   ├── components/          # Reusable UI components
│   │   ├── hooks/               # React Query hooks
│   │   ├── pages/               # Page components
│   │   └── types.ts             # TypeScript interfaces
│   ├── nginx.conf               # Production nginx config
│   └── Dockerfile.prod          # Production frontend container
│
├── smoothschedule/              # Django backend
│   ├── config/                  # Django settings
│   │   └── settings/
│   │       ├── base.py          # Base settings
│   │       ├── local.py         # Local development
│   │       └── production.py    # Production settings
│   ├── smoothschedule/          # Django apps (domain-based)
│   │   ├── identity/            # Users, tenants, authentication
│   │   │   ├── core/            # Tenant, Domain, middleware
│   │   │   └── users/           # User model, MFA, auth
│   │   ├── scheduling/          # Core scheduling
│   │   │   ├── schedule/        # Resources, Events, Services
│   │   │   ├── contracts/       # E-signatures
│   │   │   └── analytics/       # Business analytics
│   │   ├── communication/       # Notifications, SMS, mobile
│   │   ├── commerce/            # Payments, tickets
│   │   └── platform/            # Admin, public API
│   ├── docker-compose.local.yml
│   └── docker-compose.production.yml
│
├── deploy.sh                    # Automated deployment script
└── CLAUDE.md                    # Development guide
```

---

## Local Development Setup

### Prerequisites

- **Docker** and **Docker Compose** (for backend)
- **Node.js 22+** and **npm** (for frontend)
- **Git**

### Step 1: Clone the Repository

```bash
git clone https://github.com/your-repo/smoothschedule.git
cd smoothschedule
```

### Step 2: Start the Backend (Django in Docker)

```bash
cd smoothschedule

# Start all backend services
docker compose -f docker-compose.local.yml up -d

# Wait for services to initialize (first time takes longer)
sleep 30

# Run database migrations
docker compose -f docker-compose.local.yml exec django python manage.py migrate

# Create a superuser (optional)
docker compose -f docker-compose.local.yml exec django python manage.py createsuperuser
```

### Step 3: Start the Frontend (React with Vite)

```bash
cd ../frontend

# Install dependencies
npm install

# Start development server
npm run dev
```

### Step 4: Access the Application

The application uses `lvh.me` (resolves to 127.0.0.1) for subdomain-based multi-tenancy:

| URL | Purpose |
|-----|---------|
| http://platform.lvh.me:5173 | Platform admin dashboard |
| http://demo.lvh.me:5173 | Demo tenant (if created) |
| http://lvh.me:8000/api/ | Backend API |
| http://lvh.me:8000/admin/ | Django admin |

**Why `lvh.me`?** Browsers don't allow cookies with `domain=.localhost`, but `lvh.me` resolves to 127.0.0.1 and allows proper cookie sharing across subdomains.

### Local Development Commands

```bash
# Backend commands (always use docker compose)
cd smoothschedule

# View logs
docker compose -f docker-compose.local.yml logs -f django

# Run migrations
docker compose -f docker-compose.local.yml exec django python manage.py migrate

# Django shell
docker compose -f docker-compose.local.yml exec django python manage.py shell

# Run tests
docker compose -f docker-compose.local.yml exec django pytest

# Stop all services
docker compose -f docker-compose.local.yml down

# Frontend commands
cd frontend

# Run tests
npm test

# Type checking
npm run typecheck

# Lint
npm run lint
```

### Creating a Test Tenant

```bash
cd smoothschedule
docker compose -f docker-compose.local.yml exec django python manage.py shell
```

```python
from smoothschedule.identity.core.models import Tenant, Domain

# Create tenant
tenant = Tenant.objects.create(
    name="Demo Business",
    schema_name="demo",
)

# Create domain
Domain.objects.create(
    domain="demo.lvh.me",
    tenant=tenant,
    is_primary=True,
)

print(f"Created tenant: {tenant.name}")
print(f"Access at: http://demo.lvh.me:5173")
```

---

## Production Deployment

### Prerequisites

- Ubuntu/Debian server with Docker and Docker Compose
- Domain name with DNS configured:
  - `A` record: `yourdomain.com` → Server IP
  - `A` record: `*.yourdomain.com` → Server IP (wildcard)
- SSH access to the server

### Quick Deploy (Existing Server)

For routine updates to an existing production server:

```bash
# From your local machine
./deploy.sh user@yourdomain.com

# Or deploy specific services
./deploy.sh user@yourdomain.com nginx
./deploy.sh user@yourdomain.com django
```

### Fresh Server Deployment

#### Step 1: Server Setup

SSH into your server and install Docker:

```bash
ssh user@yourdomain.com

# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

# Logout and login for group changes
exit
ssh user@yourdomain.com
```

#### Step 2: Clone Repository

```bash
cd ~
git clone https://github.com/your-repo/smoothschedule.git smoothschedule
cd smoothschedule
```

#### Step 3: Configure Environment Variables

Create production environment files:

```bash
mkdir -p smoothschedule/.envs/.production

# Django configuration
cat > smoothschedule/.envs/.production/.django << 'EOF'
DJANGO_SECRET_KEY=your-random-secret-key-here
DJANGO_DEBUG=False
DJANGO_ALLOWED_HOSTS=yourdomain.com,*.yourdomain.com

DJANGO_ADMIN_URL=your-secret-admin-path/
FRONTEND_URL=https://platform.yourdomain.com
PLATFORM_BASE_URL=https://platform.yourdomain.com

REDIS_URL=redis://redis:6379/0
CELERY_BROKER_URL=redis://redis:6379/0

# DigitalOcean Spaces (or S3)
DJANGO_AWS_ACCESS_KEY_ID=your-access-key
DJANGO_AWS_SECRET_ACCESS_KEY=your-secret-key
DJANGO_AWS_STORAGE_BUCKET_NAME=your-bucket
DJANGO_AWS_S3_ENDPOINT_URL=https://nyc3.digitaloceanspaces.com
DJANGO_AWS_S3_REGION_NAME=nyc3

# SSL
DJANGO_SECURE_SSL_REDIRECT=True
DJANGO_SESSION_COOKIE_SECURE=True
DJANGO_CSRF_COOKIE_SECURE=True

# Cloudflare (for wildcard SSL)
CF_DNS_API_TOKEN=your-cloudflare-api-token
EOF

# PostgreSQL configuration
cat > smoothschedule/.envs/.production/.postgres << 'EOF'
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=smoothschedule
POSTGRES_USER=smoothschedule_user
POSTGRES_PASSWORD=your-secure-database-password
EOF
```

#### Step 4: Build and Start

```bash
cd ~/smoothschedule/smoothschedule

# Build all images
docker compose -f docker-compose.production.yml build

# Start services
docker compose -f docker-compose.production.yml up -d

# Wait for startup
sleep 30

# Run migrations
docker compose -f docker-compose.production.yml exec django python manage.py migrate

# Collect static files
docker compose -f docker-compose.production.yml exec django python manage.py collectstatic --noinput

# Create superuser
docker compose -f docker-compose.production.yml exec django python manage.py createsuperuser
```

#### Step 5: Verify Deployment

```bash
# Check all containers are running
docker compose -f docker-compose.production.yml ps

# View logs
docker compose -f docker-compose.production.yml logs -f

# Test endpoints
curl https://yourdomain.com/api/health/
```

### Production URLs

| URL | Purpose |
|-----|---------|
| https://yourdomain.com | Marketing site |
| https://platform.yourdomain.com | Platform admin |
| https://*.yourdomain.com | Tenant subdomains |
| https://api.yourdomain.com | API (if configured) |
| https://yourdomain.com:5555 | Flower (Celery monitoring) |

### Production Management Commands

```bash
ssh user@yourdomain.com
cd ~/smoothschedule/smoothschedule

# View logs
docker compose -f docker-compose.production.yml logs -f django

# Restart services
docker compose -f docker-compose.production.yml restart

# Run migrations
docker compose -f docker-compose.production.yml exec django python manage.py migrate

# Django shell
docker compose -f docker-compose.production.yml exec django python manage.py shell

# Database backup
docker compose -f docker-compose.production.yml exec postgres pg_dump -U smoothschedule_user smoothschedule > backup.sql
```

---

## Architecture

### Multi-Tenancy Model

```
PostgreSQL Database
├── public (shared schema)
│   ├── Tenants
│   ├── Domains
│   ├── Users
│   └── PermissionGrants
├── demo (tenant schema)
│   ├── Resources
│   ├── Events
│   ├── Services
│   └── Customers
└── acme (tenant schema)
    ├── Resources
    ├── Events
    └── ...
```

### Role Hierarchy

| Role | Level | Access |
|------|-------|--------|
| SUPERUSER | Platform | All tenants (god mode) |
| PLATFORM_MANAGER | Platform | All tenants |
| PLATFORM_SALES | Platform | Demo accounts only |
| PLATFORM_SUPPORT | Platform | Can masquerade as tenant users |
| TENANT_OWNER | Tenant | Full tenant access |
| TENANT_MANAGER | Tenant | Most tenant features |
| TENANT_STAFF | Tenant | Limited tenant access |
| CUSTOMER | Tenant | Own data only |

### Request Flow

```
Browser → Traefik (SSL) → nginx (frontend) or django (API)
                              ↓
                         React SPA
                              ↓
                    /api/* → django:5000
                    /ws/*  → django:5000 (WebSocket)
```

---

## Configuration Files

### Backend

| File | Purpose |
|------|---------|
| `smoothschedule/docker-compose.local.yml` | Local Docker services |
| `smoothschedule/docker-compose.production.yml` | Production Docker services |
| `smoothschedule/.envs/.local/` | Local environment variables |
| `smoothschedule/.envs/.production/` | Production environment variables |
| `smoothschedule/config/settings/` | Django settings |
| `smoothschedule/compose/production/traefik/traefik.yml` | Traefik routing config |

### Frontend

| File | Purpose |
|------|---------|
| `frontend/.env.development` | Local environment variables |
| `frontend/.env.production` | Production environment variables |
| `frontend/nginx.conf` | Production nginx config |
| `frontend/vite.config.ts` | Vite bundler config |

---

## Troubleshooting

### Backend won't start

```bash
# Check Docker logs
docker compose -f docker-compose.local.yml logs django

# Common issues:
# - Database not ready: wait longer, then restart django
# - Missing migrations: run migrate command
# - Port conflict: check if 8000 is in use
```

### Frontend can't connect to API

```bash
# Verify backend is running
curl http://lvh.me:8000/api/

# Check CORS settings in Django
# Ensure CORS_ALLOWED_ORIGINS includes http://platform.lvh.me:5173
```

### WebSockets disconnecting

```bash
# Check nginx has /ws/ proxy configured
# Verify django is running ASGI (Daphne)
# Check production traefik/nginx logs
```

### Multi-tenant issues

```bash
# Check tenant exists
docker compose exec django python manage.py shell
>>> from smoothschedule.identity.core.models import Tenant, Domain
>>> Tenant.objects.all()
>>> Domain.objects.all()
```

---

## Additional Documentation

- **[CLAUDE.md](CLAUDE.md)** - Development guide, coding standards, architecture details
- **[DEPLOYMENT.md](DEPLOYMENT.md)** - Comprehensive deployment guide
- **[PRODUCTION_DEPLOYMENT.md](PRODUCTION_DEPLOYMENT.md)** - Step-by-step manual deployment

---

## License

MIT
