When a client is ready to purchase, AutoPart Pro carries their cart through a three-stage flow: items are held in React state (andDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/JFKoryy/autopart-pro/llms.txt
Use this file to discover all available pages before exploring further.
localStorage) via CartContext, the Checkout page collects shipping details and submits a single POST /api/sales request, and the server atomically records the order and deducts stock for every line item inside a MySQL transaction. The entire operation either commits fully or rolls back — there is no partial state.
Cart State (Frontend)
CartContext is a React context provider that lives at frontend/src/context/CartContext.jsx. It manages the in-memory cart and persists it to localStorage so items survive page refreshes.
items, addItem, updateQty, removeItem, clearCart, count, and total to any component wrapped inside <CartProvider>.
Checkout Flow
Browse the catalog and add items
On the Catalog page (
/catalogo) the client clicks Add to Cart on a ProductCard. The card calls addItem(product) from useCart(), which merges the product into the cart state and increments its quantity if it already exists.Review the cart
Navigating to
/carrito opens the Cart.jsx page. The client can adjust quantities with the + / − controls (which call updateQty) or remove individual lines with the trash icon (removeItem). A summary panel shows the running subtotal.Proceed to checkout
Clicking Proceder al pago navigates to
/checkout. The Checkout.jsx page collects shipping details and renders a payment-gateway placeholder. The grand total includes a flat shipping fee of 10 000 on top of the cart subtotal.Submit the order
On form submission,
Checkout.jsx calls checkout(items) from api.js, which maps the cart into the wire format and sends it to the backend:Server records the sale and deducts stock
The
createSale controller passes the authenticated user’s ID and the items array to SaleModel.create(), which runs everything inside a single MySQL transaction (see below).Server-Side Transaction
SaleModel.create() in backend/src/models/saleModel.js uses an explicit MySQL connection to guarantee atomicity:
sum(quantity × unit_price) across all items, so a client cannot manipulate the total by altering the request payload after the unit prices are set.
Checkout Request & Response
Request —POST /api/sales
Requires a valid JWT (Authorization: Bearer <TOKEN>).
201 Created
400:
Viewing Sales History
GET /api/sales returns order history scoped to the caller’s role:
- Admin — calls
SaleModel.getAll(), which returns every sale in the system joined with user details. - Client / Employee — calls
SaleModel.getByUser(req.user.id), which filters byuser_id.
items array assembled via MySQL’s JSON_ARRAYAGG:
The
user_name and user_email fields only appear in the admin view (SaleModel.getAll()). The client-scoped query (getByUser) omits those fields since the buyer is already known from the JWT.Related Pages
Inventory Management
Understand the product data model that backs each sale line item.
User Roles
See how
POST /api/sales is protected and how admin vs. client sales visibility is enforced.