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 Inventory module gives you a complete picture of every physical product sold at Spartans Gym. Admins can create new products, update details, adjust stock counts, and delete records — including the associated Cloudinary image. Receptionists have read-only access to the same data and can browse or filter without making changes.

Product Data Model

Each product stored in the database has the following fields:
FieldTypeDescription
idIntAuto-incremented primary key
nameStringDisplay name of the product
priceDecimal(10,2)Unit price in MXN
catCategoryOne of: Suplementos, Bebidas, Snacks, Merchandising, Accesorios
skuString (unique)Stock-keeping unit identifier
stockIntCurrent units available
reorderIntMinimum threshold before “Stock Bajo” status triggers (default: 5)
imageString?Cloudinary URL, or null if no image has been uploaded
createdAtDateTimeRecord creation timestamp
updatedAtDateTimeLast modification timestamp

Stock Status

The backend calculates a status string for every product based on its stock and reorder values. The frontend uses this to render color-coded badges:

En Stock

stock > reorder — shown with a green badge. The product is well-stocked.

Stock Bajo

stock > 0 and stock <= reorder — shown with an orange badge. Time to reorder.

Agotado

stock <= 0 — shown with a red badge. The product cannot be sold from POS.

Inventory Stats

Four summary cards appear at the top of the page, recalculated whenever the product list changes:
  • Total Productos — total number of products in the catalog
  • Stock Bajo — count of products with stock > 0 and stock <= reorder
  • Agotados — count of products with stock === 0
  • Valor Estimado — sum of price × stock across all products, formatted in MXN

Browsing the Catalog

The inventory table is paginated at 8 items per page. Use the numbered page buttons or the previous/next arrows at the bottom to navigate. The total count shown in the footer always reflects the currently filtered set.

Category Filter

A segmented control above the list lets you restrict the view to a single category. The available options match the Category enum: Todos, Suplementos, Merchandising, Bebidas, Accesorios, and Snacks. Switching filters resets pagination to page 1.

Responsive Layout

On large screens the inventory renders as a full table with columns for Product (name + SKU + thumbnail), Category, Current Stock, Price, Status, and Actions. Edit and Delete buttons appear in the Actions column for admins; receptionists see “Solo lectura” in that column instead.

Managing Products (Admin Only)

Admin users see an Añadir Stock button at the top right of the page. Receptionists do not see this button, and the edit/delete controls are hidden from them throughout the interface.

Adding a Product

Click Añadir Stock to open the product form modal.
1

Enter product details

Fill in Nombre del producto and Precio ($). Both are required.
2

Select category

Choose one of the five categories from the dropdown: Suplementos, Bebidas, Snacks, Merchandising, or Accesorios.
3

Set SKU

Enter a custom SKU in the SKU field. If you leave it blank, the frontend auto-generates one in the format SKU-{random 3-digit number}.
4

Set stock and reorder point

Enter the current Stock actual and the Stock mínimo (reorder threshold). The reorder threshold defaults to 5 if left empty.
5

Upload image (optional)

Click the image area to open a file picker. The selected image is uploaded as multipart/form-data to POST /api/products. The backend sends the file buffer to Cloudinary via the uploadImage service and stores the resulting URL in the image field.
6

Save

Click Guardar producto. The new product is prepended to the product list.
SKU values must be unique across the entire product catalog. If you submit a SKU that already belongs to another product, the API returns HTTP 400 with the message "Ya existe un producto con este SKU". Choose a different SKU and try again.
Image uploads are handled via multer in the Express backend. The image is read into memory as a buffer (not saved to disk) before being streamed to Cloudinary, so upload speed depends on the file size. Keep product images under a few megabytes for the best experience.

Editing a Product

Click Editar on any product row or card (admin only) to reopen the form pre-filled with the existing values.
  • To replace the image, click the image area and select a new file. The old Cloudinary asset is deleted automatically before the new one is uploaded.
  • To remove the image entirely, clear the preview (the frontend sends removeImage: "true" in the form data). The backend calls deleteImage on the old Cloudinary public ID and sets image to null.
  • Changes are submitted to PUT /api/products/:id.

Deleting a Product

Click Eliminar on any product row or card (admin only). A confirmation dialog appears with the product name and a warning that the action cannot be undone. Confirming sends DELETE /api/products/:id. If the product has an associated Cloudinary image, the backend deletes it from Cloudinary before removing the database record.

Adjusting Stock

Admins can set a product’s stock to any absolute value by sending PATCH /api/products/:id/stock with a stock field in the request body. This endpoint is used for manual inventory corrections and does not go through the product edit form in the current UI.
// PATCH /api/products/:id/stock
{
  "stock": 50,
  "reason": "Restock from supplier"
}
The response includes the updated product with a recalculated status field.

API Reference

MethodPathAuthDescription
GET/api/productsAnyList all products; supports ?category= and ?search= query params
GET/api/products/:idAnyGet a single product by ID
POST/api/productsAdminCreate a product (multipart/form-data)
PUT/api/products/:idAdminUpdate a product (multipart/form-data)
DELETE/api/products/:idAdminDelete a product and its Cloudinary image
PATCH/api/products/:id/stockAdminManually set absolute stock value

Build docs developers (and LLMs) love