Where everything is
Last reviewed against the codebase: 2026-07-25.
A task-oriented map of the codebase: given a thing you want to change, this page tells you which package owns it, why it lives there, and where the deeper reference is. For the authoritative, code-generated list of every workspace package, see the Repository guide - this page is the human-oriented companion to it and deliberately does not duplicate that list.
The mental model: one monorepo, two source roots
The repo is a pnpm workspace monorepo. Everything is TypeScript, and the deliberate split is:
artifacts/- deployable things. Each subdirectory is something you can ship: the API server, the app, the docs site, the marketing site. If it has a deploy target, it lives here.lib/- shared libraries. Code that more than one artifact depends on, published as@workspace/*packages and consumed by path, not by version. If two artifacts would otherwise copy-paste it, it belongs here.infra/- Terraform + the hibernate/wake scripts. This is not a workspace package (it isn’t TypeScript and isn’t installed by pnpm); it’s operated on its own. See Run it in production and Infrastructure.scripts/- a small@workspace/scriptspackage for repo-wide utilities (e.g. the post-merge hook).
Why a monorepo at all? The client and the server must agree, byte-for-byte, on two things: the
API contract and the fire-spread geometry. If those drifted between a separately-versioned
client repo and server repo, a map would draw a hazard cone the server never predicted, or the app
would call a route shape the server rejects. Keeping them as shared lib/* packages consumed by
path means a single edit updates both sides in the same commit, and pnpm run typecheck fails the
build the moment they disagree. That guarantee is the whole reason for the layout.
What each package is
| Package | Path | Responsible for |
|---|---|---|
@workspace/api-server | artifacts/api-server | Node/Express + Drizzle API - auth, assets, fires, predictions, alerts, geocoding, plus the ingest scheduler and alert evaluator. |
@workspace/firepath-ai | artifacts/firepath-ai | The universal Expo / React Native app (iOS, Android, web SPA) with MapLibre maps. |
@workspace/docs-site | artifacts/docs-site | This Astro / Starlight developer site (includes the generated reference). |
@workspace/marketing-site | artifacts/marketing-site | The public marketing site (www.firepath.software). |
@workspace/db | lib/db | Drizzle schema + migrations for PostGIS - the single source of truth for the data model. |
@workspace/spread-model | lib/spread-model | Dependency-free fire-spread geometry (hazard bands, arrows, ETA labels) shared by client and server. |
@workspace/api-spec / api-zod / api-client-react | lib/* | The shared API contract: the spec, its Zod schemas, and the typed React query client. |
@workspace/web-brand | lib/web-brand | Brand tokens + logo/favicon shared by the web surfaces. |
@workspace/scripts | scripts | Repo-wide utility scripts (e.g. the post-merge hook). |
”I want to change X → go here”
The core of this page. Find your task, go to the path, follow the cross-link for depth.
| I want to change… | Go to | Depth / reference |
|---|---|---|
| An API route or its behaviour | artifacts/api-server/src/routes/ | API reference |
| The shape of a request/response (contract) | lib/api-spec + lib/api-zod | API reference |
| The database schema (a table or column) | lib/db/src/schema/ | Data model |
| Fire-spread geometry (bands, cone, ETA math) | lib/spread-model (shared client + server) | Overview & architecture |
| A screen, map, or navigation in the app | artifacts/firepath-ai/app (+ components, hooks) | - |
| An environment variable / feature flag | .env.example and the server config.ts | Configuration reference |
| Ingest scheduling (FIRMS/DEA/weather) | artifacts/api-server/src/ingest/scheduler.ts | Overview & architecture |
| Fire clustering / incident tracking | artifacts/api-server/src/ingest/clustering.ts | Overview & architecture |
| Alert evaluation + delivery | artifacts/api-server/src/notifications/ | Security (delivery audit) |
| Spread precompute (per-hotspot geometry) | artifacts/api-server/src/precompute/fireSpread.ts | Overview & architecture |
| Terraform, wake/hibernate scripts | infra/ | Run it in production, Infrastructure |
| Brand colours / logo on the web | lib/web-brand | - |
| This documentation | artifacts/docs-site/src/content/docs | Update common things |
Why the API server is the “everything” package
Look at artifacts/api-server/src/ and you’ll see it is more than a set of HTTP handlers - it also
carries the background pipeline (ingest/, precompute/, notifications/) that turns raw
satellite hotspots into per-asset alerts. The routes are the thin part; the seams below are where the
product’s value actually lives:
ingest/scheduler.ts- the cron-like loop that pulls FIRMS (firms.ts), DEA (dea.ts), weather (openmeteo.ts), and computes fire-danger (ffdi.ts).ingest/clustering.ts- groups raw hotspots into tracked fire incidents (gated by theFIRE_CLUSTERING_ENABLEDflag; see the caution below).precompute/fireSpread.ts- runs the sharedlib/spread-modelgeometry per hotspot server-side, so the app doesn’t have to.notifications/- the alert evaluator that matches predicted spread against user assets and fans out deliveries (push/email/SMS).
When you change ingest, clustering, or alerting, you’re editing this package’s seams, not its routes - that distinction is why the “change X” table points at specific files rather than “the API”.
Running a single package
Because it’s a pnpm workspace, you can target any one package with a filter instead of running the
whole tree. The scripts below are the real ones defined in each package’s package.json.
Type-check the whole repo (libs first, then artifacts - this is the build’s correctness gate):
pnpm run typecheck# Runs `tsc --build` across lib/* then each artifact/scripts typecheck.# Exits non-zero on the first type error - this is what catches client/server contract drift.Run just the server, or just the app:
pnpm --filter @workspace/api-server dev # builds then starts the API on :3000pnpm --filter @workspace/firepath-ai web # Expo web SPA on :8081Run one package’s tests (Vitest, no real secrets needed):
pnpm --filter @workspace/api-server testpnpm --filter @workspace/spread-model test # the pure geometry lib - fastest suiteFor the full local start/stop sequence (Postgres + Redis via Docker, .env, cloudflared), see
Start it locally; for what to run to confirm a change is good, see
Verify.
Changing the data model
The database schema is the single source of truth, and it is code, not SQL you hand-write. Each
table is a file under lib/db/src/schema/ (e.g. fires.ts, assets.ts, alerts.ts,
fire_incidents.ts). To change the model:
-
Edit or add the Drizzle table definition in
lib/db/src/schema/. -
Push it to your local database:
Terminal window pnpm --filter @workspace/db push# drizzle-kit diffs the schema against the live DB and applies the change.
The generated, human-readable view of every table lives in the Data model reference, regenerated from this schema - so after a schema change, that page is how you confirm the change landed as intended.
Changing configuration or a feature flag
Configuration is externalised, never hard-coded. Two layers:
- Local / dev: copy
.env.exampleto.envand edit values there. Every variable the server reads is documented in the Configuration reference, generated from the server’sconfig.ts- so that page, not this one, is the authoritative variable list. - Production: the same variables come from AWS Secrets Manager + Terraform variables, not from a
file. Feature flags such as
FIRE_CLUSTERING_ENABLEDare set by their Terraform counterparts (enable_fire_clustering,enable_wind_worker, …) covered in Infrastructure.
If you’re adding a new config value, add it to config.ts and .env.example in the same commit,
so the generated reference and the local template stay in lock-step. Never repeat a config literal
across files - externalise it to the one config source.
The documentation itself
This site is @workspace/docs-site (Astro + Starlight). Prose pages are Markdown under
artifacts/docs-site/src/content/docs. The /reference/* pages (API, data model, configuration,
repository tree) are generated from the code - do not hand-edit them; change the source and
regenerate. See Update common things for the regenerate + publish flow.
Where to go next
- Start it locally - bring the stack up on your machine.
- Update common things - the step-by-step for a route, a schema change, a config value, a doc, an app build.
- Verify - health checks, typecheck, and tests to prove a change is good.
- Repository guide - the authoritative, generated package/tree listing.
- Overview & architecture - how the tiers and the fire-science model fit together.