Skip to content

Commit 8d94f93

Browse files
committed
chg: add copilot instructions
1 parent 98fde05 commit 8d94f93

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

.github/copilot-instructions.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Copilot Instructions for nina-maps
2+
3+
## Architecture Overview
4+
5+
This is a React map editor for geospatial data using MapLibre GL. The architecture follows a configuration-driven approach where map definitions are JSON files validated against Zod schemas.
6+
7+
**Key data flow:** JSON config → Zod validation → Zustand store → transformation libs → MapLibre/DeckGL layers
8+
9+
## Schemas (src/schemas/)
10+
11+
All types are defined as Zod schemas and exported from `src/schemas/index.ts` via `src/types.ts`. When modifying types:
12+
13+
1. Edit the Zod schema in the appropriate file under `src/schemas/`
14+
2. Run `pnpm generate-schema` to regenerate `schemas/map-config.schema.json`
15+
3. Types are auto-inferred - never manually duplicate type definitions
16+
17+
Schema organization:
18+
- `legend/` - Raster (linear, interval, image) and vector (fill, line, circle) legends
19+
- `source/` - Layer sources: pmtiles, titiler, raster, parquet, wms, wmts
20+
- `layer/` - Layer, Folder, Tree structures
21+
- `map.ts` - MapConfig, MapSettings, ViewState
22+
23+
## State Management (src/hooks/app.ts)
24+
25+
Global state uses Zustand with immer middleware. The store (`useAppStore`) holds the entire MapConfig and provides actions for mutations.
26+
27+
**Pattern:** Use reselect selectors (`createAppSelector`) for derived data. Export custom hooks like `useLayer(id)`, `useLayers()`, `useMaplibreMapConf()`.
28+
29+
## Layer Transformation (src/libs/)
30+
31+
- `toMaplibre.ts` - Converts layer configs to MapLibre source/layer specs. Contains `buildPMTilesLayer()`, `buildRasterLayer()`, etc.
32+
- `toDeckGL.ts` - Converts parquet layers to DeckGL layers with GeoArrow support
33+
34+
When adding a new layer type: add schema in `src/schemas/source/`, export from `src/schemas/source/index.ts`, add builder function in `toMaplibre.ts`.
35+
36+
## Routing (src/routes/)
37+
38+
Uses TanStack Router with file-based routing:
39+
- `$mapId.tsx` - Dynamic map routes
40+
- `editor/` - Editor-specific routes with `_layout` for shared layout
41+
- `_view/` folders contain read-only views, `edit/` contains editable forms
42+
43+
Routes use `createFileRoute()` and can define loaders with TanStack Query via `queryOptions()`.
44+
45+
## Components
46+
47+
- `src/components/layer-fields/` - Form fields for each source type (PMTilesFields, TitilerFields, etc.)
48+
- `src/components/form-items/` - Reusable form primitives with TanStack Form
49+
- `MaplibreMap.tsx` - Main map component, integrates Popup for feature info
50+
51+
## Commands
52+
53+
```bash
54+
pnpm dev # Development server (proxies /titiler to localhost:8989)
55+
pnpm build # Production build with TypeScript check
56+
pnpm lint # Biome check
57+
pnpm lint:fix # Biome auto-fix
58+
pnpm generate-schema # Regenerate JSON schema from Zod definitions
59+
```
60+
61+
## Code Style
62+
63+
- Use `@/` path alias for imports from `src/` (configured in tsconfig.app.json and vite.config.ts)
64+
- Biome for formatting (2-space indent, 120 line width) - run `pnpm lint:fix`
65+
- JSDoc comments for exported functions, especially in libs/
66+
67+
## Adding New Source Types
68+
69+
1. Create schema file: `src/schemas/source/newtype.ts`
70+
2. Export from `src/schemas/source/index.ts` and add to `LayerConfigSchema` union
71+
3. Add form fields: `src/components/layer-fields/NewTypeFields.tsx`
72+
4. Add transformation: `src/libs/toMaplibre.ts` (or `toDeckGL.ts` for DeckGL layers)
73+
5. Run `pnpm generate-schema`

0 commit comments

Comments
 (0)