Authorization in KaroKar is capability-driven, not title-driven. Rather than asking “Is this user a Corporate Admin?”, every access decision asks “Does this user hold the permission to perform this specific action within this organization?” This distinction matters enormously at scale: roles are implementation details that may change, proliferate, or be customized per enterprise customer, but permissions are stable expressions of business capabilities. The entire authorization chain — from JWT extraction through guard evaluation to ownership validation — is built around permissions as the single source of truth.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Codefied-CodePix/Karokar-backend/llms.txt
Use this file to discover all available pages before exploring further.
The Authorization Chain
OrganizationMember record. That membership references a Role. The role is a named collection of Permission records. When a request arrives, the authorization system resolves this chain and evaluates whether the resolved permission set contains the required permission for the requested action.
Role Entity
OrganizationType. A VENDOR_ADMIN role can only be assigned within a VENDOR organization — the data model enforces this at the role definition level.
Permission Entity
Permission Naming Convention
All permissions follow a strictresource.action format. This makes permission strings self-documenting and consistent across every domain.
resource segment maps to a domain aggregate. The action segment maps to a business operation within that aggregate’s lifecycle.
Phase 01 Role-Permission Mappings
PLATFORM_ADMIN
Full platform governance. Can approve and suspend organizations, review verifications, and access global reports.Key permissions:
organization.approve, vehicle.read, booking.readVENDOR_ADMIN
Manages the vendor fleet and responds to booking requests from corporate organizations.Permissions:
vehicle.create, vehicle.update, vehicle.read, booking.read, booking.approve, booking.rejectCORPORATE_ADMIN
Creates bookings on behalf of the corporate organization and manages employee memberships.Permissions:
vehicle.read, booking.create, booking.read, assignment.create, employee.manageEMPLOYEE
Read-only access to their own bookings and the ability to respond to vehicle assignments.Permissions:
assignment.read, assignment.accept, assignment.reject, booking.readThe @RequirePermission Decorator
Every protected controller method is annotated with a single decorator that declares the required permission string. The decorator stores the value as route metadata using NestJS’sSetMetadata.
Example Usage on a Controller
How PermissionGuard Works
ThePermissionGuard runs on every request that has a @RequirePermission annotation. It reads the permission key from route metadata, extracts userId and organizationId from the authenticated request, and delegates the evaluation to the IAuthorizationService.
- Authentication check —
userIdandorganizationIdmust both be present on the request. If either is missing, a401 Unauthorizedis thrown. - Permission check —
authorizationService.can(userId, organizationId, permission)resolves the user’s membership in that specific organization, walks the Role → Permission chain, and returns a boolean. Iffalse, a403 Forbiddenis thrown.
Organization Isolation
Permission checks alone are insufficient. A user withbooking.approve in Vendor A must never be able to approve a booking that belongs to Vendor B — even if both vendors share the same role definition. The authorization model therefore combines two distinct checks:
- Permission check — Does the user hold the required capability?
- Ownership check — Does the resource being acted upon belong to the user’s current organization?
Organization Context Propagation
TheOrganizationContextInterceptor runs before guards and extracts organizationId from the JWT payload, attaching it directly to request.organizationId. This ensures the PermissionGuard always has the tenant context available without requiring controllers to parse the token themselves.
Future-Proofing
The current Phase 01 roles (PLATFORM_ADMIN, VENDOR_ADMIN, CORPORATE_ADMIN, EMPLOYEE) are system roles seeded at boot time. The data model supports custom roles without any code changes: a new Role row with isSystemRole: false can be created for an enterprise customer and populated with any subset of existing Permission records. Future roles such as FLEET_MANAGER, FINANCE_MANAGER, APPROVER, and DRIVER are anticipated in the ADR and will require only data changes — not schema or application code changes.