Developer

Architecture

H2OFlows system architecture — backend, frontend, data model, and hosting.

What this is

H2OFlows is a streamflow data platform — a gauge dashboard backed by an open reach registry that the entire whitewater community can build on. At its core it aggregates real-time CFS readings from USGS and Colorado DWR, overlays community-defined flow ranges, and ties gauge data to geographic reach records (put-ins, take-outs, rapids, access notes).

The platform is free, open source, and will remain so. The data belongs to the community.

Tech stack

Backend

LayerChoice
LanguageGo
RouterChi
DatabasePostgreSQL 16 + PostGIS
Migrationsgolang-migrate
AIAnthropic Claude (anthropic-sdk-go)
Object storageCloudflare R2 (planned)
AuthSupabase (Google OAuth)

Frontend

LayerChoice
FrameworkNuxt 4
UINuxt UI (Tailwind CSS v4)
StatePinia
MapsMapLibre GL

Infrastructure

ComponentHosting
APIEC2 at api.h2oflows.app (Docker Compose + Caddy)
Web appNetlify at h2oflows.app
DocsNetlify at docs.h2oflows.app
DNSCloudflare

Repositories

RepoContents
h2oflows-app/apiGo backend, migrations, gauge adapters
h2oflows-app/webNuxt 4 frontend
h2oflows-app/docsThis documentation site

Gauge adapters

The gauge-core package in the API implements a plugin interface for data sources. Each adapter is a single file that satisfies the interface. Current adapters:

  • USGS — National Water Information System (waterservices.usgs.gov)
  • DWR — Colorado Division of Water Resources (dwr.state.co.us)

Adding a new data source means writing one adapter file. See the contributing guide for details.

Data model (key tables)

gauges          — gauge metadata (source, external_id, name, lat/lng)
gauge_readings  — time-series CFS readings per gauge
reaches         — river sections (slug, name, class, geometry)
reach_gauges    — many-to-many: reaches linked to gauges
flow_ranges     — CFS band definitions per reach (too_low / min / optimal / pushy / flood)
rapids          — rapid inventory per reach (name, class, coords, description)
reach_access    — put-in/take-out/parking/shuttle per reach
dashboards      — named watchlists per user
watchlist_items — gauge memberships in dashboards

Reach data seeding

Reach content is seeded using AI (Claude) from guidebook knowledge, American Whitewater records, and community trip reports. The cmd/seed-reaches tool defines reaches with local knowledge notes embedded in the seed prompt; the AI generates rapid inventory, access notes, descriptions, and flow ranges.

Every seeded item carries a data_source and confidence score:

  • confidence >= 85 → auto-verified
  • confidence 50–84 → stored as draft, shown with badge
  • confidence < 50 → dropped at generation time

Community corrections and verified field data override AI-seeded content.

Build phases

PhaseStatus
Phase 1 — Gauge dashboardComplete
Phase 2 — Reach pages + user featuresComplete
Phase 3 — Accounts, alertsDeferred (post-pilot)
Phase 4 — Trip planningPlanned
Phase 5 — Permit trip modulePlanned
Phase 6 — Public API docs + token issuanceParallel to Phase 3+

Contributing

Non-developer contributions:

  • Add or verify reach data for rivers you know
  • Define flow ranges for local gauges

Developer contributions:

  • Issues tagged good-first-issue are the entry point
  • Gauge source adapters are the easiest first contribution

See CONTRIBUTING.md for development setup.