# Deployment Guide - LOAF Membership Platform ## Fresh Database Installation Follow these steps in order for a **brand new deployment**: ### Step 1: Create PostgreSQL Database ```bash # Connect to PostgreSQL psql -U postgres # Create database CREATE DATABASE membership_db; # Create user (if needed) CREATE USER loaf_admin WITH PASSWORD 'your-secure-password'; GRANT ALL PRIVILEGES ON DATABASE membership_db TO loaf_admin; # Exit PostgreSQL \q ``` ### Step 2: Run Initial Schema ```bash cd backend # Apply the complete schema (creates all 17 tables, 8 enums, indexes) psql -U loaf_admin -d membership_db -f migrations/000_initial_schema.sql ``` **What this creates:** - ✅ 17 tables: users, events, subscriptions, roles, permissions, etc. - ✅ 8 custom enums: UserStatus, UserRole, RSVPStatus, etc. - ✅ All indexes and foreign keys - ✅ All constraints and defaults ### Step 3: Mark Database for Alembic Tracking ```bash # Mark the database as being at the baseline alembic stamp head ``` ### Step 4: Verify Setup ```bash # Check Alembic status alembic current # Expected output: 001_initial_baseline (head) # Check database tables psql -U loaf_admin -d membership_db -c "\dt" # Should show 17 tables ``` ### Step 5: Set Environment Variables Create `backend/.env`: ```env # Database DATABASE_URL=postgresql://loaf_admin:your-password@localhost:5432/membership_db # JWT JWT_SECRET=your-secret-key-minimum-32-characters-long JWT_ALGORITHM=HS256 ACCESS_TOKEN_EXPIRE_MINUTES=30 # Email (SMTP) SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USERNAME=your-email@gmail.com SMTP_PASSWORD=your-app-password SMTP_FROM_EMAIL=noreply@loafmembers.org SMTP_FROM_NAME=LOAF Membership # Frontend URL FRONTEND_URL=https://members.loafmembers.org # Cloudflare R2 R2_ENDPOINT_URL=https://your-account-id.r2.cloudflarestorage.com R2_ACCESS_KEY_ID=your-r2-access-key R2_SECRET_ACCESS_KEY=your-r2-secret-key R2_BUCKET_NAME=loaf-membership R2_PUBLIC_URL=https://cdn.loafmembers.org # Stripe STRIPE_SECRET_KEY=sk_live_... STRIPE_WEBHOOK_SECRET=whsec_... STRIPE_PRICE_ID_ANNUAL=price_... STRIPE_PRICE_ID_GROUP=price_... ``` ### Step 6: Install Dependencies ```bash # Backend cd backend pip install -r requirements.txt # Frontend cd ../frontend yarn install ``` ### Step 7: Start Services ```bash # Backend (in backend/) uvicorn server:app --host 0.0.0.0 --port 8000 # Frontend (in frontend/) yarn start ``` ### Step 8: Create First Superadmin User ```bash # Connect to database psql -U loaf_admin -d membership_db # Create superadmin user INSERT INTO users ( id, email, password_hash, first_name, last_name, status, role, email_verified, created_at, updated_at ) VALUES ( gen_random_uuid(), 'admin@loafmembers.org', '$2b$12$your-bcrypt-hashed-password-here', -- Use bcrypt to hash password 'Admin', 'User', 'active', 'superadmin', true, NOW(), NOW() ); ``` **Generate password hash:** ```python import bcrypt password = b"your-secure-password" hashed = bcrypt.hashpw(password, bcrypt.gensalt()) print(hashed.decode()) ``` --- ## Existing Database Update For **updating an existing deployment** with new code: ### Step 1: Backup Database ```bash pg_dump -U loaf_admin membership_db > backup_$(date +%Y%m%d_%H%M%S).sql ``` ### Step 2: Pull Latest Code ```bash git pull origin main ``` ### Step 3: Install New Dependencies ```bash # Backend cd backend pip install -r requirements.txt # Frontend cd ../frontend yarn install ``` ### Step 4: Apply Database Migrations ```bash cd backend # Check current migration status alembic current # Apply pending migrations alembic upgrade head # Verify alembic current ``` ### Step 5: Restart Services ```bash # Restart backend systemctl restart membership-backend # Rebuild and restart frontend cd frontend yarn build systemctl restart membership-frontend ``` --- ## First-Time Alembic Setup (Existing Database) If you have an **existing database** that was created with `000_initial_schema.sql` but hasn't been marked for Alembic tracking: ```bash cd backend # Mark database as being at the baseline (one-time only) alembic stamp head # Verify alembic current # Expected output: 001_initial_baseline (head) ``` --- ## Database Schema Verification **Check all tables exist:** ```bash psql -U loaf_admin -d membership_db -c "\dt" ``` **Expected tables (17 total):** - users - events - event_rsvps - subscriptions - subscription_plans - permissions - roles - role_permissions - user_invitations - import_jobs - import_rollback_audit - event_galleries - newsletter_archives - financial_reports - bylaws_documents - donations - storage_usage **Check enums:** ```bash psql -U loaf_admin -d membership_db -c "\dT" ``` **Expected enums (8 total):** - userstatus - userrole - rsvpstatus - subscriptionstatus - donationtype - donationstatus - invitationstatus - importjobstatus --- ## Rollback Procedures ### Rollback Last Migration ```bash cd backend alembic downgrade -1 ``` ### Rollback to Specific Revision ```bash alembic downgrade ``` ### Complete Database Reset ```bash # WARNING: This deletes ALL data! # 1. Backup first pg_dump -U loaf_admin membership_db > emergency_backup.sql # 2. Drop database dropdb membership_db # 3. Recreate database createdb membership_db # 4. Run initial schema psql -U loaf_admin -d membership_db -f backend/migrations/000_initial_schema.sql # 5. Mark for Alembic cd backend alembic stamp head ``` --- ## Troubleshooting ### "relation does not exist" error The database wasn't initialized properly. **Solution:** ```bash psql -U loaf_admin -d membership_db -f backend/migrations/000_initial_schema.sql alembic stamp head ``` ### "Target database is not up to date" Migrations haven't been applied. **Solution:** ```bash cd backend alembic upgrade head ``` ### "Can't locate revision" Alembic tracking is out of sync. **Solution:** ```bash # Check what revision the database thinks it's at alembic current # If empty or wrong, manually set it alembic stamp head ``` ### Database connection errors Check `.env` file has correct `DATABASE_URL`. **Format:** ``` DATABASE_URL=postgresql://username:password@host:port/database ``` --- ## Production Checklist Before going live: - [ ] Database created and schema applied - [ ] Alembic marked as up-to-date (`alembic current` shows baseline) - [ ] All environment variables set in `.env` - [ ] Dependencies installed (Python + Node) - [ ] Superadmin user created - [ ] SSL certificates configured - [ ] Backup system in place - [ ] Monitoring configured - [ ] Domain DNS pointing to server - [ ] Email sending verified (SMTP working) - [ ] Stripe webhook endpoint configured - [ ] R2 bucket accessible and CORS configured --- ## Support For issues: 1. Check logs: `tail -f backend/logs/app.log` 2. Check Alembic status: `alembic current` 3. Verify environment variables: `cat backend/.env` 4. Test database connection: `psql -U loaf_admin -d membership_db`