Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/azahel79/Spartans-gym/llms.txt

Use this file to discover all available pages before exploring further.

Spartans Gym uses a two-role authorization model to separate what staff members can do. Every request to the API must carry a valid JWT Bearer token, and the server verifies the caller’s role before allowing access to any protected resource. Role checks happen at the middleware layer, meaning no route can be reached unless the correct role is present in the decoded token — frontend restrictions alone are never relied upon.

Roles

There are exactly two roles in the system, defined as a Prisma enum:
RoleDescription
adminFull system access including user management, configuration, and financial data
recepcionistaDay-to-day operations — managing clients, recording attendance, and processing transactions
New users default to recepcionista unless a different role is specified at creation time.

How Authentication Works

Every protected route runs the authenticate middleware first. It reads the Authorization header, expects a Bearer <token> value, and verifies the JWT with the server secret. The decoded payload is then attached to the request object for downstream middleware and controllers to use.
// auth.middleware.ts — token shape after decoding
export interface TokenPayload {
  id: number;
  email: string;
  role: string;
}
If the header is missing or the token is invalid or expired, the server immediately returns 401 Unauthorized.

Role Enforcement Middleware

Two ready-made middleware exports handle the most common access patterns:
// role.middleware.ts
export const requireAdmin = requireRole('admin');
export const requireAnyUser = requireRole('admin', 'recepcionista');
requireAdmin allows only users whose token carries role: "admin". requireAnyUser allows either role. Any mismatch returns 403 Forbidden with the body { "success": false, "error": "No tienes permiso para acceder a este recurso" }. Routes apply these middlewares at the router level so every endpoint in that group is protected uniformly:
// user.routes.ts — all user management routes require admin
router.use(authenticate);
router.use(requireAdmin);

Permissions by Feature

The table below shows which HTTP methods are permitted for each role across every major feature area.
OperationMethodEndpointAdminRecepcionista
List / search clientsGET/api/clients
Create clientPOST/api/clients
Record attendancePOST/api/clients/:id/attendance
Renew membershipPOST/api/clients/:id/renew
Edit clientPUT/api/clients/:id
Delete clientDELETE/api/clients/:id

Frontend Enforcement

The frontend reinforces server-side rules in two ways:

PrivateRoute Guard

Admin-only pages such as /config are wrapped in a PrivateRoute component that checks the authenticated user’s role. A receptionist navigating directly to that URL is redirected before the page renders.

Conditional UI Elements

Edit and delete buttons throughout the interface are conditionally rendered based on user.role. Receptionists see read-only views of plans, products, and client profiles without action controls.

Changing a User’s Role

An admin can promote or demote any other user by sending a PATCH request to the role endpoint:
PATCH /api/users/:id/role
Authorization: Bearer <admin-token>
Content-Type: application/json

{
  "role": "admin"
}
The only accepted values for role are "admin" and "recepcionista". Any other value returns 400 Bad Request.
A user cannot change their own role or delete their own account. The frontend blocks both actions when the target user’s email matches the currently authenticated session. Attempting to do so via the UI triggers a warning toast and the request is never sent.

Build docs developers (and LLMs) love