5.6 KiB
5.6 KiB
Tasks: enterprise-react-port-tracking
Change ID: enterprise-react-port-tracking
Package: @suaveplan/react-port-tracking
Target path: react/platform/react-port-tracking
Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/events, @suaveplan/ports, @suaveplan/react-map, @suaveplan/react-translate
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin 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.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold
- Create directory tree. Write
package.jsonat0.1.0,tsconfig.json,vitest.config.ts, scripts. - Dependencies:
@suaveplan/error workspace:^,@suaveplan/events workspace:^,@suaveplan/ports workspace:^,@suaveplan/react-map workspace:^,@suaveplan/react-translate workspace:^,@opentelemetry/api catalog:observability,zod catalog:forms,tslib catalog:build.
2. Error codes and types
- Define
PortTrackingError; codes:PORT_SEARCH_FAILED,VESSEL_TRACK_FAILED,ETA_ESTIMATE_FAILED. - Define all types:
ETAPanelProps,PortInfoCardProps,PortMapProps,PortMarkerProps,ShippingLaneOverlayProps,VesselPosition,VesselTrackerProps,UseETAEstimateOptions,UseETAEstimateReturn,UsePortSearchOptions,UsePortSearchReturn,ShippingLaneWithDistance,UseShippingLanesReturn,UseVesselTrackingOptions,UseVesselTrackingReturn,PortIconType.
3. Utils
port-icons.ts
portIconPaths: Record<PortIconType, string>— SVG path strings for sea/air/rail/multimodal port icon types.- Write
port-icons.test.ts(≤500 lines): all icon types present, paths are valid non-empty strings.{ timeout: 5000 }. - Write
port-icons.md.
4. Hooks
usePortSearch
- Searches ports via
@suaveplan/ports. Returns{ results, loading, error, search }. OTelport.searchspan. ThrowsPortTrackingError(PORT_SEARCH_FAILED)on engine error. - Write test + md.
useShippingLanes
- Loads shipping lanes with distance from a reference point. Returns
{ lanes, loading, error }. - Write test + md.
useETAEstimate
- Computes ETA from current position + route via
@suaveplan/ports. Returns{ eta, distance, speed, loading, error }. OTelvessel.eta.estimatespan. - Write test + md.
useVesselTracking
- Subscribes to vessel position updates via
@suaveplan/events. Returns{ position, history, loading, error }. OTelvessel.position.updatecounter. ThrowsPortTrackingError(VESSEL_TRACK_FAILED)on connection failure. - Write
use-vessel-tracking.test.ts(≤500 lines): initial position, position update event, history accumulates, unsubscribe on unmount.{ timeout: 10000 }. - Write
use-vessel-tracking.md.
5. Components
PortMarker
- SVG marker using
portIconPathsfor port type. Acceptsport,onClick, ARIA label viauseTranslation. - Write test, stories (all-types, selected, playground), md.
ETAPanel
- Displays ETA, distance, speed. Labels "Arriving" / "Delayed" via
useTranslation. HandlesnullETA with "–". - Write test, stories (arriving, delayed, unknown, playground), md.
PortInfoCard
- Port card with facilities, name, type, coordinates. All labels via
useTranslation. - Write test, stories (default, with-facilities, no-facilities, playground), md.
ShippingLaneOverlay
- Renders shipping lanes as
Polygon/ polylines on@suaveplan/react-mapcanvas. - Write
shipping-lane-overlay.test.tsx(≤500 lines): renders lanes on map, no-lanes empty state.{ timeout: 5000 }. - Write stories (default, multi-lane, highlighted, playground), md.
VesselTracker
- Renders vessel icon at current position using
@suaveplan/react-mapMarker. Shows course line. Updates smoothly on position change. - Write
vessel-tracker.test.tsx(≤500 lines): renders at position, updates on new position event, shows course.{ timeout: 5000 }. - Write stories (default, in-motion, anchored, playground), md.
PortMap
- Composite:
MapViewfrom@suaveplan/react-map+PortMarker[]+ShippingLaneOverlay+VesselTracker[]. Acceptsadapterprop forwarded toMapView. - Write
port-map.test.tsx(≤500 lines): renders map + markers + overlays, vessel positions updated, empty markers state.{ timeout: 10000 }. - Write stories (default, with-vessels, with-lanes, loading, playground), md.
6. E2E
e2e/port-tracking.spec.ts— Playwright:- Render
PortMapwith test data; verify port markers present. - Simulate vessel position update event; verify
VesselTrackermoves. - Verify
ETAPanelshows "Arriving" label for an in-bound vessel. - Test search for a port; verify
PortInfoCardrenders for the result.
- Render
7. Verify and publish
bunx turbo lint typecheck test --filter=@suaveplan/react-port-tracking— green.bunx turbo test:coverage --filter=@suaveplan/react-port-tracking— 100%.bun scripts/publish.ts --package @suaveplan/react-port-tracking.- Archive change folder.