Skip to content

Logistics

Purpose

Akshaya Logistics provides rural shipment operations, Commerce fulfilment support, customer tracking, routes, hubs, pickup/delivery partners, drivers, vehicles and a simple logistics billing ledger.

Current functional status

The application is now D1-backed. Browser localStorage is no longer the source of truth for shipments, routes, hubs, partners or billing.

The Logistics hostname has an app-specific Cloudflare Worker. Static React assets are served by Worker Static Assets, while /api/* routes run Worker-first.

Two access levels are intentionally separated:

  • public/customer-safe routes: shipment tracking plus active hubs/partners
  • operational routes: /api/ops/*, available only after signing in with an existing Akshaya Admin account from the shared D1 identity store

The Logistics site creates its own host-only Admin session cookie. It does not use Cloudflare Access seats and does not create another Admin identity database.

Source directory

apps/logistics-web/

  • src/ — React storefront/operations UI
  • worker/entry.ts — Worker entry and Admin-authenticated bridge to central protected fulfilment
  • worker/index.ts — Logistics API, Admin session boundary and direct D1 operations
  • worker/logistics.ts — validation and shipment status rules
  • worker/*.test.ts — Logistics-specific tests

Framework

React 18 + TypeScript + Vite + Cloudflare Worker Static Assets + D1.

Commands

npm run dev:logistics
npm run build:logistics
npm run configure:logistics:operations-token
npm run deploy:logistics

The root npm test also runs Logistics Worker tests.

Output

apps/logistics-web/dist/ plus the Worker entry point apps/logistics-web/worker/entry.ts.

Deployment mechanism

Cloudflare Worker akshaya-logistics, custom domain:

logistics.akshayagroupglobal.com

apps/logistics-web/wrangler.jsonc binds:

  • ASSETS — built React application
  • DB — shared akshaya-group-global D1 database
  • API_BASE_URL — non-secret central API base URL

run_worker_first is restricted to /api/*; other paths use SPA/static-asset handling.

Required secret

OPERATIONS_API_TOKEN must be configured on the Logistics Worker with the same value already used by workers/api and commerce-web:

npm run configure:logistics:operations-token

The secret exists only in the Worker runtime. It is never exposed in Vite variables, React source, browser responses or logs. Logistics uses it only after a valid Logistics Admin session has already authorized the operator, to call the central protected Commerce fulfilment routes server-to-server.

Admin sign-in itself uses the existing shared users, auth_sessions and auth_audit tables and requires no additional identity secret.

Data model

Migration 0011_logistics_operations.sql evolves the existing shipments table additively and adds:

  • logistics_routes
  • logistics_hubs
  • logistics_partners
  • logistics_drivers
  • logistics_vehicles
  • shipment_events
  • logistics_invoices

Additional shipment fields cover address/network assignment, driver/vehicle assignment, estimated delivery, delivery timestamps and operational notes.

There is no hard-delete route for operational records. Shipment lifecycle is retained through status plus shipment_events; master records use Active/Inactive or equivalent lifecycle states.

Commerce → Logistics identity and fulfilment flow

Commerce orders already store the authenticated Customer user_id and immutable checkout delivery address.

A signed-in Logistics Admin sees the Commerce fulfilment queue inside the Shipments screen. The browser calls the Logistics Worker only. The Worker then calls the central protected operations API with its Worker-only OPERATIONS_API_TOKEN:

Admin browser
  -> Logistics host-only Admin session
  -> Logistics Worker /api/ops/commerce-orders/:id/fulfil
  -> central API /api/commerce/orders/:id/fulfil
  -> D1 shipment + order shipment_id

The central fulfilment endpoint is idempotent for an order that already has shipment_id and creates the shipment with the same Customer user_id.

Migration 0011_logistics_operations.sql adds a D1 trigger that, for shipments created from a Commerce order, hydrates the new shipment from order_address rather than leaving the historical placeholder Pending Address destination.

The resulting ownership chain remains:

Authenticated Customer
  -> Commerce order.user_id
  -> Logistics shipment.user_id
  -> Customer Account orders + shipments

A shipment insert also creates its initial shipment_events row automatically, including Commerce fulfilment shipments created by the protected central API.

Shipment lifecycle

Supported statuses:

Ready
Assigned
In Transit
Out for Delivery
Delivered
Exception
Cancelled

The Worker enforces allowed transitions. Delivered and Cancelled are terminal. Every actual status change adds a shipment_events record. When an order-linked shipment moves to transit, the Commerce order is updated to Shipped; delivery updates it to Delivered.

Assigned vehicles are returned to Available when a shipment reaches Delivered or Cancelled.

Public routes

POST /api/tracking
GET  /api/public/stats
GET  /api/public/hubs
GET  /api/public/partners

Tracking requires both shipment ID and the mobile number attached to that shipment. The public response is field-allowlisted: it does not return customer name, mobile, complete address, user ID, internal driver/vehicle IDs or billing details.

Admin authentication routes

POST /api/auth/login
POST /api/auth/logout
GET  /api/auth/session

Only an existing Active Admin user can establish a Logistics operations session. Password verification and lockout use the same PBKDF2 parameters and shared account fields as the central Admin Worker.

Protected operational routes

GET       /api/ops/summary
GET/POST  /api/ops/shipments
GET/PATCH /api/ops/shipments/:id
PATCH     /api/ops/shipments/:id/status

GET       /api/ops/commerce-orders
POST      /api/ops/commerce-orders/:id/fulfil

GET/POST  /api/ops/routes
PATCH     /api/ops/routes/:id
GET/POST  /api/ops/hubs
PATCH     /api/ops/hubs/:id
GET/POST  /api/ops/partners
PATCH     /api/ops/partners/:id
GET/POST  /api/ops/drivers
PATCH     /api/ops/drivers/:id
GET/POST  /api/ops/vehicles
PATCH     /api/ops/vehicles/:id
GET/POST  /api/ops/invoices
PATCH     /api/ops/invoices/:id

All /api/ops/* routes are denied when no valid Logistics Admin session exists. The Commerce bridge also fails closed with 503 if the Logistics Worker operations token is not configured.

Central protected operations API

The central API retains its server-to-server shipment/order endpoints:

GET  /api/logistics/shipments
POST /api/logistics/shipments
GET  /api/commerce/orders
POST /api/commerce/orders/:id/fulfil

They remain protected by OPERATIONS_API_TOKEN from PR #9. The Logistics React browser never receives or uses that token.

Known limitations / follow-ups

  • Full route optimization/map-distance calculation is not implemented; routes are maintained as operational master data.
  • Driver mobile apps, proof-of-delivery photos/signatures and live GPS are not implemented.
  • Public tracking is intentionally minimal. Cloudflare rate limiting/WAF should be used if traffic or abuse warrants it.
  • Billing is an operational ledger, not an accounting/tax platform.
  • Advanced fleet maintenance, fuel and telematics are outside this phase.

Troubleshooting

  • 401 from /api/ops/*: sign in through Logistics Operations with an Active Akshaya Admin user.
  • 503 from the Commerce fulfilment queue: configure the Logistics OPERATIONS_API_TOKEN with the same value used by the central API.
  • 404 from public tracking: verify both shipment ID and registered mobile number.
  • Empty hubs/partners on a fresh database are expected until Admin creates/activates network data.
  • Schema errors after deployment generally indicate migration 0011_logistics_operations.sql was not applied; the production pipeline applies D1 migrations before deploying application Workers.