Files
membership-be/DEPLOYMENT_GUIDE.md
2025-12-16 20:03:50 +07:00

288 lines
6.9 KiB
Markdown

# 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 <username> -d <database_name> -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: <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
```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 <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:
```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 <username>;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO <username>;
```
---
## 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.