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.

The Products API manages everything sold at the Spartans Gym front desk: supplements, drinks, snacks, accessories, and branded merchandise. Each product tracks its current stock against a configurable reorder threshold, and every response includes a computed status field that tells you at a glance whether a product is fully stocked, running low, or sold out. Product images are stored on Cloudinary — the API handles uploads, replacements, and deletions automatically. All endpoints require a valid Bearer token; write operations are restricted to admin users.

The Product Object

id
integer
required
Auto-incremented integer identifier for the product.
name
string
required
Display name of the product.
price
number
required
Retail price in MXN (Decimal(10,2) in the database, returned as a JavaScript number).
cat
string
required
Product category. One of Suplementos, Bebidas, Snacks, Merchandising, or Accesorios.
sku
string
required
Stock-Keeping Unit — a unique identifier string for the product. Enforced as unique at the database level.
stock
integer
required
Current quantity on hand.
reorder
integer
required
Reorder threshold. When stock falls to or below this value the computed status changes to "Stock Bajo". Defaults to 5 on creation.
image
string | null
Cloudinary URL for the product image, or null if no image has been uploaded.
status
string
required
Computed field (not stored in the database). Derived from stock and reorder at query time:
ConditionStatus
stock <= 0"Agotado"
stock <= reorder"Stock Bajo"
stock > reorder"En Stock"
createdAt
string
required
ISO 8601 datetime when the product was created.
updatedAt
string
required
ISO 8601 datetime when the product was last modified.

Endpoints

List Products

Requires a valid Bearer token. Accessible to all roles (admin and recepcionista).
Returns all products ordered by creation date descending. The status field is computed on every item in the response. All query parameters are optional.
GET /api/products
Query Parameters
category
string
Filter by category. Accepted values: Suplementos, Bebidas, Snacks, Merchandising, Accesorios. Pass Todos or omit to return all categories.
Case-insensitive substring match against the product name.
Success Response — 200 OK
{
  "success": true,
  "data": [
    {
      "id": 12,
      "name": "Proteína Whey Chocolate 1kg",
      "price": 699,
      "cat": "Suplementos",
      "sku": "WHEY-CHOC-1K",
      "stock": 8,
      "reorder": 5,
      "image": "https://res.cloudinary.com/spartans/image/upload/v1/products/whey-choc.jpg",
      "status": "En Stock",
      "createdAt": "2025-06-01T10:00:00.000Z",
      "updatedAt": "2025-07-10T09:00:00.000Z"
    },
    {
      "id": 11,
      "name": "Bebida Isotónica Limón",
      "price": 35,
      "cat": "Bebidas",
      "sku": "ISOT-LIM-500",
      "stock": 3,
      "reorder": 10,
      "image": null,
      "status": "Stock Bajo",
      "createdAt": "2025-06-01T10:00:00.000Z",
      "updatedAt": "2025-07-12T08:00:00.000Z"
    }
  ]
}
Error Responses
StatusDescription
401Missing or invalid Bearer token.
403Insufficient role.
500Internal server error.

Get Product by ID

Requires a valid Bearer token. Accessible to all roles.
Retrieves a single product with its computed status.
GET /api/products/:id
Path Parameters
id
integer
required
The numeric ID of the product.
Success Response — 200 OK Returns a single Product object (including computed status) inside data. Error Responses
StatusDescription
401Missing or invalid Bearer token.
403Insufficient role.
404No product found with the given ID.
500Internal server error.

Create Product

Requires role admin only.
This endpoint uses multipart/form-data, not application/json, because it accepts an optional image file upload. Set your request’s Content-Type to multipart/form-data (most HTTP clients and <form> elements do this automatically when a file field is included).
Creates a new product. If an image file is included, it is uploaded to Cloudinary and the returned URL is stored in image. The sku must be unique — a 400 is returned if a product with that SKU already exists.
POST /api/products
Request Body (multipart/form-data)
name
string
required
Product display name.
price
number
required
Retail price in MXN. Sent as a form string; the server parses it with parseFloat.
cat
string
required
Category. One of Suplementos, Bebidas, Snacks, Merchandising, Accesorios.
sku
string
required
Unique SKU string. Returns 400 if already in use.
stock
integer
Initial stock quantity. Defaults to 0 if omitted.
reorder
integer
Reorder threshold. Defaults to 5 if omitted.
image
file
Optional product image. Must be a valid image file; uploaded to Cloudinary on success. Returns 400 if the upload fails.
Success Response — 201 Created
{
  "success": true,
  "data": {
    "id": 15,
    "name": "Proteína Whey Vainilla 2kg",
    "price": 1299,
    "cat": "Suplementos",
    "sku": "WHEY-VAN-2K",
    "stock": 20,
    "reorder": 5,
    "image": "https://res.cloudinary.com/spartans/image/upload/v1/products/whey-van.jpg",
    "status": "En Stock",
    "createdAt": "2025-07-16T15:00:00.000Z",
    "updatedAt": "2025-07-16T15:00:00.000Z"
  }
}
Error Responses
StatusDescription
400Missing required fields, duplicate SKU, or Cloudinary upload failure.
401Missing or invalid Bearer token.
403User is not an admin.
500Internal server error.
curl -X POST https://api.example.com/api/products \
  -H "Authorization: Bearer <token>" \
  -F "name=Proteína Whey Vainilla 2kg" \
  -F "price=1299" \
  -F "cat=Suplementos" \
  -F "sku=WHEY-VAN-2K" \
  -F "stock=20" \
  -F "reorder=5" \
  -F "image=@/path/to/whey-van.jpg"

Update Product

Requires role admin only.
Like POST /api/products, this endpoint also uses multipart/form-data to support image file replacement. Supply only the fields you wish to change.
Partially updates a product. Image management follows these rules:
  • No image changes: omit both image and removeImage — the existing image URL is preserved.
  • Remove image: include removeImage=true in the form data. The existing Cloudinary asset is deleted and image is set to null.
  • Replace image: include a new image file. The existing Cloudinary asset is deleted before the new one is uploaded.
PUT /api/products/:id
Path Parameters
id
integer
required
Numeric ID of the product to update.
Request Body (multipart/form-data) (all fields optional)
name
string
Updated product name.
price
number
Updated retail price in MXN.
cat
string
Updated category.
sku
string
Updated SKU. Returns 400 if a different product already uses this value.
stock
integer
Updated stock quantity.
reorder
integer
Updated reorder threshold.
removeImage
string
Pass "true" to delete the existing Cloudinary image and set image to null. Ignored if a new image file is also provided (replacement takes priority).
image
file
New image file. Replaces the existing image: the old Cloudinary asset is deleted first, then the new file is uploaded.
Success Response — 200 OK Returns the full updated Product object (including computed status) inside data. Error Responses
StatusDescription
400Duplicate SKU or Cloudinary upload failure.
401Missing or invalid Bearer token.
403User is not an admin.
404No product found with the given ID.
500Internal server error.

Delete Product

Requires role admin only. This is a hard delete — the product record is permanently removed. If the product has a Cloudinary image, it is also deleted from Cloudinary before the database record is removed.
Permanently deletes a product and its associated Cloudinary image (if any).
DELETE /api/products/:id
Path Parameters
id
integer
required
Numeric ID of the product to delete.
Success Response — 200 OK
{
  "success": true,
  "message": "Producto eliminado correctamente"
}
Error Responses
StatusDescription
401Missing or invalid Bearer token.
403User is not an admin.
404No product found with the given ID.
500Internal server error.
curl -X DELETE https://api.example.com/api/products/15 \
  -H "Authorization: Bearer <token>"

Adjust Stock

Requires role admin only.
Sets the absolute stock level for a product. This is not an increment/decrement operation — the value you provide becomes the new stock. Use this for inventory corrections, physical counts, or manual adjustments. An optional reason string is logged server-side for audit purposes but is not persisted to the database.
PATCH /api/products/:id/stock
Path Parameters
id
integer
required
Numeric ID of the product to adjust.
Request Body
stock
integer
required
New absolute stock value. Must be a non-negative integer. Setting this to 0 will result in a computed status of "Agotado".
reason
string
Optional human-readable reason for the adjustment (e.g. "Inventario físico julio 2025"). Logged to server output for audit trails but not stored in the database.
Success Response — 200 OK
{
  "success": true,
  "data": {
    "id": 12,
    "name": "Proteína Whey Chocolate 1kg",
    "price": 699,
    "cat": "Suplementos",
    "sku": "WHEY-CHOC-1K",
    "stock": 15,
    "reorder": 5,
    "image": "https://res.cloudinary.com/spartans/image/upload/v1/products/whey-choc.jpg",
    "status": "En Stock",
    "createdAt": "2025-06-01T10:00:00.000Z",
    "updatedAt": "2025-07-16T17:00:00.000Z"
  }
}
Error Responses
StatusDescription
400stock field is missing from the request body.
401Missing or invalid Bearer token.
403User is not an admin.
404No product found with the given ID.
500Internal server error.
curl -X PATCH https://api.example.com/api/products/12/stock \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "stock": 15, "reason": "Inventario físico julio 2025" }'

Build docs developers (and LLMs) love