RBAC: Enforce read-only viewer role across backend and frontend

- Add global WriteAccessGuard that blocks POST/PUT/PATCH/DELETE for viewer role
- Add @AllowViewer() decorator for endpoints viewers need (switch-org, intro-seen, AI recommendations)
- Add useIsReadOnly hook to auth store for frontend role checks
- Hide write UI (add/edit/delete/import buttons, inline editors) in all 13 data pages for viewers
- Disable inline NumberInputs on Budgets and Monthly Actuals pages for viewers
- Skip onboarding wizard for viewer role users

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 09:18:32 -05:00
parent 07347a644f
commit c92eb1b57b
20 changed files with 269 additions and 156 deletions

View File

@@ -42,6 +42,9 @@ interface AuthState {
logout: () => void;
}
/** Hook to check if the current user has read-only (viewer) access */
export const useIsReadOnly = () => useAuthStore((s) => s.currentOrg?.role === 'viewer');
export const useAuthStore = create<AuthState>()(
persist(
(set, get) => ({