# SmoothSchedule - Multi-Tenant Scheduling Platform

A production-ready multi-tenant SaaS platform for resource scheduling and orchestration.

## 🎯 Features

- ✅ **Multi-Tenancy**: PostgreSQL schema-per-tenant using django-tenants
- ✅ **8-Tier Role Hierarchy**: From SUPERUSER to CUSTOMER with strict permissions
- ✅ **Modern Stack**: Django 5.2 + React 18 + Vite
- ✅ **Docker Ready**: Complete production & development Docker Compose setup
- ✅ **Cloud Storage**: DigitalOcean Spaces (S3-compatible) for static/media files
- ✅ **Auto SSL**: Let's Encrypt certificates via Traefik reverse proxy
- ✅ **Task Queue**: Celery + Redis for background jobs
- ✅ **Real-time**: Django Channels + WebSockets support
- ✅ **Production Ready**: Fully configured for deployment

## 📚 Documentation

- **[PRODUCTION_DEPLOYMENT.md](PRODUCTION_DEPLOYMENT.md)** - **Manual step-by-step production deployment** (start here for fresh deployments)
- **[QUICK-REFERENCE.md](QUICK-REFERENCE.md)** - Common commands and quick start
- **[PRODUCTION-READY.md](PRODUCTION-READY.md)** - Production deployment status
- **[DEPLOYMENT.md](DEPLOYMENT.md)** - Comprehensive deployment guide
- **[CLAUDE.md](CLAUDE.md)** - Development guide and architecture

## 🚀 Quick Start

### Local Development

```bash
# Start backend (Django in Docker)
cd smoothschedule
docker compose -f docker-compose.local.yml up -d

# Start frontend (React with Vite)
cd ../frontend
npm install
npm run dev

# Access the app
# Frontend: http://platform.lvh.me:5173
# Backend API: http://lvh.me:8000/api
```

See [CLAUDE.md](CLAUDE.md) for detailed development instructions.

### Production Deployment

For **fresh deployments or complete reset**, follow [PRODUCTION_DEPLOYMENT.md](PRODUCTION_DEPLOYMENT.md) for manual step-by-step instructions.

For **routine updates**, use the automated script:

```bash
# Deploy to production server (code changes only)
./deploy.sh poduck@smoothschedule.com
```

See [PRODUCTION-READY.md](PRODUCTION-READY.md) for deployment checklist and [DEPLOYMENT.md](DEPLOYMENT.md) for detailed steps.

## 🏗️ Architecture

### Multi-Tenancy Model

```
┌─────────────────────────────────────────┐
│         PostgreSQL Database             │
├─────────────────────────────────────────┤
│ public (shared schema)                  │
│  ├─ Tenants                             │
│  ├─ Domains                             │
│  ├─ Users                               │
│  └─ PermissionGrants                    │
├─────────────────────────────────────────┤
│ tenant_demo (schema for Demo Company)   │
│  ├─ Appointments                        │
│  ├─ Resources                           │
│  └─ Customers                           │
├─────────────────────────────────────────┤
│ tenant_acme (schema for Acme Corp)      │
│  ├─ Appointments                        │
│  ├─ Resources                           │
│  └─ Customers                           │
└─────────────────────────────────────────┘
```

### Role Hierarchy

| Role                | Level    | Access Scope              |
|---------------------|----------|---------------------------|
| SUPERUSER           | Platform | All tenants (god mode)    |
| PLATFORM_MANAGER    | Platform | All tenants               |
| PLATFORM_SALES      | Platform | Demo accounts only        |
| PLATFORM_SUPPORT    | Platform | Tenant users              |
| TENANT_OWNER        | Tenant   | Own tenant (full access)  |
| TENANT_MANAGER      | Tenant   | Own tenant                |
| TENANT_STAFF        | Tenant   | Own tenant (limited)      |
| CUSTOMER            | Tenant   | Own data only             |

### Masquerading Matrix

| Hijacker Role      | Can Masquerade As                |
|--------------------|----------------------------------|
| SUPERUSER          | Anyone                           |
| PLATFORM_SUPPORT   | Tenant users                     |
| PLATFORM_SALES     | Demo accounts (`is_temporary=True`) |
| TENANT_OWNER       | Staff in same tenant             |
| Others             | No one                           |

**Security Rules:**
- Cannot hijack yourself
- Cannot hijack SUPERUSERs (except by other SUPERUSERs)
- Maximum depth: 1 (no hijack chains)
- All attempts logged to `logs/masquerade.log`

## 📁 Project Structure

```
smoothschedule/
├── config/
│   └── settings.py          # Multi-tenancy & security config
├── core/
│   ├── models.py            # Tenant, Domain, PermissionGrant
│   ├── permissions.py       # Hijack permission matrix
│   ├── middleware.py        # Masquerade audit logging
│   └── admin.py             # Django admin for core models
├── users/
│   ├── models.py            # Custom User with 8-tier roles
│   └── admin.py             # User admin with hijack button
├── logs/
│   ├── security.log         # General security events
│   └── masquerade.log       # Hijack activity (JSON)
└── setup_project.sh         # Automated setup script
```

## 🔐 Security Features

### Audit Logging

All masquerade activity is logged in JSON format:

```json
{
  "timestamp": "2024-01-15T10:30:00Z",
  "action": "HIJACK_START",
  "hijacker_email": "support@smoothschedule.com",
  "hijacked_email": "customer@demo.com",
  "ip_address": "192.168.1.1",
  "session_key": "abc123..."
}
```

### Permission Grants (30-Minute Window)

Time-limited elevated permissions:

```python
from core.models import PermissionGrant

grant = PermissionGrant.create_grant(
    grantor=admin_user,
    grantee=support_user,
    action="view_billing",
    reason="Customer requested billing support",
    duration_minutes=30,
)

# Check if active
if grant.is_active():
    # Perform privileged action
    pass
```

## 🧪 Testing Masquerading

1. Access Django Admin: `http://localhost:8000/admin/`
2. Create test users with different roles
3. Click "Hijack" button next to a user
4. Verify audit logs: `docker-compose exec django cat logs/masquerade.log`

## 📊 Admin Interface

- **Tenant Management**: View tenants, domains, subscription tiers
- **User Management**: Color-coded roles, masquerade buttons
- **Permission Grants**: Active/expired/revoked status, bulk revoke
- **Domain Verification**: AWS Route53 integration status

## 🛠️ Development

### Adding Tenant Apps

Edit `config/settings.py`:

```python
TENANT_APPS = [
    'django.contrib.contenttypes',
    'appointments',   # Your app
    'resources',      # Your app
    'billing',        # Your app
]
```

### Custom Domain Setup

```python
domain = Domain.objects.create(
    domain="app.customdomain.com",
    tenant=tenant,
    is_custom_domain=True,
    route53_zone_id="Z1234567890ABC",
)
```

Then configure Route53 CNAME: `app.customdomain.com` → `smoothschedule.yourhost.com`

## 📖 Key Files Reference

| File | Purpose |
|------|---------|
| `setup_project.sh` | Automated project initialization |
| `config/settings.py` | Multi-tenancy, middleware, security config |
| `core/models.py` | Tenant, Domain, PermissionGrant models |
| `core/permissions.py` | Masquerading permission matrix |
| `core/middleware.py` | Audit logging for masquerading |
| `users/models.py` | Custom User with 8-tier roles |

## 📝 Important Notes

- **Django Admin**: The ONLY HTML interface (everything else is API)
- **Middleware Order**: `TenantMainMiddleware` must be first, `MasqueradeAuditMiddleware` after `HijackUserMiddleware`
- **Tenant Isolation**: Each tenant's data is in a separate PostgreSQL schema
- **Production**: Update `SECRET_KEY`, database credentials, and AWS keys via environment variables

## 🐛 Troubleshooting

**Cannot create tenant users:**
- Error: "Users with role TENANT_STAFF must be assigned to a tenant"
- Solution: Set `user.tenant = tenant_instance` before saving

**Hijack button doesn't appear:**
- Check `HIJACK_AUTHORIZATION_CHECK` in settings
- Verify `HijackUserAdminMixin` in `users/admin.py`
- Ensure user has permission per matrix rules

**Migrations fail:**
- Run shared migrations first: `migrate_schemas --shared`
- Then run tenant migrations: `migrate_schemas`

## 📄 License

MIT

## 🤝 Contributing

This is a production skeleton. Extend `TENANT_APPS` with your business logic.

---

**Built with ❤️ for multi-tenant SaaS perfection**
