Section 04
Role-Based Permission Matrix
All permissions are enforced server-side via the user_roles table and the has_role() security-definer function. RLS policies on every table check role membership before granting read or write access.
FFull (CRUD + admin)AApprove / verifyWRead + create/edit ownRRead only—No access
| Module | Admin | Gov Officer | Vet | Farmer | Buyer | Rider |
|---|---|---|---|---|---|---|
| Users & Roles | F | R | — | — | — | — |
| Farm Verification | F | A | — | R | R | — |
| Own Farm — Animals / Crops | R | R | R | F | — | — |
| Marketplace Listings | F | R | — | W | R | — |
| Buyer Requests / Orders | F | R | — | W | F | R |
| Deliveries | F | R | — | R | R | W |
| Health Cases / Vet | R | R | F | W | — | — |
| Outbreak Reports | F | F | W | R | — | — |
| Finance — Own | R | — | — | F | F | F |
| Finance — All | R | — | — | — | — | — |
| Premium AI (gated) | F | F | — | — | — | — |
| National Analytics | F | F | R | — | — | — |
| Demo Mode / Reset | F | — | — | — | — | — |
Security note: Roles are stored in
public.user_roles (separate from profiles) to prevent privilege escalation. The has_role() function is SECURITY DEFINER with a fixed search_path, and all RLS policies use it instead of querying roles directly — eliminating recursive RLS bugs.