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.

Every person who walks through the gym door is represented as a Client record. The client model captures identity, contact, membership plan, payment, and attendance data in a single entity. This page covers the full lifecycle of a client record — from creation at the front desk to eventual expiry and deletion.
Email addresses were intentionally removed from the client model. Phone number (telefono) is the unique identifier used for member lookup and search. This decision simplifies the enrollment flow and removes a field that gym staff rarely need.

Client Data Model

The table below lists every field stored in the clients database table, its type, and whether it is required at creation time.
FieldTypeRequiredNotes
idString (UUID)AutoGenerated by the database on creation.
nombreStringFirst name(s).
apellidosStringLast name(s).
generoGenero enumMasculino | Femenino | Otro
telefonoStringUsed as the primary search identifier.
planStringMust match the name of an active Plan record.
montoDecimal (MXN)Amount charged at enrollment or last renewal.
metodoPagoPaymentMethod enumEfectivo | Tarjeta | Transferencia
statusClientStatus enumAutoDefaults to ACTIVO on creation.
ultimaVisitaString (HH:MM)AutoLast check-in time. Defaults to "--:--".
vencimientoDateTimeAutoCalculated from the plan period at creation.
fotoUrlString?Cloudinary URL. Null if no photo uploaded.
attendanceDateDateTime?AutoFull timestamp of the most recent check-in.
createdAtDateTimeAutoSet by the database on insert.
updatedAtDateTimeAutoUpdated automatically on every change.

Creating a Client

New clients are created via POST /api/clients. The request body must include all required fields. fotoUrl is the only optional field.
{
  "nombre": "Carlos",
  "apellidos": "Ramírez Ortiz",
  "genero": "Masculino",
  "telefono": "5512345678",
  "plan": "Mensual",
  "monto": 450,
  "metodoPago": "Efectivo",
  "fotoUrl": "https://res.cloudinary.com/example/image/upload/v1/photo.jpg"
}
The backend performs the following steps on creation:
  1. Validates that all required fields are present.
  2. Validates that genero is one of Masculino, Femenino, or Otro.
  3. Looks up the plan by name and confirms it is active (isActive = true).
  4. Calculates the expiry date by adding the plan’s period (in months) to the current date.
  5. Creates the record with status = ACTIVO and ultimaVisita = "--:--".
On success the API returns HTTP 201 with the full client object.

Photo Upload

Profile photos are hosted on Cloudinary. Upload the image to Cloudinary first (via the /upload endpoint exposed by the frontend or a direct Cloudinary API call), then pass the returned URL as fotoUrl in the client creation payload. The field is entirely optional — the reception UI falls back to a placeholder image when fotoUrl is null.

Expiry Date Calculation

The expiry date is computed at the moment of enrollment based on the selected plan’s period field. The mapping is:
Period valueMonths added
"Mes"1
"3 Meses" / "trimestral"3
"6 Meses" / "semestral"6
"Año" / "anual"12
The same logic is applied during renewal. See Memberships for details.

Searching Clients

GET /api/clients accepts the following optional query parameters to filter results:
ParameterTypeBehaviour
searchStringCase-insensitive partial match on nombre, apellidos, or telefono.
statusStringExact match. Accepts ACTIVO, VENCIDO, or PENDIENTE.
planStringExact match on the plan name string.
Parameters can be combined freely. Results are always ordered by createdAt descending (newest first).
# Search by name fragment
GET /api/clients?search=Carlos

# All expired clients on the Mensual plan
GET /api/clients?status=VENCIDO&plan=Mensual

# Combined: active clients whose phone contains "551"
GET /api/clients?search=551&status=ACTIVO

Editing a Client

PUT /api/clients/:id updates an existing client record. This endpoint is admin-only. Any subset of the following fields can be included in the request body:
{
  "nombre": "Carlos Alberto",
  "telefono": "5598765432",
  "plan": "Trimestral",
  "monto": 1200,
  "metodoPago": "Tarjeta",
  "fotoUrl": "https://res.cloudinary.com/example/image/upload/v2/new_photo.jpg"
}
Fields omitted from the body retain their current values. The status, vencimiento, ultimaVisita, and attendanceDate fields cannot be changed through this endpoint — they are managed by dedicated attendance and renewal endpoints.

Deleting a Client

DELETE /api/clients/:id permanently removes the client record and all associated attendance rows (cascade delete). This endpoint is admin-only.
Client deletion is permanent and irreversible. All attendance history linked to the client is also deleted via the onDelete: Cascade constraint defined in the Prisma schema. Consider setting the client’s status to PENDIENTE instead of deleting if you need to retain historical data.

Status Lifecycle

Every client record carries a status field that reflects the current state of their membership.
The default status set at creation and restored after every successful renewal. The client can check in and use the gym’s services. The attendance button in Reception is enabled.
Applied automatically when the current date passes the vencimiento date. The attendance button in Reception is disabled with the label MEMBRESÍA VENCIDA. The client record is retained in full; the member cannot check in until the membership is renewed.
A manual status flag that staff can set on a client to mark them for follow-up (e.g., awaiting payment confirmation, incomplete enrollment). While PENDIENTE, check-in is also blocked. The transition from VENCIDO to PENDIENTE is intentional — PENDIENTE does not auto-expire back to VENCIDO.
The typical flow is:
[Enrollment] → ACTIVO → VENCIDO (automatic, date-based) → PENDIENTE (manual)
                  ↑                                              |
                  └──────────── ACTIVO (after renewal) ─────────┘

Build docs developers (and LLMs) love