Hazard data on this site is live. Case and health records shown are sample data. CryoHealth is in field testing and not yet approved for clinical use.
CRYOHEALTH
Scalable solution for glacier-dependent regions
Sign in

System architecture

Four services share one PostgreSQL + PostGIS database. The EO pipeline measures lakes, the API decides what becomes an alert, and the field app and this website put that alert in front of people.

CryoHealth system architectureOpen full screen ↗

Components

CryoHealth-api ↗
NestJS service that owns product logic: authentication and roles, alert policy, offline sync, admin, and the unauthenticated Open Data API. It is the only place schema migrations are written.
PostgreSQL 16 + PostGIS
The single shared database. Lake points and boundaries are stored as PostGIS geometries (SRID 4326).
CryoHealth-geo ↗
Python / FastAPI pipeline on a schedule. It fetches Sentinel-2 scenes, measures lake water extent with NDWI, writes observations, and posts hazard scores to the API, which stores them.
CryoHealth-app ↗
Expo / React Native field app. Works offline and syncs through the API's /sync endpoint when a connection is available.
cryohealth dashboard ↗
This website, server-rendered with TanStack Start on Cloudflare Workers, for the public, administrators, and CHW leads.
Cloudflare tunnel
The backend host accepts no inbound connections. Traffic reaches the API only through an outbound-only tunnel at api.cryohealth.io.

From satellite scene to alert

  1. CryoHealth-geo fetches new Sentinel-2 scenes for each monitored lake.
  2. It measures water extent with NDWI and writes a row to observations, tagged with the pipeline run ID.
  3. It computes a hazard score and tier and posts it, with every input, to the API, which stores it in hazard_scores (inputs in components).
  4. CryoHealth-api applies alert policy. Creating or overriding an alert requires a human-readable reason, recorded in the audit table.
  5. The field app and this website read the alert. CHWs acknowledge it, and the app syncs field cases back when online.

Design rules

  • One schema authority

    Migrations live only in CryoHealth-api. Every other service reads and writes tables defined there and never alters the schema.

  • Policy is code and people, never silent ML

    The geo service computes scores. Deciding a tier or issuing an alert happens in the API with an audited reason a person can read.

  • Safety information is never gated

    Open Data endpoints need no login. Every other route requires a signed token and one of four roles: cryohealth_admin, facility_admin, chw, or viewer.

  • Offline first

    Each case from the field app carries a client-generated ID, so repeated syncs from a device are idempotent. Every sync is logged in sync_log.

  • Reproducible

    Every observation and hazard score carries the run ID that produced it, and scores keep their inputs so any tier can be recomputed later.

Source documents

The tables behind this flow are documented in Schema design.