Files
suaveplan/openspec/changes/enterprise-api-plugin-logistics/tasks.md
2026-05-27 23:29:53 +01:00

3.5 KiB

Tasks: enterprise-api-plugin-logistics

Change ID: enterprise-api-plugin-logistics Package: @suaveplan/api-plugin-logistics Target path: api/logistics/api-plugin-logistics Prerequisite packages on Verdaccio: @suaveplan/api, @suaveplan/api-shared, @suaveplan/api-plugin-auth, @suaveplan/api-plugin-database, @suaveplan/events, @suaveplan/idempotency, @suaveplan/audit-logging, @suaveplan/barcode, @suaveplan/rate-limiter, @suaveplan/error


0. Pre-flight (non-negotiable)

  • 0.1 Confirm clean working tree (git status reports nothing) and no in-flight worktrees with uncommitted work (git worktree list then git status in each)
  • 0.2 If any worktrees exist under .claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
  • 0.3 Confirm the package set in MANIFEST.md matches find packages -maxdepth 3 -name package.json count. Drift here means a prior change archived without regenerating the manifest.

1. Scaffold + types + errors + events

  • Create api/logistics/api-plugin-logistics/; package.json v0.0.0; standard tooling.
  • Types: Shipment, Carrier, Pallet, Container, TransportLeg, LossReport, LogisticsConfig (Zod with basePath, statusVocabulary, defaultCurrency).
  • Errors: 6-code union + registration. Test + doc.
  • Events: LogisticsEventMap (logistics:shipment:created, :dispatched, :delivered, :lost, :loss-report:filed).

2. SurrealQL

  • carrier.surql, shipment.surql, pallet.surql, container.surql, transport_leg.surql, loss_report.surql. All with tenantId indexes + status indexes.

3. Services (all with .test.ts + .md)

  • ShipmentService: createShipment, updateShipment, updateStatus (state machine: created→dispatched→in-transit→delivered; illegal transitions throw), getShipment, listShipments, getLabelBarcode (via @suaveplan/barcode).
  • CarrierService: CRUD.
  • PalletService: createPallet, addShipment, removeShipment, listPallets. Weight limit enforcement (LogisticsError.PALLET_OVERLOAD).
  • ContainerService: createContainer, addPallet, removePallet, listContainers. Volume enforcement.
  • TransportLegService: multi-leg transport chain (road/sea/air); attach to shipment; list by shipment.
  • LossInvestigationService: fileLossReport, updateReport, resolveReport (carrier attribution). Emit logistics:shipment:lost; audit-log.

4. Routes

  • Full CRUD + status update on each entity.
  • All write routes: requireAuth + permission gates + idempotency + audit.
  • Shipment label: GET /logistics/shipments/:id/label — returns barcode SVG.
  • Route .test.ts + .md.

5. Plugin factory + integration tests + publish

  • createLogisticsPlugin: definePlugin, dependencies: ["database", "auth"], migrationsPath: "./surql".
  • onTenantCreate/onTenantDelete: namespace SurrealDB + teardown.
  • Integration: create carrier → create shipment → dispatch → deliver → loss report filed (real SurrealDB).
  • bunx turbo lint typecheck test --filter=@suaveplan/api-plugin-logistics — green; 100% coverage.
  • bun scripts/publish.ts --package @suaveplan/api-plugin-logistics.
  • Archive → openspec/archive/2026-04-24-enterprise-api-plugin-logistics/.