317 lines
17 KiB
Markdown
317 lines
17 KiB
Markdown
# RBAC Architecture Visual Guide
|
|
|
|
## System Overview
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ PLATFORM LEVEL │
|
|
│ │
|
|
│ ┌──────────────────┐ ┌──────────────────┐ │
|
|
│ │ Admin Users │ │ Vendor Users │ │
|
|
│ │ role="admin" │ │ role="vendor" │ │
|
|
│ │ │ │ │ │
|
|
│ │ • Full platform │ │ • Can own/join │ │
|
|
│ │ access │ │ vendors │ │
|
|
│ │ • Cannot access │ │ • Cannot access │ │
|
|
│ │ vendor portal │ │ admin portal │ │
|
|
│ └──────────────────┘ └──────────────────┘ │
|
|
│ │ │
|
|
└──────────────────────────────────────────────┼──────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ VENDOR LEVEL │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
│ │ Vendor: ACME │ │
|
|
│ │ │ │
|
|
│ │ ┌──────────────┐ ┌──────────────────────┐ │ │
|
|
│ │ │ 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 │ │ │
|
|
│ │ │ removed │ │ │ │ │
|
|
│ │ └──────────────┘ └──────────────────────┘ │ │
|
|
│ │ │ │ │
|
|
│ │ ▼ │ │
|
|
│ │ ┌──────────────────────────────┐ │ │
|
|
│ │ │ Roles │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ • Manager (many perms) │ │ │
|
|
│ │ │ • Staff (moderate perms) │ │ │
|
|
│ │ │ • Support (limited perms) │ │ │
|
|
│ │ │ • Viewer (read-only) │ │ │
|
|
│ │ │ • Custom (owner-defined) │ │ │
|
|
│ │ └──────────────────────────────┘ │ │
|
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ CUSTOMER LEVEL │
|
|
│ (Separate from Users) │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
│ │ Customers (per vendor) │ │
|
|
│ │ │ │
|
|
│ │ • Vendor-scoped authentication │ │
|
|
│ │ • Can self-register │ │
|
|
│ │ • Access own account + shop catalog │ │
|
|
│ │ • Cannot access admin/vendor portals │ │
|
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Team Invitation Flow
|
|
|
|
```
|
|
┌──────────┐
|
|
│ Owner │
|
|
│ (ACME) │
|
|
└────┬─────┘
|
|
│
|
|
│ 1. Click "Invite Team Member"
|
|
│ Email: jane@example.com
|
|
│ Role: Manager
|
|
▼
|
|
┌─────────────────────┐
|
|
│ System Creates: │
|
|
│ • User account │
|
|
│ • VendorUser │
|
|
│ • Invitation token │
|
|
└────┬────────────────┘
|
|
│
|
|
│ 2. Email sent to jane@example.com
|
|
│
|
|
▼
|
|
┌──────────────────────┐
|
|
│ Jane clicks link │
|
|
│ /invitation/accept? │
|
|
│ token=abc123... │
|
|
└────┬─────────────────┘
|
|
│
|
|
│ 3. Jane sets password
|
|
│ Enters name
|
|
│
|
|
▼
|
|
┌─────────────────────┐
|
|
│ Account Activated: │
|
|
│ • User.is_active │
|
|
│ • VendorUser. │
|
|
│ is_active │
|
|
└────┬────────────────┘
|
|
│
|
|
│ 4. Jane can now login
|
|
│
|
|
▼
|
|
┌──────────────────────┐
|
|
│ Jane logs in to │
|
|
│ ACME vendor portal │
|
|
│ with Manager perms │
|
|
└──────────────────────┘
|
|
```
|
|
|
|
## Permission Check Flow
|
|
|
|
```
|
|
┌────────────────┐
|
|
│ User makes │
|
|
│ request to: │
|
|
│ POST /products │
|
|
└───────┬────────┘
|
|
│
|
|
▼
|
|
┌────────────────────────────────┐
|
|
│ FastAPI Dependency: │
|
|
│ require_vendor_permission( │
|
|
│ "products.create" │
|
|
│ ) │
|
|
└───────┬────────────────────────┘
|
|
│
|
|
│ 1. Get vendor from request.state
|
|
│ 2. Get user from JWT
|
|
│
|
|
▼
|
|
┌────────────────────────────────┐
|
|
│ Is user a member of vendor? │
|
|
└───────┬────────────────────────┘
|
|
│
|
|
├─ No ──> ❌ VendorAccessDeniedException
|
|
│
|
|
▼ Yes
|
|
┌────────────────────────────────┐
|
|
│ Is user the owner? │
|
|
└───────┬────────────────────────┘
|
|
│
|
|
├─ Yes ──> ✅ Allow (owners have all perms)
|
|
│
|
|
▼ No
|
|
┌────────────────────────────────┐
|
|
│ Get user's role and │
|
|
│ permissions from VendorUser │
|
|
└───────┬────────────────────────┘
|
|
│
|
|
▼
|
|
┌────────────────────────────────┐
|
|
│ Does role contain │
|
|
│ "products.create"? │
|
|
└───────┬────────────────────────┘
|
|
│
|
|
├─ No ──> ❌ InsufficientVendorPermissionsException
|
|
│
|
|
▼ Yes
|
|
┌────────────────────────────────┐
|
|
│ ✅ Allow request │
|
|
│ Handler executes │
|
|
└────────────────────────────────┘
|
|
```
|
|
|
|
## Database Relationships
|
|
|
|
```
|
|
┌──────────────────┐
|
|
│ users │
|
|
│ │
|
|
│ id (PK) │◄────┐
|
|
│ email │ │
|
|
│ role │ │
|
|
│ ('admin' or │ │
|
|
│ 'vendor') │ │
|
|
└──────────────────┘ │
|
|
│ │
|
|
│ owner_user_id │
|
|
│ │
|
|
▼ │
|
|
┌──────────────────┐ │
|
|
│ vendors │ │
|
|
│ │ │
|
|
│ id (PK) │ │
|
|
│ vendor_code │ │
|
|
│ owner_user_id ──┼─────┘
|
|
└──────────────────┘
|
|
│
|
|
│
|
|
▼
|
|
┌──────────────────┐ ┌──────────────────┐
|
|
│ vendor_users │ │ roles │
|
|
│ │ │ │
|
|
│ id (PK) │ │ id (PK) │
|
|
│ vendor_id (FK) │ │ vendor_id (FK) │
|
|
│ user_id (FK) │ │ name │
|
|
│ role_id (FK) ───┼────►│ permissions │
|
|
│ user_type │ │ (JSON) │
|
|
│ ('owner' or │ └──────────────────┘
|
|
│ 'member') │
|
|
│ invitation_* │
|
|
│ is_active │
|
|
└──────────────────┘
|
|
|
|
Separate hierarchy:
|
|
|
|
┌──────────────────┐
|
|
│ customers │
|
|
│ │
|
|
│ id (PK) │
|
|
│ vendor_id (FK) │
|
|
│ email │
|
|
│ hashed_password │
|
|
│ (vendor-scoped) │
|
|
└──────────────────┘
|
|
```
|
|
|
|
## Permission Naming Convention
|
|
|
|
```
|
|
Resource.Action
|
|
|
|
Examples:
|
|
✓ dashboard.view
|
|
✓ products.view
|
|
✓ products.create
|
|
✓ products.edit
|
|
✓ products.delete
|
|
✓ products.import
|
|
✓ products.export
|
|
✓ orders.view
|
|
✓ orders.edit
|
|
✓ orders.cancel
|
|
✓ orders.refund
|
|
✓ customers.view
|
|
✓ customers.edit
|
|
✓ reports.financial
|
|
✓ team.invite
|
|
✓ team.remove
|
|
✓ settings.edit
|
|
```
|
|
|
|
## Role Presets
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
│ OWNER │
|
|
│ ALL PERMISSIONS (automatic, not stored in role) │
|
|
└──────────────────────────────────────────────────────────────┘
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
│ MANAGER │
|
|
│ Most permissions except: │
|
|
│ • team.invite/remove (owner only) │
|
|
│ • Critical settings (owner only) │
|
|
│ │
|
|
│ Has: products.*, orders.*, customers.*, reports.* │
|
|
└──────────────────────────────────────────────────────────────┘
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
│ STAFF │
|
|
│ Day-to-day operations: │
|
|
│ • products.view/create/edit │
|
|
│ • stock.view/edit │
|
|
│ • orders.view/edit │
|
|
│ • customers.view │
|
|
└──────────────────────────────────────────────────────────────┘
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
│ SUPPORT │
|
|
│ Customer service focus: │
|
|
│ • orders.view/edit │
|
|
│ • customers.view/edit │
|
|
│ • products.view (read-only) │
|
|
└──────────────────────────────────────────────────────────────┘
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
│ VIEWER │
|
|
│ Read-only access: │
|
|
│ • *.view permissions only │
|
|
│ • No edit/create/delete │
|
|
└──────────────────────────────────────────────────────────────┘
|
|
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
│ MARKETING │
|
|
│ Marketing & analytics focus: │
|
|
│ • customers.view/export │
|
|
│ • marketing.* (all marketing actions) │
|
|
│ • reports.view │
|
|
└──────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Security Boundaries
|
|
|
|
```
|
|
❌ BLOCKED ✅ ALLOWED
|
|
|
|
Admin → Vendor Portal Admin → Admin Portal
|
|
Vendor → Admin Portal Vendor → Vendor Portal
|
|
Customer → Admin Portal Customer → Shop Catalog
|
|
Customer → Vendor Portal Customer → Own Account
|
|
|
|
Cookie Isolation:
|
|
admin_token (path=/admin) ← Only sent to /admin/*
|
|
vendor_token (path=/vendor) ← Only sent to /vendor/*
|
|
customer_token (path=/shop) ← Only sent to /shop/*
|
|
```
|