Skip to content

Plan a road route for custom-route shipments (#328) - #336

Merged
Connor-Finn merged 1 commit into
mainfrom
tms/328-shipment-routes
Oct 4, 2026
Merged

Connor-Finn merged 1 commit into
mainfrom
tms/328-shipment-routes

Conversation

@Connor-Finn

Copy link
Copy Markdown
Collaborator

Part 1 of #328.

What changed

  • ShipmentRoute (new table, reference role): the planned road route for a shipment on a custom route (no lane), with the stop sequence it was calculated for (stopsKey).
  • ShipmentRoutePlanner, run by ShipmentRoutePlanningHandler on shipment.created / shipment.updated:
    • a lane shipment rides its lane; any route of its own is removed
    • a draft or ready custom-route shipment gets a Google Directions route through its stops in sequence, only when the stops changed
    • the provider is called off the request path and outside any transaction; SetShipmentRouteCommand stores the result and emits shipment.route_planned
    • with no Google Maps server key, planning is skipped and logged
  • One effective route (ShipmentRouteRepository.findEffectiveRoute): the shipment's own route, otherwise its lane's. Checkpoints, route deviation in the ETA monitor, the new GET /api/v1/shipments/:id/route and the shipment map use it.
  • Route planning is registered in the embedded (API) workers, which register their other handlers without a command bus.

Testing

  • Full backend suite, tsc (backend and frontend), tenancy and boundary lints pass.
  • Live against a seeded database: a lane shipment returns its lane's route and the map draws it through the new endpoint; a shipment with neither returns null; an unknown id returns 404; creating a custom-route shipment ran the planner (no server key in the test org, so no_server_key as expected). The Google call is covered by tests with it stubbed.

🤖 Generated with Claude Code

Part 1 of #328. A shipment on a custom route (no lane) gets its own
planned route in a new ShipmentRoute table, calculated through its stops in
sequence by ShipmentRoutePlanner when the shipment is created or changed
while draft or ready, and only when the stop sequence changed. The
provider call runs off the request path (ShipmentRoutePlanningHandler) and
outside any transaction; SetShipmentRouteCommand stores the result and
emits shipment.route_planned. With no Google Maps server key, planning is
skipped and logged.

Checkpoints, route deviation in the ETA monitor, the new
GET /api/v1/shipments/:id/route and the shipment map all use the
shipment's effective route: its own, otherwise its lane's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Connor-Finn
Connor-Finn merged commit 683ae53 into main Oct 4, 2026
@Connor-Finn
Connor-Finn deleted the tms/328-shipment-routes branch October 4, 2026 10:03
Connor-Finn added a commit that referenced this pull request Oct 4, 2026
PgBossEventBus only fanned events out to handlers registered in its own
process, so with DISABLE_EMBEDDED_WORKERS=true every event the API
published was recorded and then delivered nowhere. A process that runs
no handlers now puts events on an evt.__dispatch queue, and every process
that has started handlers consumes it and fans them out to its handler
queues. This also covers WORKER_MODE=integrations workers.

The standalone worker now sets up the same DI container as the API
(queue adapter, event bus, full command bus, delivery and arrival
services) instead of hand-built command buses, and both processes
register the event handlers with the full command bus. The
command-driven handlers (issue engine, auto-replenishment, route
planning) therefore run in both setups, whether or not an LLM is
configured. Replaces the route-planning-only workaround from #336.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant