first commit
This commit is contained in:
91
plugins/library-navigator/skills/sp-ports/SKILL.md
Normal file
91
plugins/library-navigator/skills/sp-ports/SKILL.md
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
name: sp-ports
|
||||
description: Global port database with UN/LOCODE lookups, shipping-lane routing, great-circle distance, ETA estimation, and spatial-indexed proximity search.
|
||||
---
|
||||
|
||||
# Ports for Suaveplan
|
||||
|
||||
Global port database with shipping-lane routing, ETA estimation, and UN/LOCODE port lookups for sea ports, airports, and rail terminals. Ships curated datasets, spatial-indexed proximity search, and Zod schemas for every public type.
|
||||
|
||||
## Architecture
|
||||
|
||||
| Component | Responsibility |
|
||||
|-----------|---------------|
|
||||
| `findPort` / `findPortStrict` | O(1) UN/LOCODE lookup (case-insensitive) with optional strict throw-on-miss. |
|
||||
| `findPortsByCountry` / `findPortsByType` / `searchPorts` | Filtering by ISO country, `PortType`, or name substring. |
|
||||
| `findNearestPort` / `findPortsInRadius` | Proximity search backed by a 5°-bucketed `PortSpatialIndex`. |
|
||||
| `PortSpatialIndex` | Buckets ports by lat/lon cells at construction time for fast nearest/radius queries. |
|
||||
| `estimateETA` | Vessel ETA along a `ShippingLane` using configurable speed, departure time, and waypoint resolution. |
|
||||
| `estimateLaneDistance` / `cumulativeDistances` | Great-circle distance metrics for a lane's waypoint chain. |
|
||||
| `PORTS_CODES` + `PortsError` | Eight stable error codes with typed subclasses (e.g. `PortsPortNotFoundError`). |
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
geospatial/logistics/ports/
|
||||
src/data/ # Curated datasets: seaPorts, airports, railTerminals, shippingLanes
|
||||
src/find-port/ # UN/LOCODE and name lookups
|
||||
src/nearest-port/ # Proximity search
|
||||
src/spatial-index/ # 5°-bucketed spatial index
|
||||
src/lane-lookup/ # Shipping lane lookups
|
||||
src/lane-distance/ # Great-circle distance for waypoints
|
||||
src/lane-progress/ # Vessel position projection onto a lane
|
||||
src/eta/ # ETA estimation
|
||||
src/distance/ # Distance helpers (km, nm, raw metres)
|
||||
src/schemas/ # Zod schemas for Port, ShippingLane, ETAEstimate, etc.
|
||||
src/otel/ # OTel counters and histograms
|
||||
```
|
||||
|
||||
Sibling packages:
|
||||
- `@suaveplan/geo` — provides `greatCircleDistance` used by lane-distance and nearest-port modules.
|
||||
- `@suaveplan/error` — provides `SuaveplanError` base and `defineCodes` registry.
|
||||
|
||||
## Patterns
|
||||
|
||||
### Quick Start
|
||||
|
||||
```typescript
|
||||
import { findPort, findNearestPort, getShippingLaneStrict, estimateETA } from "@suaveplan/ports";
|
||||
|
||||
const shanghai = findPort("CNSHA");
|
||||
const nearestSea = findNearestPort({ latitude: 1.26, longitude: 103.82 });
|
||||
const suez = getShippingLaneStrict("asia-europe-suez");
|
||||
const eta = estimateETA(
|
||||
{ latitude: 12.5, longitude: 43.3 },
|
||||
suez,
|
||||
14,
|
||||
{ departureTime: new Date() }
|
||||
);
|
||||
console.log(eta.etaDate, eta.confidence);
|
||||
```
|
||||
|
||||
### Scoped Search
|
||||
|
||||
```typescript
|
||||
import { findPortsByType, searchPorts, PortsPortNotFoundError } from "@suaveplan/ports";
|
||||
|
||||
const sea = findPortsByType("sea");
|
||||
const named = searchPorts("rotterdam", sea);
|
||||
|
||||
try {
|
||||
const port = findPortStrict("ZZZZZ");
|
||||
} catch (err) {
|
||||
if (err instanceof PortsPortNotFoundError) {
|
||||
// handle missing port
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Constraints
|
||||
|
||||
- The UN/LOCODE index is built lazily on first lookup and cached at module scope for the process lifetime.
|
||||
- Filtering helpers return fresh arrays so callers can mutate without affecting the curated registry.
|
||||
- `findPort` is case-insensitive; `findPortStrict` throws `PORTS.PORT_NOT_FOUND` on miss.
|
||||
- Proximity search uses a 5° bucket grid — accurate enough for logistics use cases without the overhead of a full R-tree.
|
||||
|
||||
## Checklist
|
||||
|
||||
1. Use `findPort` for lenient lookups and `findPortStrict` when a missing port is an error condition.
|
||||
2. Scope `searchPorts` to a filtered subset (e.g. `findPortsByType("sea")`) when you only care about one port category.
|
||||
3. Provide a realistic cruise speed (knots) to `estimateETA` — the default is derived from `VESSEL_CLASS_SPEEDS`.
|
||||
4. Import Zod schemas from `./schemas/schemas` when validating external port/lane data at API boundaries.
|
||||
Reference in New Issue
Block a user