# AirBrief — Project Status *Last updated: June 16, 2026* --- ## What It Is A static web app for business aviation situational awareness — specifically built for Airshare line pilots and flight control. Not a certified briefing replacement. Gives a fast, clean weather picture before the official brief happens. **Live at:** rockcampbell.com/airbrief **Target users:** - Line pilot at KMKC with 2–4 legs today, needs a 90-second weather picture - Flight control building the day's operation, wants to flag potential weather disruptions --- ## Current State (MVP Complete) ### Airport Lookup (single ICAO/IATA) Type one airport ID → full detail view: - Flight category badge (VFR / MVFR / IFR / LIFR), color coded - Wind, visibility, ceiling, altimeter (inHg — Kollsman window value), temp/dewpoint - Sky conditions (tagged) - Present weather decoded to plain English - METAR: plain-English paragraph + raw text - TAF: plain-English per change group (Initial / From / Temporary / Becoming / Probability) + raw text ### Route Weather (multiple space-separated IDs) Type `KMKC KSTL KDEN` → route view: - Flight category strip: colored badges per airport with visibility and ceiling - Per-airport detail cards: wind, vis, ceiling, altimeter, temp/dewpoint, plain-English summary, obs time - Active hazard summary: SIGMETs and AIRMETs filtered to the route bounding box, sorted by severity (convective SIGMETs first) --- ## Tech Stack | Layer | Choice | Notes | |---|---|---| | Frontend | Vanilla HTML/CSS/JS | Single file, no framework, no build step | | Weather data | aviationweather.gov public API | No key, no cost, no rate limit | | Hazard data | aviationweather.gov `/airsigmet` | Same API, returns SIGMETs + AIRMETs | | METAR/TAF decode | Client-side JS | No third-party decoder — all done in-browser | | Hosting | hugo-site nginx container on rocklab | Static file served directly from disk | | CORS proxy | Nginx location `/airbrief-api/` | aviationweather.gov doesn't send CORS headers; nginx proxies server-side | --- ## File Locations ``` /home/rock/airbrief/ ├── index.html ← entire app (single file) └── PROJECT.md ← this file ``` **Nginx proxy config:** `/home/rock/docker/rockcampbell/nginx.conf` - `/airbrief` → serves `/srv/airbrief/` (the airbrief directory) - `/airbrief-api/` → proxies to `https://aviationweather.gov/api/data/` **Docker volume mount:** `/home/rock/docker/rockcampbell/docker-compose.yml` - `/home/rock/airbrief:/srv/airbrief:ro` Changes to `index.html` go live immediately — no container restart needed. --- ## API Endpoints in Use All routed through the local proxy at `/airbrief-api/`: | Endpoint | Used for | |---|---| | `/metar?ids=KMKC&format=json&hours=2` | METAR for one or multiple airports (comma-separated) | | `/taf?ids=KMKC&format=json` | TAF including structured `fcsts` array | | `/airsigmet?format=json` | All active SIGMETs and AIRMETs | **Key API field notes:** - `fltCat` (capital C) — flight category; computed from ceiling/vis as fallback - `altim` — in **hPa**, not inHg. Divide by 33.8639 to get the Kollsman window value - `visib` — string, may return `"10+"` rather than a number - `clouds[]` — array of `{cover, base, type}` objects; base in feet --- ## Hazard Filtering When displaying route hazards, the app builds a bounding box from the lat/lon of all found airports (±3 degrees padding) and filters the SIGMET/AIRMET list to hazards whose coordinates overlap that box. Hazards with no coordinate data are included. Sort order: convective SIGMETs → other SIGMETs → AIRMETs. Color: red = convective SIGMET, orange = other SIGMET or severe turb/ice, yellow = AIRMET. --- ## v2 Backlog (do not build until David returns to this) From the original project brief — in priority order: 1. **Winds Aloft by waypoint** — enter cruise altitude (FL350, FL410), get forecast winds and temps at each route waypoint. API: `/windtemp?format=json` 2. **Flight Category Map** — Leaflet.js map centered on the route, stations color-coded by flight category, route corridor overlay. Deferred because Turf.js route geometry math was saved for post-MVP. 3. **PIREPs near route** — pilot reports filtered to the route corridor. API: `/pirep?format=json` 4. **TFRs** — active temporary flight restrictions. API: `/tfr?format=json` (different response format from airsigmet) 5. **Multi-leg trip view** — full day's operation across multiple aircraft 6. **Saved routes / push alerts** 7. **Radar layer** on the map 8. **Mobile PWA** (offline-capable) 9. **Integration with Airshare/Horizon trip data** --- ## Known Notes / Gotchas - The `airsigmet` endpoint returns ~2,000 records nationally. Bounding box filtering cuts this down significantly for regional routes. For very short routes the box is small; for cross-country the box is large and more hazards show. - TAF not always available for smaller airports (returns empty array — handled gracefully). - IATA identifiers (e.g., `MKC`) work in addition to ICAO (`KMKC`). - Route input accepts space, comma, or slash as separators. - The disclaimer is required on every page per the original brief.