Commit graph

5 commits

Author SHA1 Message Date
Vadym Samoilenko
0432635153 Grant oversight_admin write access to campaigns and proofs
Oversight admins can now create campaigns, upload proofs, and
flag/resolve issues when they have an agency assigned. They retain
all existing cross-agency read access for analytics, auditing, and
user management. Oversight admins without an agency see a read-only
campaigns view.

Changes:
- Add oversight_admin to canWrite permission in UserContext
- Guard readOnly for oversight_admin without agency in App.tsx
- Remove oversight_admin block from require_write_access dependency
- Remove WebSocket oversight_admin upload block in main.py
- Require agency for oversight_admin campaign creation in routes.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 13:08:54 +00:00
michael
a25c7a9d31 Grant oversight_admin read-only access to User Management
Allow oversight_admin users to view the User Management screen with
read-only access. They can see users, roles, agencies, and change
history but cannot edit roles, assign agencies, or create agencies.

Backend: open GET /users and GET /users/{id}/change-history to
oversight_admin (PUT /users stays super_admin only).
Frontend: add oversight_admin to sidebar nav and context permission,
render static text instead of dropdowns and hide the add-agency form
for non-super-admin users.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:35:07 -06:00
michael
ebfcd60c71 Fix campaign visibility bug for unassigned users after agency reassignment
Unassigned (no agency) non-admin users previously saw ALL campaigns due to
a truthiness check that treated None agency_id as "no filter". This was a
security bug — they should see NO campaigns and be blocked from creating them.

Backend: Add _NO_AGENCY sentinel to distinguish "no filter" from "no agency",
add early-returns at all 5 list/analytics endpoints, fix _check_campaign_access
to explicitly reject unassigned users, and block campaign creation with 403.

Frontend: Add isUnassigned boolean to UserContext, show informational empty
state on Campaigns view, and reinforce readOnly for defense-in-depth.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 07:42:42 -06:00
michael
a08d54ec6d Fix Agency Admin campaign creation and proof upload permissions
Switch canWrite from blacklist (role !== 'oversight_admin') to explicit
whitelist (super_admin, agency_admin, basic_user) for clearer permission
logic. Propagate readOnly prop to CampaignDetail and ProofDetailView
subcomponents so upload/delete buttons are properly hidden for read-only
roles at all navigation levels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 07:23:58 -06:00
michael
05e74becfe Add frontend RBAC: UserContext, role-based sidebar, agency filter, user management
- Add UserRole type and AppUser interface to types.ts
- Create UserContext with useUser() hook providing role-based permission booleans
- Split App into App (auth wrapper) + AppContent (uses UserContext)
- Update Sidebar to filter nav items by UserRole instead of boolean isAdmin
- Add User Management nav item (super_admin only)
- Add AgencyFilterBar component for oversight_admin/super_admin session-level filtering
- Pass agencyId to getCampaigns, getAnalytics, audit endpoints in apiService
- Add getMe, getUsers, updateUser, createAgency to apiService
- Build UserManagement page with user table (role/agency dropdowns) and agency CRUD
- Add readOnly prop to Campaigns (hides create/delete/status-toggle for oversight_admin)
- Add readOnly prop to Settings (disables all ManagementCards, shows view-only banner)
- Pass agencyId to Analytics component for filtered data
- Update urlState with Knowledge Base and User Management views

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 08:36:38 -06:00