SansiStore’s courier module provides users with theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ProcesosAgilesUMSS/sansistore/llms.txt
Use this file to discover all available pages before exploring further.
mensajero role a mobile-optimized portal for managing their daily delivery route. Couriers accept assigned orders, navigate to customer locations using a built-in Leaflet map, collect cash on delivery, and close their shift with a summary at the end of the day. All delivery state is synced in real time via Firestore subscriptions.
The legacy route
/mensajero is a server-side redirect to /courier. All new development and links should use /courier.Courier portal pages
Courier dashboard
Session overview with three summary metrics: pending deliveries, deliveries completed today, and total cash to collect. Lists active pending orders in a table with inline actions for registering payment and marking as delivered.
Active deliveries
The messenger-facing view uses
DeliveryActionsPanel at /courier, which wraps MessengerDashboard and organises orders into five sidebar tabs: Gestión Entregas, Pedidos aceptados, Reprogramados, No entregados, and Entregados. Each tab renders order cards with contextual action buttons.Delivery detail
Individual delivery page rendered by
DeliveryOrderDetailPage. Shows full order info, customer location map link, cash amount to collect, and status-transition action buttons. Accessible at /delivery/order/{orderId}.Buyer map
Leaflet map page at
/mapa showing the customer’s location as a marker and the allowed delivery zones as polygon overlays. Opens via a deep link that passes lat, lng, and order as query parameters.Messenger shift model
Couriers work in day-long shifts. When a courier closes their shift, the platform writes a document to themessenger_shift_closures Firestore collection.
| Field | Type | Description |
|---|---|---|
id | string | Document ID, formatted as {courierId}_{dateKey} (e.g. uid-luis_2025-06-15) |
courierId | string | UID of the courier |
dateKey | string | Local date in YYYY-MM-DD format |
status | 'closed' | Always closed when the document exists |
startedAt | Timestamp | Earliest activity timestamp derived from the day’s orders |
closedAt | Timestamp | Server timestamp written at closure time |
summary.completedCount | number | Orders delivered and payment collected today |
summary.pendingCount | number | Orders still in assigned, accepted, or in_transit at closure |
summary.notDeliveredCount | number | Orders in not_delivered state |
summary.cancelledCount | number | Orders cancelled for non-payment |
summary.totalCollected | number | Sum of cashToCollect for all collected orders today |
A shift can only be closed once per day. If a document with
id = {courierId}_{dateKey} already exists, closeMessengerShift throws La jornada de hoy ya fue cerrada. The courier must contact an admin to reopen or correct the record.Delivery acceptance eligibility
A courier can only have one active delivery at a time. An active delivery is one with statusaccepted or in_transit. Deliveries in assigned, delivered, not_delivered, cancelled, reprogrammed, or pending_reassignment do not count as active.
The eligibility check is enforced in two layers:
Client-side (acceptEligibility.ts):
assertCanAcceptMessengerOrder):
Before any accepted write reaches Firestore, the service queries all deliveries documents for the courier and rejects the request if any sibling delivery is in accepted or in_transit. This server-side check prevents double-acceptance from multiple browser tabs or stale UI state.
If blocked, the UI displays the AcceptBlockedModal with the message:
Ya tienes una entrega activa (aceptada o en camino). Termínala antes de aceptar otro pedido.The
deliveryAvailability.ts library used by the admin panel exposes countActiveDeliveriesByCourier and isCourierAvailableFromActiveCount for a courier-level availability check from the admin assignment view. A courier is considered available only when their active delivery count is 0.
Order visibility rules
ThegetVisibleMessengerOrders utility de-duplicates the deliveries subscription so each order ID appears only once in the courier’s list. When the same orderId is associated with multiple delivery documents (e.g. after a reprogramming), the rule is:
- Higher status priority wins. The priority order is:
assigned / reprogrammed(1) →accepted(2) →in_transit(3) →not_delivered / pending_reassignment / cancelled(4) →delivered(5). - If same priority: the document with the most recent
updatedAt/assignedAt/createdAttimestamp wins. - If same timestamp: the document with the lexicographically greater
deliveryIdwins.
Cash collection
All deliveries in SansiStore are cash-on-delivery (paymentMethod: 'cash_on_delivery'). The amount the courier must collect is stored in the delivery document as cashToCollect, which is derived from delivery.amountCollected or, if absent, from the linked payment.amount or order.total.
When the courier registers a payment (registerMessengerCashPayment), a single writeBatch atomically updates:
orders/{orderId}→paymentStatus: 'COBRADO',paymentCollectedAt,collectedBydeliveries/{deliveryId}→amountCollected,customerConfirmed: true,status: 'delivered'payments/{paymentId}→status: 'COBRADO',collectedAt,collectedBy
formatBolivianos, which rounds floating-point noise before rendering (e.g. 302.59999999999997 → Bs 302.6).
Daily courier workflow
Start the shift
The courier logs in at
/courier. The DeliveryActionsPanel component (which wraps MessengerDashboard) subscribes to all deliveries where courierId == currentUser.uid. Any orders in assigned status appear immediately in the Gestión Entregas tab.Accept assigned deliveries
The courier taps Aceptar pedido on an assigned order card. A confirmation dialog (
ConfirmAssignedOrderActionModal) appears before any write. On confirmation, acceptMessengerOrder first runs the server-side eligibility check, then transitions the delivery to accepted.Only one delivery can be in accepted or in_transit at a time. If the check fails, the AcceptBlockedModal is shown instead.Start transit
From the delivery detail page at
/delivery/order/{orderId}, the courier taps Iniciar entrega. This transitions status to in_transit and records inTransitAt on the delivery document.Collect payment and confirm delivery
On arrival at the customer’s location, the courier:
- Taps Registrar pago — records
paymentCollectedAtand marks payment asCOBRADO. - Taps Marcar como entregado (enabled only after payment is registered) — transitions delivery to
deliveredand setscustomerConfirmed: true.
UndeliveredModal or CancelNoPaymentModal. Both actions write the incident reason to the delivery document and update the order status.Close the shift
At the end of the day, the courier taps Cerrar jornada. The platform calls
closeMessengerShift, which builds a MessengerShiftClosure snapshot from all of the day’s orders and writes it to messenger_shift_closures. The closure is permanent — a new shift begins automatically the next day.