Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Luisangelebp/SCO_Autolavados/llms.txt

Use this file to discover all available pages before exploring further.

Sales records represent finalized invoices in SCO Autolavados. Each sale captures the USD exchange rate at the moment of transaction, links to an approved payment, and contains one or more line items — either completed service orders or physical products sold from inventory. Creating a sale atomically decrements inventory for any product line items.

Endpoints

GET /api/sales

Retrieve the full invoice history ordered by date descending. Each sale includes its nested line items (salesDetails) and the cashier (user) who registered it. If the sale is linked to a payment, the payment and customer details are also included. Authentication: Public — no token required.
curl http://localhost:3000/api/sales
Response 200 — Array of Sale objects:
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "date": "2026-06-26T11:30:00.000Z",
    "tazaUsd": 622.21,
    "totalUsd": 7.5,
    "paymentId": "p1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "userId": "u1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "user": {
      "name": "Admin",
      "lastName": "Sistema"
    },
    "payment": {
      "method": "Pago Movil",
      "mountUSD": 7.5,
      "mountBS": 4666.60,
      "approved": true,
      "customer": {
        "name": "María",
        "lastName": "González"
      }
    },
    "salesDetails": [
      {
        "id": "d1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "cant": 1,
        "UPriceUsd": 5.0,
        "serviceOrderId": "so1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "itemId": null,
        "serviceOrder": {
          "service": { "name": "Lavado Básico", "stimatedTimeMin": 30 }
        }
      },
      {
        "id": "d2b2c3d4-e5f6-7890-abcd-ef1234567890",
        "cant": 1,
        "UPriceUsd": 2.5,
        "serviceOrderId": null,
        "itemId": "i1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "item": { "name": "Ambientador Pino Nuevo" }
      }
    ]
  }
]

POST /api/sales

Register a finalized sale. This endpoint runs inside a database transaction: it creates the Sales record with all SalesDetails in a single operation and then decrements inventory for every product line item. If any product has insufficient stock, the entire transaction is rolled back and an error is returned. Authentication: Requires a valid JWT token with the ADMIN role.
tazaUsd is stored immutably on each sale record at the moment of creation. It is never updated retroactively. Always fetch the current BCV rate from GET /api/autolavado/exchange-rate immediately before building the sale payload — do not cache a rate across requests.

Request Body

tazaUsd
number
required
The USD → Bolívares exchange rate at the exact moment of the sale. Fetch this from GET /api/autolavado/exchange-rate before calling this endpoint.
totalUsd
number
required
Total sale amount in USD. Should equal the sum of cant × UPriceUsd across all detail lines.
userId
string (UUID)
required
ID of the cashier (ADMIN user) registering the sale.
details
array
required
Array of line items. Must contain at least one element. Each item must include either serviceOrderId (for a completed wash) or itemId (for a product from inventory), but not both.
details[].cant
number
required
Quantity of units for this line item.
details[].UPriceUsd
number
required
Unit price in USD for this line item.
details[].serviceOrderId
string (UUID)
UUID of a FINALIZADO service order. Mutually exclusive with itemId.
details[].itemId
string (UUID)
UUID of a product from inventory. Mutually exclusive with serviceOrderId. The inventory quantity will be decremented by cant inside the transaction.
paymentId
string (UUID)
UUID of an approved Payment record to link to this sale. Optional — walk-in cash transactions may not have a pre-registered payment.

Example — Full sale with a service line and a product line

This is the exact curl taken from the business flow at the point of checkout after María’s wash and store purchase:
curl -X POST http://localhost:3000/api/sales \
  -H "Authorization: Bearer <ADMIN_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "paymentId": "<ID_DEL_PAGO>",
    "tazaUsd": 622.21,
    "totalUsd": 7.5,
    "userId": "<ID_DEL_ADMIN>",
    "details": [
      {
        "cant": 1,
        "UPriceUsd": 5.0,
        "serviceOrderId": "<ID_ORDEN_SERVICIO>"
      },
      {
        "cant": 1,
        "UPriceUsd": 2.5,
        "itemId": "<ID_AMBIENTADOR_PINO>"
      }
    ]
  }'
Response 201 — Newly created Sale object:
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "date": "2026-06-26T11:30:00.000Z",
  "tazaUsd": 622.21,
  "totalUsd": 7.5,
  "paymentId": "p1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "userId": "u1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "salesDetails": [
    {
      "id": "d1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "cant": 1,
      "UPriceUsd": 5.0,
      "saleId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "serviceOrderId": "so1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "itemId": null
    },
    {
      "id": "d2b2c3d4-e5f6-7890-abcd-ef1234567890",
      "cant": 1,
      "UPriceUsd": 2.5,
      "saleId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "serviceOrderId": null,
      "itemId": "i1b2c3d4-e5f6-7890-abcd-ef1234567890"
    }
  ]
}
The POST response includes only the salesDetails nested array — it does not include the user or payment relations. Those expanded fields are only returned by GET /api/sales, which uses a wider include query. To display cashier or customer details after creating a sale, issue a subsequent GET request.
Error responses:
StatusCondition
400 / 500Missing required fields (tazaUsd, totalUsd, userId, or empty details)
500Insufficient inventory for a product line item — entire sale is rolled back
401Missing or invalid JWT token
403Caller does not have the ADMIN role

Sale Object Reference

FieldTypeDescription
idstringUUID of the sale record
datestringISO 8601 timestamp when the sale was recorded
tazaUsdnumberExchange rate (Bs per USD) locked at sale time
totalUsdnumberTotal amount charged in USD
paymentIdstring | nullUUID of the linked Payment, if any
userIdstringUUID of the cashier who registered the sale
userobjectCashier name and lastName
paymentobject | nullLinked payment details including customer info
salesDetailsarrayLine items — see SalesDetails below
SalesDetails fields:
FieldTypeDescription
cantnumberQuantity sold
UPriceUsdnumberUnit price in USD at time of sale
serviceOrderIdstring | nullLinked service order UUID (for wash lines)
itemIdstring | nullLinked inventory item UUID (for product lines)

Build docs developers (and LLMs) love