# 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