Coding standards
Optimize for clarity, correctness, and safe change. Consistency beats personal preference.
Structure and naming
Organize code by domain or feature once a project has more than a few modules. Keep HTTP handlers thin; place business rules in application services and data access behind explicit boundaries.
| Item | Standard | Example |
|---|---|---|
| TypeScript files | kebab-case.ts |
tile-source.ts |
| React components | PascalCase.tsx |
LayerPanel.tsx |
| Python modules | snake_case.py |
geometry_validator.py |
| Classes/types | PascalCase | TileManifest |
| Functions/variables | language idiom | calculateBounds, parse_feature |
| Constants | UPPER_SNAKE_CASE only for true constants | MAX_TILE_ZOOM |
TypeScript and React
- Use TypeScript strict mode. Do not hide uncertainty with
any. - Prefer named exports and small, typed component interfaces.
- Keep map state separate from rendering where practical; clean up listeners, sources, and layers.
- Use Tailwind utility classes; extract repeated semantic UI patterns into components.
- Treat user input and external GeoJSON as untrusted.
Python and Rust
- Format Python with Ruff, type public boundaries, and use Pydantic models at API boundaries.
- Use explicit transactions for multi-step writes; avoid implicit ORM queries in loops.
- In Rust, run
cargo fmtandcargo clippy -- -D warnings; model invalid states out of public APIs. - Return actionable errors with stable error codes for clients; log context without secrets.
GIS data rules
- Store geometry with a declared SRID; transform deliberately, never by assumption.
- Use EPSG:4326 for interchange unless the product documents another contract.
- Validate geometry type, validity, dimensions, bounds, and size before persistence.
- Preserve source, timestamp, license, processing steps, and CRS as metadata.
- Use parameterized spatial queries and appropriate PostGIS indexes.
Coordinate systems are product behavior
A CRS mismatch can look plausible while being catastrophically wrong. Test known coordinates, units, and transformations at ingestion boundaries.
Testing
Use the smallest test that proves behavior, then add integration coverage at boundaries.
| Level | Covers | Required when | | --- | --- | | Unit | Pure logic, parsers, transforms | Logic changes | | Integration | API, DB, PostGIS, object storage | Crosses a process or data boundary | | End-to-end | Critical user journeys | User flow or deployment changes | | Visual/manual | Map rendering and interactions | Rendering changes or data is inherently visual |
Do not target coverage percentages at the expense of useful assertions. Every bug fix includes a regression test when practical.