6.9 KiB
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.
# Connect to your database
psql -U <username> -d <database_name> -f migrations/006_add_dynamic_roles.sql
What this does:
- Creates
rolestable - Adds
role_idcolumn tousers(nullable) - Adds
role_idcolumn torole_permissions(nullable) - Legacy
roleenum 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.
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.
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.
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:
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: <uuid>
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
# 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:
# Get all roles
curl -H "Authorization: Bearer <token>" \
http://your-server/api/admin/roles
# Get all permissions
curl -H "Authorization: Bearer <token>" \
http://your-server/api/admin/permissions
# Test export (the issue we just fixed)
curl -H "Authorization: Bearer <token>" \
http://your-server/api/admin/users/export
Rollback Plan (If Needed)
If something goes wrong, you can rollback:
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:
- Verify backend code is latest version
- Check server.py has export route BEFORE {user_id} route (around line 1965)
- Restart backend server
Issue: Permission denied errors
Solution: Make sure your database user has permissions:
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO <username>;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO <username>;
Files Involved
Migration Files
migrations/006_add_dynamic_roles.sql- Schema changesroles_seed.py- Seed system rolesmigrate_users_to_dynamic_roles.py- Migrate user datamigrate_role_permissions_to_dynamic_roles.py- Migrate permission dataverify_admin_account.py- Verification script
Code Changes
server.py- Route reordering (export before {user_id})auth.py- get_user_role_code() helpermodels.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:
- Backend logs:
tail -f /path/to/backend.log - Database logs: Check PostgreSQL error logs
- Frontend console: Browser developer tools
For questions, refer to the CLAUDE.md file for system architecture details.