v1.13.12026-05-29
Performance Overhaul, Security Hardening, Audit Fixes
- Bounding box filter now uses PostGIS spatial index instead of in-memory filtering. Previously fetched 1,000 rows and passed all polygons through regardless of location.
- Nearby endpoint uses PostGIS ST_DWithin with GiST index. Previously loaded all incidents into memory for Haversine calculation (3.4s down to 1.8s).
- Historical data endpoint no longer times out on broad queries. Composite indexes on archive_records reduced query time from 5.9 seconds to 3 milliseconds.
- ETag conditional requests now work correctly. Repeated requests for unchanged data return 304 Not Modified, saving bandwidth.
- Events endpoints now return rate limit headers, ETag, and plan tier (previously plain JSON with no standard headers).
- Supabase admin client now fails fast on missing service key instead of silently degrading to anon permissions.
- WA DFES parser correctly reports centroid confidence when using Perth fallback coordinates.
- Snapshot endpoint returns proper 500 for internal errors instead of masking as 400.
- Sensitive credentials removed from committed agent files.
v1.13.02026-05-28
Tree Down Event Type and Hazard Category
- New tree_down event type for fallen tree incidents. Previously classified as storm or other regardless of cause.
- New hazard category groups physical hazard incidents that are not weather-dependent. Filter with ?category=hazard.
- Improved event type matching catches SA SES-PAGER variants where address text was causing misclassification.
- ACT "Storm or Tree Damage" incidents now correctly classified as tree_down instead of other.
- Backfilled 81,000+ historical records across incidents, incidents_history, and archive_records tables.
v1.12.32026-05-28
Schema Discovery, OpenAPI Completeness, Filter Fixes
- New /api/v1/schema endpoint returns all valid enum values (event types, categories, states, warning levels, etc.) with category-to-type mapping. No auth required.
- OpenAPI spec now documents all filter parameters: category, urgency, certainty were previously undocumented
- Added burn_off and alarm to the eventType enum (were supported but not documented)
- Added eventCategory enum to the response schema with full category list
- Fixed category filter on /incidents/nearby (was silently ignored)
- Added category, severity, urgency, certainty, warningLevel, status, and agency filters to /incidents/history
v1.12.22026-05-27
Historical Data Endpoint, Source Identifiers, Tier Improvements
- New /v1/incidents/history endpoint: access 4.8M+ historical incident records spanning 1840 to 2026 across all Australian states and territories
- Historical data is tier-gated: Starter gets 1 year lookback, Developer gets 5 years, Enterprise gets the full archive
- WA DFES incidents now include CAD dispatch ID, upstream record ID, and deep link URL to Emergency WA website in the details object
- Source ID mapper infrastructure added so future feeds can expose agency identifiers via YAML config
- New API keys now inherit the tier from the user profile instead of defaulting to free
- New /about page with business details, Supply Nation registration, and contact information
v1.12.02026-05-22
Event Categories, Severity Inference, Lifecycle Model, SAAS Notes
- Event category filter on /incidents and /map pages with cascade logic (selecting Fire narrows Type dropdown to bushfire, structure fire, etc.)
- Map legend grouped by category with live counts
- Shared categories module centralises event colours, labels, and formatting across all pages
- Severity/urgency inference chain resolves Unknown values using warning level, resource count, and incident status (severity Unknown reduced from 8.2% to 4.5%)
- Inference applied to both standard and custom-parsed feeds (7 feeds previously bypassed the logic)
- Event category API filter (?category=fire) and event_category column on incidents table (migration 027)
- SAAS operational notes decoder extracts safety flags, police co-response markers, time constraints, and priority overrides from raw pager addresses
- Incident lifecycle model captures state transitions (status, warning level, severity, urgency, resource count) before each poll cycle overwrites the active row
- is_latest flag on incidents_history enables clean single-row-per-incident queries across the 728K+ row archive
v1.11.12026-05-17
SA Geocoding Overhaul, Event Type Fixes, New Guides
- SA geocoding: 196,566 centroid incidents resolved to street or grid-cell level (98% resolved). UBD bounding boxes recalibrated from 30 physical map pages using Redfearn's formulae
- SA Atlas town maps: 11 regional town maps calibrated (Mount Gambier, Whyalla, Angaston, Ardrossan, Balaklava) with 250m grid-cell accuracy for 233 incidents
- SA pager parser fixes: grid refs were being silently discarded for 3-digit page numbers, extractGridRef now searches anywhere in the address string, grid ref takes priority over suburb-level Nominatim
- Regional town fallback: 55 SA town codes resolve to town centroid when no grid-cell data is available
- New alarm event type for fire alarm activations (previously classified as other)
- Domestic gas incidents now correctly classified as hazmat
- SAAS ambulance priority no longer triggers emergency warning level (P1 ambulance is urgent, not a disaster warning)
- New guides: bushfire season 2026-27 preparation, emergency management landscape, EM-DAT schema mapping
- ACT ESA suburb extraction fix (was NULL for all 201 records)
- T340 historical archive: 832K additional rows imported (Phase 3b)
v1.11.02026-04-30
6 New Feeds, Location Search, Historical Data Archive
- 6 new feeds: WA SLIP incident/warning/TFB polygon boundaries, ACT allincidents.json (120 incidents vs 32), TAS theList warning polygons, NSW RFS CAP enrichment with fire perimeters
- Feed count: 27 to 33 across all 8 states plus national sources
- Incidents page: location search with geocoding (search by suburb, filter by radius), severity/warning/agency filter dropdowns
- Incidents page: expanded detail panel now shows first reported time, urgency, certainty, and agency details (fire size, resources, aircraft)
- T340 historical archive: 3.98M rows normalised into archive_records table with EM-DAT international standard fields
- Home Assistant integration built (JackDempsey9/homeassistant-emergencyapi) with geo_location map pins, binary_sensor alert trigger, and incident count sensors
- Fixed event_id schema mismatch on incidents_history (migration 021)
- Geocode proxy at /api/geocode for Nominatim location search
v1.10.02026-04-26
Event Intelligence (D3)
- PostGIS native geometry column with GiST spatial index on incidents table
- Spatial clustering groups related incidents into events using ST_ClusterDBSCAN
- New /v1/events endpoint returns clustered events as GeoJSON with boundary polygons
- New /v1/events/:id endpoint with ?include_incidents=true for drill-down to individual incidents
- Auto-generated event titles (e.g. "Cherry Gardens bushfire") and structured summaries
- Estimated hectares calculated from event boundary polygon area
- Events table with lifecycle tracking and archival to events_history
- Poller integration with 5-minute clustering timer and dirty flag optimisation
v1.9.02026-04-24
Retraction Support, SA Pager Decoder
- Incident retraction system: when upstream feeds stop publishing an incident, it is now marked as retracted instead of silently removed
- Retracted incidents stay visible for 24 hours as tombstones so polling consumers see the retraction signal
- New query parameter ?include_retracted=true to retrieve retracted incidents
- CAP Cancel detection: upstream cancellation signals are detected and surfaced
- CAP-AU output now emits Cancel message type for retracted incidents
- SA pager messages now decode MFS unit call signs (station name + appliance type)
- SA pager messages now decode SAAS priority codes (life-threatening, urgent, routine, etc.)
- SA pager alarm levels decoded to human-readable descriptions (Advice, Watch and Act, Emergency Warning)
- AIDR Warnings Republisher compliance: 11 of 12 obligations now satisfied
v1.8.12026-04-24
Durable Rate Limiting, Security Hardening
- IP rate limiting now survives Vercel cold starts (dual-layer: in-memory + Supabase)
- Domain approval system for new signups (auto-approve major providers, manual review for custom domains)
- Auth route security hardening (redirect validation, RLS tightening, webhook idempotency)
- CAP-AU validator compliance fixes (profile code, timestamp format, language, eventCode, expires)
- Monthly emergency incidents report at /reports with auto-generated breakdowns
- Google Analytics 4 tracking integrated
- Font self-hosted (ChiCZago.woff2), loading skeletons for ISR routes, WebAPI JSON-LD schema
v1.8.02026-04-22
Interactive Map, Stripe Payments, Audit Trail
- Interactive /map page with Leaflet and OpenStreetMap, colour-coded by event type, filterable by state and category
- Emergency warning visual hierarchy with banner, larger markers, and white borders
- Polygon area rendering for fire boundaries and flood zones
- Stripe payment integration with 4 paid tiers (Developer, Team, Professional, Enterprise)
- Pricing page with Mac System 7 styled tier cards and Stripe Checkout
- Subscription management via Stripe billing portal from the dashboard
- /api/v1/incidents/snapshot endpoint for audit trail queries at any point in time
- Latitude and longitude now included in all incident API responses
- Incidents page redesigned as single rolling table with click-to-expand detail panels
- Improved severity and urgency inference from resource counts and incident status
- Burn-off event types corrected (permitted burns, fuel reduction burns, cultural burns now classified as burn_off)
- SA pager geocoding now validates coordinates land within SA state bounds
- 32x32 PNG favicon for Google search results
- CSP updated to allow OpenStreetMap tile servers
v1.7.02026-04-21
SEO Overhaul, Live Incidents Page, Use-Case Pages
- Live /incidents page showing active emergencies across all states, server-rendered with 30s ISR
- 8 per-state incident pages (/incidents/nsw through /incidents/nt) for state-specific SEO
- 4 use-case landing pages: developers, insurance, media, utilities
- Use-cases hub page with cross-linking between all use-case pages
- Dynamic OG image (1200x630) matching the retro Mac design
- Canonical URLs, per-page OpenGraph metadata, and Twitter card upgrade on all pages
- Custom 404 and error pages with navigation back to key sections
- robots.ts, font preconnect, docs iframe accessibility fix
- Switched homepage and quickstart to Next.js Link components for client-side navigation
- Homepage use-case cards now link to dedicated pages
- Satellite hotspot feed excluded from showcase page (still available via API)
- Header, footer, and homepage CTA now link to /incidents
- Sitemap expanded from 8 to 22 pages with real last-modified dates
- SEO score improved from 68/100 to 83/100
v1.6.12026-04-20
Timestamp Fix, WA SLIP Migration, Auth Repair
- Fixed timezone bug where SA and WA ArcGIS feeds returned local-time epochs treated as UTC (106 future-dated incidents resolved)
- New timezone-aware transforms: epochToISOPerth (AWST, UTC+8) and epochToISOAdelaide (ACST/ACDT, DST-aware)
- WA DFES incidents migrated from legacy API to SLIP FeatureServer with Esri token auth
- Signup email verification fixed. Client-side callback page replaces broken server-side route handler
- ACT ESA CAP feed disabled due to 79% event-type misclassification and duplication with primary ACT feed
- Per-feed Uptime Kuma monitors deployed (27 keyword monitors, 120s interval, Gmail alerts)
- PostGIS and pgvector extensions enabled on prod Supabase
- Feed count corrected to 27 active feeds
v1.6.02026-04-17
Adaptive ETL Engine, Production Cutover
- Legacy hand-coded poller retired; the Adaptive ETL Engine is now the sole prod writer
- Feed count expanded from 12 to 27 live feeds across all 8 states and territories
- New national coverage: Digital Earth Australia (GA-HOTSPOTS) satellite hotspots, 36,000+ incidents ingested
- SA now runs 7 feeds (CFS, MFS, SES, CFS-PAGER, SES-PAGER, SAAS-PAGER, BOMBER-PAGER)
- VIC expanded to 5 feeds (EMV, EMV-FIRE, EMV-FLOOD, CFA-FDR, SES)
- Multi-agency correctness: feed_status now keys on (state_code, agency) so every feed has its own row
- Homepage State Coverage + /api/v1/status now report per-feed rather than collapsing by state
- Batched upserts (500 rows/chunk) fix Postgres statement_timeout on large feeds like GA-HOTSPOTS
- Segregation-check warnings no longer block engine startup (were blocking on Alpine where `ps` is unavailable)
- YAML-driven feed configs replace bespoke per-feed code. Adding feeds is now a config change, not a code change
v1.5.02026-04-14
Expanded Data Coverage
- QLD now covers all incident types (structure fires, rescues, MVAs, hazmat) via ESCAD, not just bushfires
- TAS incidents now include real geographic coordinates (previously placeholder geometry)
- WA warnings feed added (CAP-AU format with alert polygons and circles)
- Geoscience Australia earthquake data added nationally (Australian earthquakes, magnitude 2.0+)
- Feed count increased from 10 to 12
- Poller resilience improved with Docker health checks and log rotation
- NT duplicate incident ID issue resolved
- Terms of Service agreement checkbox added to signup
- Attribution endpoint updated with all data sources including SA pager feeds and GA earthquakes
v1.4.02026-04-13
SEO and Analytics
- Open Graph and Twitter card meta tags for link previews
- XML sitemap (emergencyapi.com/sitemap.xml)
- Canonical URLs and structured metadata (19 keywords)
- Vercel Analytics for visitor tracking and page view metrics
v1.3.22026-04-13
Production Polish
- Landing page stats are now live from the database (not hardcoded)
- State coverage table pulls real-time feed status, incident counts, and last polled timestamps
- Agency labels show all agencies per state (not just primary feed)
- WA and NT event type mapping improved (25+ new types, reduced "other" count)
- Status values standardised to "healthy/degraded/down/unknown" across all code
- Better sample JSON response on landing page
v1.3.12026-04-13
Security Hardening and Next.js 16
- Full security audit: 20 findings identified, 11 fixed in code
- Removed service key from client-side bundle
- IP-based rate limiting on auth routes (login 5/min, signup 3/hr)
- Signup no longer reveals if an email is already registered
- Auth callback redirect validated against path allowlist
- Max 10 API keys per user account
- Password change now requires current password verification
- Docker container runs as non-root user
- Cursor pagination validates input format
- Feed status endpoint no longer exposes internal error details
- Upgraded from Next.js 14 to 16, React 18 to 19 (zero code changes needed)
v1.3.02026-04-12
SA Pager Feed Integration
- Integrated SA CFS/MFS and SES pager feeds from urgmsg.net RSS
- Dispatch-level data: exact addresses, units dispatched, incident details
- Automatic deduplication between government and pager feed data
- Address token matching merges pager enrichment into government incidents
v1.2.02026-04-12
Auth System and Dashboard
- Email/password signup with Supabase Auth email verification
- User dashboard with API key management (create, name, revoke)
- Live feed status panel showing all 10 feeds (8 government + 2 SA pager)
- Quick test panel to try API endpoints from the dashboard
- 7-day usage history tracking
- Settings page with profile editing and password change
- Forgot/reset password flow
- Per-user rate limiting across all API keys (500 requests/day shared)
v1.1.02026-04-12
Design System and Landing Page
- Retro Macintosh System 7 design aesthetic
- Chicago font, Mac window chrome, teal desktop background
- Design system document (DESIGN-SYSTEM.md) for consistency
- Security headers: CSP, X-Frame-Options, X-Content-Type-Options
- robots.txt and security.txt (RFC 9116)
v1.0.02026-04-10
Initial Launch
- 8 Australian state feeds: QLD, NSW, VIC, SA, WA, ACT, TAS, NT
- 6 API endpoints: incidents, incidents/:id, incidents/nearby, states, status, attribution
- GeoJSON FeatureCollection responses aligned with CAP-AU standards
- Cursor-based pagination, bbox filtering, geo-radius search
- Poller deployed on Raspberry Pi 4B with Docker
- Resilience: cockatiel retry/circuit breaker, email alerting, stale detection
- API deployed on Vercel at emergencyapi.com
- 212+ tests passing
v0.1.02026-04-07
Project Kickoff
- Monorepo scaffolded with pnpm workspaces
- Database schema designed and deployed to Supabase
- Unified incident type definitions aligned with CAP-AU and GeoJSON RFC 7946
- First two feed parsers: QLD QFD and ACT ESA
- Research completed: competition, legal, technical feasibility, pricing, demand