The POS terminal is the primary tool for store employees and admins processing in-store sales. It is optimised for speed — barcode scanning adds items to the cart instantly, and keyboard shortcuts reduce mouse interaction. The search input is auto-focused on page load and re-focused after every successful scan or item addition, keeping the operator’s hands on the keyboard or scanner at all times.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/DragonesMagicos/ferromax_v0.8/llms.txt
Use this file to discover all available pages before exploring further.
How the POS Works
Search or scan a product
The operator types a product name, SKU, or scans a barcode directly into the search field. The terminal detects scanner input by measuring the time elapsed per character — if the input arrives faster than 30 ms/character and has at least 4 characters, it is treated as a barcode scan.Product lookup follows this priority order:
GET /api/productos/empleado/barcode/{codigo}— exact barcode matchGET /api/productos/empleado/sku/{sku}— exact SKU match- Name substring search across all active products (manual typing only)
/api/productos/barcode/{codigo}, /api/productos/sku/{sku}) which may return additional pricing or supplier fields.Product appears in the cart
A matched product is added to the cart immediately. If the product is already in the cart, its quantity is incremented by 1. The
POSCarrito component (components/pos/POSCarrito.jsx) renders each line item with the product name, SKU, per-unit price, line subtotal, and +/− quantity controls.Adjust quantities
The operator can tap + or − next to any cart line to change the quantity. Setting a quantity to 0 removes the item from the cart. A Vaciar (clear) button at the bottom of the cart list empties everything in one click.
Select a payment method
Four payment method buttons are shown in a 2×2 grid on the right panel. The operator selects one before confirming the sale. When Efectivo (cash) is chosen, an extra field appears to enter the amount tendered and the change due is calculated live.
Confirm the sale
The operator taps COBRAR. The frontend POSTs to:The backend extracts the
cajeroId and role from the JWT. Because the role is ADMIN or EMPLEADO, the origin is automatically set to OrigenVentaEnum.POS.Stock updates and ticket modal
On a
201 Created response, the cart is cleared, a ModalTicket slides in showing the full receipt (line items, subtotal, discount if any, total, and payment method), and a WebSocket event fires to /topic/stock/{productoId} for every product sold. All other connected clients — including the dashboard — receive the updated stock level in real time.Payment Methods
These values correspond directly toMedioPagoEnum in the backend:
| Enum value | Label | Icon |
|---|---|---|
EFECTIVO | Efectivo (cash) | Banknote |
DEBITO | Débito (debit card) | CreditCard |
CREDITO | Crédito (credit card) | Building2 |
MERCADOPAGO | MP (MercadoPago) | CreditCard |
medioPago field of VentaRequest. Only one method can be active per sale.
Sale Origin
OrigenVentaEnum records how and where a sale was made. The backend sets this value automatically — it is never sent by the frontend.
| Role | Origin assigned |
|---|---|
ADMIN | POS |
EMPLEADO | POS |
CLIENTE | WEB |
origen field is stored on the Venta entity and returned in VentaResponse, making it easy to filter sales by channel in reports.
Access
The POS terminal is accessible to ADMIN and EMPLEADO roles. The route is:@PreAuthorize annotation on POST /api/ventas is: