- Add comprehensive TDD documentation to CLAUDE.md with coverage requirements and examples - Extract reusable UI components to frontend/src/components/ui/ (Modal, FormInput, Button, Alert, etc.) - Add shared constants (schedulePresets) and utility hooks (useCrudMutation, useFormValidation) - Update frontend/CLAUDE.md with component documentation and usage examples - Refactor CreateTaskModal to use shared components and constants - Fix test assertions to be more robust and accurate across all test files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
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
git clone https://github.com/your-repo/smoothschedule.git
cd smoothschedule
Step 2: Start the Backend (Django in Docker)
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)
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
# 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
cd smoothschedule
docker compose -f docker-compose.local.yml exec django python manage.py shell
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:
Arecord:yourdomain.com→ Server IPArecord:*.yourdomain.com→ Server IP (wildcard)
- SSH access to the server
Quick Deploy (Existing Server)
For routine updates to an existing production server:
# 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:
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
cd ~
git clone https://github.com/your-repo/smoothschedule.git smoothschedule
cd smoothschedule
Step 3: Configure Environment Variables
Create production environment files:
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
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
# 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
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
# 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
# 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
# Check nginx has /ws/ proxy configured
# Verify django is running ASGI (Daphne)
# Check production traefik/nginx logs
Multi-tenant issues
# 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 - Development guide, coding standards, architecture details
- DEPLOYMENT.md - Comprehensive deployment guide
- PRODUCTION_DEPLOYMENT.md - Step-by-step manual deployment
License
MIT
Description
Languages
TypeScript
58.2%
Python
21.8%
HTML
18.8%
JavaScript
0.4%
Shell
0.3%
Other
0.4%