feat: RBAC Phase 1 — consolidate user roles into 4-value enum
Some checks failed
Some checks failed
Consolidate User.role (2-value: admin/store) + User.is_super_admin (boolean) into a single 4-value UserRole enum: super_admin, platform_admin, merchant_owner, store_member. Drop stale StoreUser.user_type column. Fix role="user" bug in merchant creation. Key changes: - Expand UserRole enum from 2 to 4 values with computed properties (is_admin, is_super_admin, is_platform_admin, is_merchant_owner, is_store_user) - Add Alembic migration (tenancy_003) for data migration + column drops - Remove is_super_admin from JWT token payload - Update all auth dependencies, services, routes, templates, JS, and tests - Update all RBAC documentation 66 files changed, 1219 unit tests passing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,16 +5,32 @@
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PLATFORM LEVEL │
|
||||
│ User.role (4-value enum) │
|
||||
│ │
|
||||
│ ┌──────────────────┐ ┌──────────────────┐ │
|
||||
│ │ Admin Users │ │ Store Users │ │
|
||||
│ │ role="admin" │ │ role="store" │ │
|
||||
│ │ Super Admin │ │ Platform Admin │ │
|
||||
│ │ role= │ │ role= │ │
|
||||
│ │ "super_admin" │ │ "platform_admin"│ │
|
||||
│ │ │ │ │ │
|
||||
│ │ • Full platform │ │ • Can own/join │ │
|
||||
│ │ access │ │ stores │ │
|
||||
│ │ • Full platform │ │ • Scoped to │ │
|
||||
│ │ access │ │ assigned │ │
|
||||
│ │ • All platforms │ │ platforms │ │
|
||||
│ │ • Cannot access │ │ • Cannot access │ │
|
||||
│ │ store portal │ │ admin portal │ │
|
||||
│ │ store portal │ │ store portal │ │
|
||||
│ └──────────────────┘ └──────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────┐ ┌──────────────────┐ │
|
||||
│ │ Merchant Owner │ │ Store Member │ │
|
||||
│ │ role= │ │ role= │ │
|
||||
│ │ "merchant_owner"│ │ "store_member" │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ • Owns stores │ │ • Invited to │ │
|
||||
│ │ • All perms in │ │ stores │ │
|
||||
│ │ own stores │ │ • Role-based │ │
|
||||
│ │ • Cannot access │ │ permissions │ │
|
||||
│ │ admin portal │ │ • Cannot access │ │
|
||||
│ └──────────────────┘ │ admin portal │ │
|
||||
│ └──────────────────┘ │
|
||||
│ │ │
|
||||
└──────────────────────────────────────────────┼──────────────────┘
|
||||
│
|
||||
@@ -27,17 +43,18 @@
|
||||
│ │ │ │
|
||||
│ │ ┌──────────────┐ ┌──────────────────────┐ │ │
|
||||
│ │ │ Owner │ │ Team Members │ │ │
|
||||
│ │ │ user_type= │ │ user_type= │ │ │
|
||||
│ │ │ "owner" │ │ "member" │ │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ │ • All perms │ │ • Role-based perms │ │ │
|
||||
│ │ │ • Can invite │ │ • Manager/Staff/etc │ │ │
|
||||
│ │ │ • Can remove │ │ • Can be invited │ │ │
|
||||
│ │ │ • Cannot be │ │ • Can be removed │ │ │
|
||||
│ │ │ role= │ │ role= │ │ │
|
||||
│ │ │ "merchant_ │ │ "store_member" │ │ │
|
||||
│ │ │ owner" │ │ │ │ │
|
||||
│ │ │ │ │ • Role-based perms │ │ │
|
||||
│ │ │ • All perms │ │ • Manager/Staff/etc │ │ │
|
||||
│ │ │ • Can invite │ │ • Can be invited │ │ │
|
||||
│ │ │ • Can remove │ │ • Can be removed │ │ │
|
||||
│ │ │ • Cannot be │ │ │ │ │
|
||||
│ │ │ removed │ │ │ │ │
|
||||
│ │ └──────────────┘ └──────────────────────┘ │ │
|
||||
│ │ │ │ │
|
||||
│ │ ▼ │ │
|
||||
│ │ Ownership via Merchant.owner_user_id ▼ │ │
|
||||
│ │ ┌──────────────────────────────┐ │ │
|
||||
│ │ │ Roles │ │ │
|
||||
│ │ │ │ │ │
|
||||
@@ -180,8 +197,12 @@
|
||||
│ id (PK) │◄────┐
|
||||
│ email │ │
|
||||
│ role │ │
|
||||
│ ('admin' or │ │
|
||||
│ 'store') │ │
|
||||
│ ('super_admin', │ │
|
||||
│ 'platform_ │ │
|
||||
│ admin', │ │
|
||||
│ 'merchant_ │ │
|
||||
│ owner', │ │
|
||||
│ 'store_member') │ │
|
||||
└──────────────────┘ │
|
||||
│ │
|
||||
│ owner_user_id │
|
||||
@@ -204,12 +225,12 @@
|
||||
│ store_id (FK) │ │ store_id (FK) │
|
||||
│ user_id (FK) │ │ name │
|
||||
│ role_id (FK) ───┼────►│ permissions │
|
||||
│ user_type │ │ (JSON) │
|
||||
│ ('owner' or │ └──────────────────┘
|
||||
│ 'member') │
|
||||
│ invitation_* │
|
||||
│ is_active │
|
||||
│ invitation_* │ │ (JSON) │
|
||||
│ is_active │ └──────────────────┘
|
||||
└──────────────────┘
|
||||
(no user_type column;
|
||||
ownership via
|
||||
Merchant.owner_user_id)
|
||||
|
||||
Separate hierarchy:
|
||||
|
||||
@@ -302,12 +323,14 @@ Examples:
|
||||
## Security Boundaries
|
||||
|
||||
```
|
||||
❌ BLOCKED ✅ ALLOWED
|
||||
|
||||
Admin → Store Portal Admin → Admin Portal
|
||||
Store → Admin Portal Store → Store Portal
|
||||
Customer → Admin Portal Customer → Shop Catalog
|
||||
Customer → Store Portal Customer → Own Account
|
||||
❌ BLOCKED ✅ ALLOWED
|
||||
|
||||
super_admin → Store Portal super_admin → Admin Portal
|
||||
platform_admin → Store Portal platform_admin → Admin Portal
|
||||
merchant_owner → Admin Portal merchant_owner → Store Portal
|
||||
store_member → Admin Portal store_member → Store Portal
|
||||
Customer → Admin Portal Customer → Shop Catalog
|
||||
Customer → Store Portal Customer → Own Account
|
||||
|
||||
Cookie Isolation:
|
||||
admin_token (path=/admin) ← Only sent to /admin/*
|
||||
|
||||
Reference in New Issue
Block a user