Skip to content

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/scripts package 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

PackagePathResponsible for
@workspace/api-serverartifacts/api-serverNode/Express + Drizzle API - auth, assets, fires, predictions, alerts, geocoding, plus the ingest scheduler and alert evaluator.
@workspace/firepath-aiartifacts/firepath-aiThe universal Expo / React Native app (iOS, Android, web SPA) with MapLibre maps.
@workspace/docs-siteartifacts/docs-siteThis Astro / Starlight developer site (includes the generated reference).
@workspace/marketing-siteartifacts/marketing-siteThe public marketing site (www.firepath.software).
@workspace/dblib/dbDrizzle schema + migrations for PostGIS - the single source of truth for the data model.
@workspace/spread-modellib/spread-modelDependency-free fire-spread geometry (hazard bands, arrows, ETA labels) shared by client and server.
@workspace/api-spec / api-zod / api-client-reactlib/*The shared API contract: the spec, its Zod schemas, and the typed React query client.
@workspace/web-brandlib/web-brandBrand tokens + logo/favicon shared by the web surfaces.
@workspace/scriptsscriptsRepo-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 toDepth / reference
An API route or its behaviourartifacts/api-server/src/routes/API reference
The shape of a request/response (contract)lib/api-spec + lib/api-zodAPI 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 appartifacts/firepath-ai/app (+ components, hooks)-
An environment variable / feature flag.env.example and the server config.tsConfiguration reference
Ingest scheduling (FIRMS/DEA/weather)artifacts/api-server/src/ingest/scheduler.tsOverview & architecture
Fire clustering / incident trackingartifacts/api-server/src/ingest/clustering.tsOverview & architecture
Alert evaluation + deliveryartifacts/api-server/src/notifications/Security (delivery audit)
Spread precompute (per-hotspot geometry)artifacts/api-server/src/precompute/fireSpread.tsOverview & architecture
Terraform, wake/hibernate scriptsinfra/Run it in production, Infrastructure
Brand colours / logo on the weblib/web-brand-
This documentationartifacts/docs-site/src/content/docsUpdate 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 the FIRE_CLUSTERING_ENABLED flag; see the caution below).
  • precompute/fireSpread.ts - runs the shared lib/spread-model geometry 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):

Terminal window
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:

Terminal window
pnpm --filter @workspace/api-server dev # builds then starts the API on :3000
pnpm --filter @workspace/firepath-ai web # Expo web SPA on :8081

Run one package’s tests (Vitest, no real secrets needed):

Terminal window
pnpm --filter @workspace/api-server test
pnpm --filter @workspace/spread-model test # the pure geometry lib - fastest suite

For 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:

  1. Edit or add the Drizzle table definition in lib/db/src/schema/.

  2. 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.example to .env and edit values there. Every variable the server reads is documented in the Configuration reference, generated from the server’s config.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_ENABLED are 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