130 lines
3.8 KiB
Markdown
130 lines
3.8 KiB
Markdown
# OpenSpec Change: enterprise-r3f-earth
|
|
|
|
- **Change ID**: enterprise-r3f-earth
|
|
- **Package**: `@suaveplan/r3f-earth`
|
|
- **Category**: r3f/geo
|
|
- **Target path**: `r3f/geo/r3f-earth`
|
|
- **Status**: PROPOSED
|
|
- **Date**: 2026-04-24
|
|
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/r3f-earth.md`
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
Deliver `@suaveplan/r3f-earth` on the genesis branch from scratch at enterprise quality. The package provides a React Three Fiber 3D globe component with port markers, shipping lanes, GeoJSON overlays, interactive country highlighting, and smooth camera orbiting. It ships `<Earth />`, `<EarthMarker />`, `<EarthLane />`, `<EarthOverlay />`, and `<EarthScene />` components with full TypeScript props, Storybook stories, Vitest + `@testing-library/react` tests, OTel counters for render events, and Zod-validated prop schemas.
|
|
|
|
---
|
|
|
|
## Current-state audit (genesis)
|
|
|
|
Does not exist on genesis — fresh build.
|
|
|
|
---
|
|
|
|
## Available workspace deps on genesis
|
|
|
|
| Package | Role |
|
|
|---|---|
|
|
| `@suaveplan/error` (`workspace:^`) | Typed `R3F_EARTH.*` error codes |
|
|
| `@suaveplan/types` (`workspace:^`) | `LoggerLike` |
|
|
| `@suaveplan/logger` (`workspace:^`) | Structured logs |
|
|
| `zod` (`catalog:forms`) | Prop schemas |
|
|
| `@opentelemetry/api` (`catalog:observability`) | Render counters |
|
|
| `three` (`catalog:r3f`) | 3D engine |
|
|
| `@react-three/fiber` (`catalog:r3f`) | React renderer |
|
|
| `@react-three/drei` (`catalog:r3f`) | Camera, helpers |
|
|
| `react` / `react-dom` (`catalog:react`) | React |
|
|
| `tslib` (`catalog:build`) | Runtime helpers |
|
|
|
|
---
|
|
|
|
## Public API surface
|
|
|
|
```tsx
|
|
// Main globe component
|
|
function Earth(props: EarthProps): JSX.Element
|
|
function EarthScene(props: EarthSceneProps): JSX.Element // includes Canvas + OrbitControls
|
|
function EarthMarker(props: EarthMarkerProps): JSX.Element
|
|
function EarthLane(props: EarthLaneProps): JSX.Element
|
|
function EarthOverlay(props: EarthOverlayProps): JSX.Element
|
|
|
|
interface EarthProps {
|
|
radius?: number // default: 1
|
|
segments?: number // default: 64
|
|
texturePath?: string // earth texture URL
|
|
bumpMapPath?: string
|
|
cloudTexturePath?: string
|
|
showClouds?: boolean
|
|
showAtmosphere?: boolean
|
|
atmosphereColor?: string
|
|
onCountryClick?: (code: string) => void
|
|
highlightedCountries?: string[]
|
|
highlightColor?: string
|
|
}
|
|
|
|
interface EarthMarkerProps {
|
|
lat: number
|
|
lng: number
|
|
label?: string
|
|
color?: string
|
|
size?: number
|
|
onClick?: () => void
|
|
children?: React.ReactNode
|
|
}
|
|
|
|
interface EarthLaneProps {
|
|
from: [lat: number, lng: number]
|
|
to: [lat: number, lng: number]
|
|
color?: string
|
|
animated?: boolean
|
|
speed?: number
|
|
dashed?: boolean
|
|
}
|
|
|
|
interface EarthOverlayProps {
|
|
geojson: GeoJSON.FeatureCollection
|
|
color?: string
|
|
opacity?: number
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## File layout
|
|
|
|
```text
|
|
r3f/geo/r3f-earth/
|
|
package.json
|
|
tsconfig.json
|
|
vitest.config.ts
|
|
src/
|
|
index.ts
|
|
error-codes.ts
|
|
types/
|
|
r3f-earth.types.ts
|
|
r3f-earth.types.md
|
|
components/
|
|
earth/
|
|
earth.tsx / earth.md / earth.types.ts / earth.test.tsx / earth.stories.tsx / index.ts
|
|
earth-scene/
|
|
earth-scene.tsx / earth-scene.md / earth-scene.types.ts / earth-scene.test.tsx / earth-scene.stories.tsx / index.ts
|
|
earth-marker/
|
|
earth-marker.tsx / .md / .types.ts / .test.tsx / .stories.tsx / index.ts
|
|
earth-lane/
|
|
earth-lane.tsx / .md / .types.ts / .test.tsx / .stories.tsx / index.ts
|
|
earth-overlay/
|
|
earth-overlay.tsx / .md / .types.ts / .test.tsx / .stories.tsx / index.ts
|
|
utils/
|
|
geo-math/
|
|
geo-math.ts / geo-math.md / geo-math.test.ts / index.ts
|
|
```
|
|
|
|
---
|
|
|
|
## Impact
|
|
|
|
Downstream: logistics, port-tracking, and shipping visualisation packages.
|
|
|
|
**Prerequisites on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/logger`. Requires `@testing-library/react` + `@testing-library/jest-dom` for component tests.
|