Every protected endpoint in Rappi2 enforces role-based access control. A user belongs to exactly one role, and a role carries a set of permissions. Each permission is aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/JorLOrT/rappi2/llms.txt
Use this file to discover all available pages before exploring further.
(recurso, accion) pair that grants access to a specific resource and action. Wildcards let a single permission span all resources or all actions, making it easy to grant broad access to administrative roles without enumerating every endpoint.
How permissions work
A permission is a row in thepermisos table with three fields:
| Field | Type | Example values |
|---|---|---|
recurso | varchar(50) | ordenes, conductores, roles, * |
accion | varchar(20) | read, write, delete, * |
rol_id | integer | FK → roles.id |
(rol_id, recurso, accion) prevents duplicate entries.
When the API evaluates a request, it iterates the caller’s permission list and checks:
recurso = "*"grants access to every resource for the given action.accion = "*"grants every action on the given resource.recurso = "*"andaccion = "*"together grant full access to everything.
403 Forbidden with the message Sin permiso para {recurso}:{accion}.
Built-in roles
Rappi2 ships with four roles created by the seed script. You can create additional roles via the API.| Role | Typical permissions | Use case |
|---|---|---|
| Admin | recurso="*", accion="*" | Full platform access for operators |
| Despachador | Varies | Dispatch staff managing assignments and routes |
| Cliente | ordenes:read, ordenes:write | Customers creating and tracking orders |
| Conductor | tracking:write | Drivers submitting GPS pings |
Only users with the
roles:write permission can create roles or add permissions. In practice this means only Admin-level users can manage the role hierarchy.Checking permissions
Every protected endpoint declares its required permission using therequire_permiso dependency:
get_current_user validates the Authorization: Bearer token, loads the Usuario row with its role, and rejects inactive users with 401 Unauthorized. require_permiso then checks the role’s permissions and rejects unauthorized callers with 403 Forbidden.
Permission cache
Loading permissions from PostgreSQL on every request would be expensive. Rappi2 keeps an in-memory cache keyed byrol_id:
(loaded_at_monotonic, [(recurso, accion), ...]). Entries older than 60 seconds are discarded and reloaded on the next request. When a role’s permissions are modified (via POST, DELETE on permissions, or PATCH on a role), invalidar_cache_permisos(rol_id) evicts the stale entry immediately.
The cache is process-local. If you run multiple worker processes, each process maintains its own cache and may serve slightly stale permissions for up to 60 seconds after a change. For single-worker deployments this is not a concern.
Managing roles via API
All role management endpoints are under/api/roles and require the roles:read or roles:write permission.
List all roles
Create a role
Add a permission to a role
Remove a permission from a role
204 No Content on success.
Delete a role
You cannot delete a role that still has users assigned to it. The API returns
409 Conflict with the message No se puede eliminar el rol: tiene usuarios asociados. Reasigna esos usuarios a otro rol antes de borrarlo. Reassign all affected users before deleting the role.