Lewati ke konten utama

Admin Commerce Modules

The Commerce group in the ops panel (ops.pasarseken.id) gives admins financial and logistical visibility into the live platform. Four modules: Escrow Manager, Logistics Hub, Logistics Heatmap, and Voucher Engine.


Escrow Manager​

KPI cards​

CardSource
Total Held in Escroworders, sum of total_paid where funds_status = "HELD"
Frozen (Disputes)orders, sum of total_paid in dispute states
Ready for Payoutorders, sum of item_price for COMPLETED orders
BPF Revenueledger_entries, sum of protection fee entries

The Escrow Balance Trend area chart shows daily held vs released for the last 7 days, computed from getCachedOrders().

Endpoints​

EndpointPurpose
GET /admin/escrow-summary-liveLive KPIs, reads orders + ledger cache
GET /admin/escrow-trend7-day held/released trend, reads orders cache
POST /admin/escrow-check/runTrigger escrow automation timer

Implementation notes​

  • _ledgerCacheInst in shared-cache.tsx must have fetchFn: getLedgerFromTable pointing to SupabaseOrderRepository.findAllLedgerEntries(). Without it, getCachedLedger() reads from the retired KV prefix ledger: and always returns empty, BPF Revenue shows Rp 0. (Fixed PS-360, 2026-05-12.)
  • Allowed roles for escrow endpoints: administrator, finance.

Logistics Hub​

What it shows​

  • Active Shipments table: all shipments with order context: seller name, buyer name, order status, funds status.
  • Late Orders table: orders in SHIPPED status for more than 72 hours.

Endpoint​

GET /admin/shipments

The shipments table only stores: id, order_id, courier, tracking_no, status, extra, created_at, updated_at. It does not store seller_name, buyer_name, order_status, or funds_status.

The endpoint fetches getCachedOrders() in parallel with shipmentRepo.findAllRaw(), builds an order_id → order map, and merges the four missing fields into each shipment row before pagination.


Logistics Heatmap (Logistics Control Tower)​

Three panels​

  1. Indonesia map: SVG regions colored by delivery speed status.
  2. Courier Health: per-courier on-time rate, average delivery days, active shipments.
  3. Waybill Management: full shipment table with search, filter, sort, and per-row refresh.

Region status vocabulary​

Computed from avgDeliveryDays in GET /admin/logistics-stats:

avgDeliveryDaysstatusColor
≤ 2fastTeal (#006D77)
≤ 3normalBlue (#3B82F6)
≤ 5slowOrange (#F97316)
> 5delayedRed (#EF4444)

The frontend statusColor() function in LogisticsHeatmap.tsx handles exactly these four values. Any other value renders gray.

Waybill refresh​

Each row has a refresh button that calls GET /shipping/track/:tracking_no?courier=<code>. On success, the row's status and last-update timestamp are updated in local state and the latest courier status appears in a success toast. Rows with no tracking number ("N/A") show an error toast immediately without hitting the API.


Voucher Engine​

Voucher types​

TypeColorBehaviour
flat_discountTeal (#006D77)Fixed IDR amount off
percentageAmber (#F59E0B)Percentage off, optionally capped
free_shippingGreen (#059669)Waives shipping cost
bpf_waiverBlue (#2563EB)Waives buyer protection fee

CRUD endpoints​

All five endpoints accept roles administrator and marketing:

MethodPathAction
GET/admin/vouchersList all vouchers + aggregate stats
POST/admin/vouchersCreate voucher
PUT/admin/vouchers/:idUpdate voucher fields
PUT/admin/vouchers/:id/statusActivate or deactivate
DELETE/admin/vouchers/:idSoft-delete (sets deleted_at)

Constraints​

  • Purple (#8B5CF6) is banned from VoucherEngine.tsx per BRAND-01. Use amber (#F59E0B) for the percentage type chip and green (#10B981) for positive revenue metrics.
  • Both administrator and marketing roles must be in every voucher endpoint's role array. Marketing-only restriction locks out ops admins.