Skip to main content

Welcome

ALERTCalifornia operates a network of ~1,400 wildfire cameras across the state. This app is what the people watching those cameras actually look at. A dispatcher gets an alert, opens a camera, pans it toward the smoke, and decides whether to escalate — that entire loop happens in this UI.

Hold onto that image, because it explains most of the engineering decisions you're about to meet. Operators work during emergencies, on bad connections, sometimes on a phone in a truck at 2 AM. When these docs seem obsessed with re-render counts, polling caps, and reference stability — that obsession is why. Latency here is a safety property, not a nice-to-have.

Be an operator for twenty seconds

Before a single word of architecture, feel the job this app exists for. Below is a camera on a mountain and a wide, dark world. Somewhere out there is smoke. Drag to pan. Find it. Click it.

🎥 CAM-042 · Bald Mountain Northbearing 180°
Drag to pan · click the smoke

That tension you just felt — a huge landscape, a narrow view, and something out there that matters — is the product. Everything in these docs (the pixel-to-degree math, the polling budgets, the lease protocol) exists to make that twenty seconds faster and surer for a real dispatcher.

What you're working with

Under the hood this is a Next.js 16 + React 19 app with a small, deliberate toolkit: TanStack Query caches what the server says, Zustand holds what the app knows, MUI provides the component vocabulary, and an ArcGIS map is the centerpiece of the screen. Live camera frames arrive over SignalR, a real-time socket to the backend.

Don't worry about memorizing that list — every one of those tools gets its own proper introduction, in context, when the story needs it.

The one idea to take from today

If you learn nothing else in your first hour: the browser never calls the .NET backend directly. Every request hops through a Next.js API route first:

your component
→ queries/useCameras.ts (TanStack Query — caching, retries)
→ fetch('/api/cameras')
→ pages/api/cameras.ts (the BFF — validation, auth token)
→ the .NET backend

That middle layer is a BFF — a Backend-For-Frontend. Think of it as the app's personal concierge: the browser asks the concierge, and the concierge — who holds credentials the browser must never see — talks to the real backend. The access token lives server-side, attached per request, and never touches the browser.

You'll see this pattern from every angle in the code tour. For now, one practical consequence: a feature that needs data means two files — a route in pages/api/ and a query hook in queries/. Not one.

Your path through these docs

These docs are written as a course, in reading order. Skim the whole path now so you know where everything will be when you need it:

  1. Get started (you are here) — run the app, then take the code tour.
  2. Core concepts — the architecture, the design token system, and how we measure what operators actually do.
  3. Features — the map, camera control, the tile grid, alerts: one folder per feature, each starting from what the operator sees.
  4. State management — how the app remembers things. Read this before touching any store.
  5. Deep dives — the advanced track: the pixel-to-degrees math, pano calibration, camera-lease concurrency, SignalR internals, feature flags.
  6. Security, Accessibility, and Testing — reference chapters you'll return to throughout.
  7. Contributing — how to write docs that keep this site readable.

A brand-new developer who reads chapters 1–4 in order can make a confident first change. The deep dives are there for the day a bug drags you below the waterline.

Wrapping up

You now know what the app is for, who it serves, and its one non-negotiable architectural rule. Time to see it on your own screen: Running the app locally.