# Deployment Guide - Dynamic RBAC System This guide covers deploying the dynamic Role-Based Access Control (RBAC) system to your dev server. ## Overview The RBAC migration consists of 4 phases: - **Phase 1**: Add new database tables and columns (schema changes) - **Phase 2**: Seed system roles - **Phase 3**: Migrate existing data - **Phase 4**: System is fully operational with dynamic roles ## Prerequisites - Database backup completed ✓ - PostgreSQL access credentials - Python 3.8+ environment - All dependencies installed (`pip install -r requirements.txt`) --- ## Step-by-Step Deployment ### Step 1: Run Schema Migration (Phase 1) This creates the new `roles` table and adds `role_id` columns to `users` and `role_permissions` tables. ```bash # Connect to your database psql -U -d -f migrations/006_add_dynamic_roles.sql ``` **What this does:** - Creates `roles` table - Adds `role_id` column to `users` (nullable) - Adds `role_id` column to `role_permissions` (nullable) - Legacy `role` enum columns remain for backward compatibility **Expected output:** ``` Step 1 completed: roles table created Step 2 completed: role_id column added to users table Step 3 completed: role_id column added to role_permissions table Migration 006 completed successfully! ``` --- ### Step 2: Seed System Roles (Phase 2) This creates the 5 system roles: Superadmin, Admin, Finance, Member, Guest. ```bash cd backend python3 roles_seed.py ``` **Expected output:** ``` Starting roles seeding... Created role: Superadmin (superadmin) - System role Created role: Admin (admin) - System role Created role: Finance (finance) - System role Created role: Member (member) - System role Created role: Guest (guest) - System role Roles seeding completed! Total roles created: 5 ``` --- ### Step 3: Migrate Existing Users (Phase 3a) This migrates all existing users from enum roles to the new dynamic role system. ```bash python3 migrate_users_to_dynamic_roles.py ``` **Expected output:** ``` Starting user migration to dynamic roles... Processing user: admin@loaf.org (superadmin) ✓ Mapped to role: Superadmin Processing user: finance@loaf.org (finance) ✓ Mapped to role: Finance ... User migration completed successfully! Total users migrated: X ``` --- ### Step 4: Migrate Role Permissions (Phase 3b) This migrates all existing role-permission mappings to use role_id. ```bash python3 migrate_role_permissions_to_dynamic_roles.py ``` **Expected output:** ``` Starting role permissions migration to dynamic roles... Migrating permissions for role: guest ✓ Migrated: events.view (X permissions) Migrating permissions for role: member ✓ Migrated: events.create (X permissions) ... Role permissions migration completed successfully! Total role_permission records migrated: X ``` --- ### Step 5: Verify Migration Run this verification script to ensure everything migrated correctly: ```bash python3 verify_admin_account.py ``` **Expected output:** ``` ================================================================================ VERIFYING admin@loaf.org ACCOUNT ================================================================================ ✅ User found: Admin User Email: admin@loaf.org Status: UserStatus.active Email Verified: True 📋 Legacy Role (enum): superadmin ✅ Dynamic Role: Superadmin (code: superadmin) Role ID: Is System Role: True 🔐 Checking Permissions: Total permissions assigned to role: 56 🎯 Access Check: ✅ User should have admin access (based on legacy enum) ✅ User should have admin access (based on dynamic role) ================================================================================ VERIFICATION COMPLETE ================================================================================ ``` --- ### Step 6: Deploy Backend Code ```bash # Pull latest code git pull origin main # Restart backend server # (adjust based on your deployment method) systemctl restart membership-backend # OR pm2 restart membership-backend # OR supervisorctl restart membership-backend ``` --- ### Step 7: Verify API Endpoints Test the role management endpoints: ```bash # Get all roles curl -H "Authorization: Bearer " \ http://your-server/api/admin/roles # Get all permissions curl -H "Authorization: Bearer " \ http://your-server/api/admin/permissions # Test export (the issue we just fixed) curl -H "Authorization: Bearer " \ http://your-server/api/admin/users/export ``` --- ## Rollback Plan (If Needed) If something goes wrong, you can rollback: ```sql BEGIN; -- Remove new columns ALTER TABLE users DROP COLUMN IF EXISTS role_id; ALTER TABLE role_permissions DROP COLUMN IF EXISTS role_id; -- Drop roles table DROP TABLE IF EXISTS roles CASCADE; COMMIT; ``` Then restore from your backup if needed. --- ## Post-Deployment Checklist - [ ] Schema migration completed without errors - [ ] System roles seeded (5 roles created) - [ ] All users migrated to dynamic roles - [ ] All role permissions migrated - [ ] Admin account verified - [ ] Backend server restarted - [ ] Export endpoint working (no 500 error) - [ ] Admin can view roles in UI (/admin/permissions) - [ ] Admin can create/edit roles - [ ] Admin can assign permissions to roles - [ ] Staff invitation uses dynamic roles --- ## Troubleshooting ### Issue: Migration script fails **Solution:** Check your `.env` file has correct `DATABASE_URL`: ``` DATABASE_URL=postgresql://user:password@host:port/database ``` ### Issue: "role_id column already exists" **Solution:** This is safe to ignore. The migration uses `IF NOT EXISTS` clauses. ### Issue: "No roles found" when migrating users **Solution:** Make sure you ran Step 2 (roles_seed.py) before Step 3. ### Issue: Export still returns 500 error **Solution:** 1. Verify backend code is latest version 2. Check server.py has export route BEFORE {user_id} route (around line 1965) 3. Restart backend server ### Issue: Permission denied errors **Solution:** Make sure your database user has permissions: ```sql GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ; ``` --- ## Files Involved ### Migration Files - `migrations/006_add_dynamic_roles.sql` - Schema changes - `roles_seed.py` - Seed system roles - `migrate_users_to_dynamic_roles.py` - Migrate user data - `migrate_role_permissions_to_dynamic_roles.py` - Migrate permission data - `verify_admin_account.py` - Verification script ### Code Changes - `server.py` - Route reordering (export before {user_id}) - `auth.py` - get_user_role_code() helper - `models.py` - Role model, role_id columns - Frontend: AdminRoles.js, InviteStaffDialog.js, AdminStaff.js, Navbar.js, Login.js --- ## Support If you encounter issues during deployment, check: 1. Backend logs: `tail -f /path/to/backend.log` 2. Database logs: Check PostgreSQL error logs 3. Frontend console: Browser developer tools For questions, refer to the CLAUDE.md file for system architecture details.