feat: implement RBAC permissions system
Add role-based access control with hierarchy: super_admin > team_admin > engineer > viewer. Adds is_super_admin boolean to User model (migration 010), centralized backend permissions module, frontend usePermissions hook, and UI enforcement (conditional Create/Edit buttons, editor redirect for viewers, role badge in header). All endpoint admin checks updated from role=="admin" to is_super_admin. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
24
CLAUDE.md
24
CLAUDE.md
@@ -96,6 +96,15 @@ When adding new frontend pages or components, use "ResolutionFlow" for any user-
|
||||
- Backend `get_refresh_token_payload` dependency extracts refresh token from Authorization header
|
||||
- Frontend Axios interceptor queues failed requests during refresh, retries after success
|
||||
- Auth store synced after silent refresh via `setTokens` action
|
||||
- **RBAC & Permissions:**
|
||||
- `is_super_admin` boolean on User model (migration 010)
|
||||
- Role hierarchy: super_admin > team_admin > engineer > viewer
|
||||
- `role` field values: 'engineer' | 'viewer' (no more 'admin')
|
||||
- Team Admin = `role='engineer'` + `is_team_admin=True` + valid `team_id`
|
||||
- Backend centralized: `backend/app/core/permissions.py`
|
||||
- Frontend hook: `frontend/src/hooks/usePermissions.ts`
|
||||
- Viewers CAN: browse trees, start sessions, rate steps
|
||||
- Viewers CANNOT: create/edit trees, steps, tags, categories
|
||||
- **Session Scratchpad (Floating Overlay):**
|
||||
- Fixed-position overlay panel (420px wide, 55vh tall) on right edge
|
||||
- Floating button when collapsed, slide-in panel when expanded
|
||||
@@ -158,6 +167,7 @@ patherly/
|
||||
│ │ ├── core/
|
||||
│ │ │ ├── config.py # Settings (pydantic-settings)
|
||||
│ │ │ ├── database.py # Async SQLAlchemy
|
||||
│ │ │ ├── permissions.py # Centralized RBAC (role checks, content guards)
|
||||
│ │ │ ├── security.py # JWT + password hashing
|
||||
│ │ │ ├── logging_config.py # Structured logging
|
||||
│ │ │ └── middleware.py # Request logging
|
||||
@@ -198,7 +208,7 @@ patherly/
|
||||
│ │ │ ├── auth.ts
|
||||
│ │ │ ├── trees.ts
|
||||
│ │ │ └── sessions.ts
|
||||
│ │ ├── hooks/ # Custom React hooks (useKeyboardShortcuts)
|
||||
│ │ ├── hooks/ # Custom React hooks (useKeyboardShortcuts, usePermissions)
|
||||
│ │ ├── store/
|
||||
│ │ │ ├── authStore.ts # Zustand auth state
|
||||
│ │ │ ├── themeStore.ts # Dark/light theme
|
||||
@@ -496,6 +506,17 @@ if settings.ALLOW_RAILWAY_ORIGINS:
|
||||
```
|
||||
When using `allow_origin_regex` for wildcard patterns, also include `allow_origins` for explicit custom domains. The regex alone won't match custom domains like `resolutionflow.com`.
|
||||
|
||||
### RBAC Permission Checks
|
||||
|
||||
- Backend auth deps: `get_current_user` (any logged-in), `require_engineer_or_admin` (blocks viewers), `require_admin` (super admin only)
|
||||
- Backend: `is_super_admin` replaces all `role == "admin"` checks. Never use `role == "admin"`.
|
||||
- Frontend: use `usePermissions()` hook for all role/permission checks
|
||||
- `TreeListItem` includes `team_id` for frontend permission checks (`author_id` and `team_id` are nullable)
|
||||
|
||||
### Alembic Migrations: Test Data State Before Writing WHERE Clauses
|
||||
|
||||
Migration 010 had `WHERE role = 'admin'` but the only user already had `role = 'engineer'` (changed by earlier work), so the UPDATE matched zero rows. Always verify actual data values before writing conditional migrations, or use broader conditions.
|
||||
|
||||
### findNode Requires Tree Structure Parameter
|
||||
|
||||
```tsx
|
||||
@@ -792,6 +813,7 @@ Position overlay at `right-2` (not `right-0`) so it sits inside the page scrollb
|
||||
1. Create test database: `docker exec -it patherly_postgres psql -U postgres -c "CREATE DATABASE patherly_test;"`
|
||||
2. Install dev deps: `pip install -r requirements-dev.txt`
|
||||
3. Ensure pytest-asyncio version: `pip install pytest-asyncio==0.24.0`
|
||||
4. If `unrecognized arguments: --cov` error: run with `--override-ini="addopts="` or install `pytest-cov`
|
||||
|
||||
### API 500 errors
|
||||
|
||||
|
||||
Reference in New Issue
Block a user