Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Luisangelebp/SCO_Autolavados/llms.txt

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

SCO Autolavados enforces a strict role-based access control (RBAC) model across every layer of the platform. Three distinct roles govern what each actor can see and do — from full administrative control down to purely operational, credential-free laundrer records. Every protected API route validates the caller’s role from a signed JWT before executing any business logic.

Role Overview

Admin

Full system access. Can create any user type (Admin, Customer, or Laundrer). Manages the service queue, approves payments, views KPI dashboards, configures commission settings, and accesses all historical records. Admins can only be created by another Admin — there is no self-registration path for this role.

Customer

The end-user of the car wash. Can self-register online or be pre-registered at the physical counter by an Admin. Customers can create reservations, submit customer orders from the web portal, view their own service history, and update their own profile. A Customer cannot view or modify other users’ data.

Laundrer

Purely operational — no login credentials, no frontend access. Laundrer records exist to track shift hours, assign responsibility on service orders, and feed into the commission payroll pool. Created by Admin at the reception counter using the quick-registration endpoint.

User Creation Flows

Two distinct flows handle user creation depending on the context: a quick counter flow for physical walk-ins and an online self-registration flow for customers who register themselves.

Admin / Counter Flow

Used at the physical reception desk to register walk-in customers and laundrers rapidly — no email or password required, keeping the queue moving.
POST /api/users/admin
Authorization: Bearer <ADMIN_TOKEN>
Content-Type: application/json
{
  "name": "Juan",
  "lastName": "Perez",
  "roleId": "uuid-del-rol",
  "cedula": "V12345678",
  "phone": "04141234567"
}
Response (201):
{
  "id": "uuid",
  "name": "Juan",
  "lastName": "Perez",
  "cedula": "V12345678",
  "phone": "04141234567",
  "email": null,
  "hashPassword": null,
  "status": true,
  "createdAt": "2026-06-26T10:00:00.000Z"
}
The cedula field must start with V, E, J, or G (Venezuelan identity and tax ID formats). Submissions with any other prefix will be rejected with a validation error.

Online Self-Registration

Customers can register themselves through the web portal using POST /api/users/register. The system first checks whether the provided cedula already exists in the database (meaning the customer was previously pre-registered at the counter by an Admin).
  • If the cedula exists: The account is activated — the existing record is updated with the new email, user, and hashed password. Name and phone data from the prior counter registration are preserved automatically.
  • If the cedula does not exist: A brand new Customer account is created from scratch.
POST /api/users/register
Content-Type: application/json
{
  "cedula": "V12345678",
  "name": "Juan",
  "lastName": "Perez",
  "phone": "04141234567",
  "email": "[email protected]",
  "user": "juanperez",
  "password": "mi_password_seguro"
}
Response (201): The created or activated User object with hashPassword omitted.
All fields including email, user, and password are mandatory for the online registration flow. Accounts created at the counter that already have an email set are considered fully active and cannot be re-activated via this endpoint.

Authentication

All protected routes require a Bearer token obtained from the login endpoint.
POST /api/users/login
Content-Type: application/json
{
  "identifier": "juanperez",
  "password": "mi_password_seguro"
}
The identifier field accepts either the user’s email address or their username (user field). Response (200):
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "uuid",
    "email": "[email protected]",
    "role": { "name": "Customer" }
  }
}
The access token expires in 15 minutes. The refresh token is valid for 7 days and can be exchanged for a new access token without requiring the user to log in again.
The JWT_SECRET environment variable must be set in your backend .env file before starting the server. If absent, the application will throw an error when attempting to sign or verify tokens.
Use the token in subsequent requests:
Authorization: Bearer <token>
Error (401): Returned for invalid credentials, unactivated accounts (no password set), or inactive users.

Token Refresh

Access tokens expire after 15 minutes. Exchange a valid refresh token for a new access token without re-authenticating:
POST /api/users/refresh
Content-Type: application/json
{
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response (200):
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Error (401): Returned if the refresh token is invalid, expired, or does not have isRefresh: true in its payload. The user must log in again to obtain a new token pair.

Listing Users

GET /api/users is restricted to the Admin role. It returns a paginated list of all users with their role information included.
GET /api/users?cant=10&page=1
Authorization: Bearer <ADMIN_TOKEN>
Query ParamDefaultDescription
cant10Records per page
page1Page number (1-based)
Response (200):
{
  "users": [
    {
      "id": "uuid",
      "name": "Juan",
      "lastName": "Perez",
      "cedula": "V12345678",
      "role": { "id": "uuid", "name": "CUSTOMER" }
    }
  ],
  "total": 42
}
To retrieve all users that belong to a specific role, use:
GET /api/users/role/:roleName
This endpoint is unauthenticated. The roleName parameter is case-insensitive — CUSTOMER, Customer, and customer all return the same results.

Cedula Auto-Complete

To improve the registration UX on the frontend, the system exposes a cedula lookup endpoint that the RegisterPage uses to pre-fill the form when a customer was previously registered at the counter.
GET /api/users/check/:cedula
  • Response (200): Returns the user’s basic data (name, lastName, phone) if the cedula exists in the database without an active email.
  • Response (404): Cedula not found — the user will be created from scratch.
The frontend registration form calls this endpoint as the user types their cedula. If a match is found, the name, lastName, and phone fields are filled in automatically and the customer only needs to enter their email and password to complete activation.

Photo Upload

The PATCH /api/users/:id endpoint supports profile photo uploads via multipart/form-data. Multer middleware handles the file parsing on the server side.
PATCH /api/users/:id
Authorization: Bearer <token>
Content-Type: multipart/form-data

name=Juan
lastName=Perez
photo=<binary file>
Uploaded photos are stored in the /uploads directory on the server and served as static assets. The photo field on the User record stores the relative path to the file.
An Admin can update any user’s profile. A Customer can only update their own profile — the middleware validates that req.user.id === params.id for Customer-role requests.

Users API Reference

Full endpoint reference for all user and role management endpoints, including request/response schemas and error codes.

Build docs developers (and LLMs) love