Skip to content

Show sync health per district on a map - #41

Merged
plmercereau merged 11 commits into
mainfrom
feat/district-sync-map
Sep 18, 2026
Merged

plmercereau merged 11 commits into
mainfrom
feat/district-sync-map

Conversation

@mbayangdiop95

Copy link
Copy Markdown
Contributor

Closes #3.

What changes for you

/syncs now opens on a map of the thirteen districts, coloured by the share of each district's devices that synced in the last seven days, with a legend. Hovering outlines a district; clicking opens a popup with its name, device count and sync percentage, and filters the table underneath to that district. The selection is in the URL — /syncs?district=143 — so the page can be sent to someone.

On the seeded data the map shows what the table could not: Bo, Kambia and Port Loko at 94%, and Kono, Western Area and Pujehun at 0% — the two districts the seed stops ten days ago plus the nearly silent one.

How it works

  • The query. districtSyncHealth returns one row per district: the two counts and the geometry column as it is. It starts from the districts and joins outwards, so a district with no devices comes back with zeroes instead of disappearing. No PostGIS: geometry is plain jsonb and MapLibre consumes it directly (ADR 0007).
  • The arithmetic is not in the SQL. ui/health.ts turns the counts into a percentage, a colour bucket, the GeoJSON MapLibre draws, and the bounds it frames. Pure, so the boundaries are pinned by tests.
  • MapLibre directly, not react-map-gl, loaded with a dynamic import() — see ADR 0015. That keeps its megabyte in its own chunk, fetched by the page that draws a map and no other, and keeps it away from the server render.
  • No basemap. One flat background layer and the polygons: no tile service, no API key, no network request to draw the map.

Two things found on the way

A latent bug in listRecentSyncs. It already matched a facility to its district with split_part(facility.path, '.', 2)::int. Adding a where on the district makes Postgres reorder the join and evaluate that expression before it knows which rows are facilities — including the country, whose path is one segment, so the cast gets '' and the query raises invalid input syntax for type integer: "". The expression is now nullif(split_part(...), '')::int, shared by both queries with a comment saying why. Any future where on that join would have hit it.

An out-of-range district id 500'd. ?district=3000000000 reached where district.id = $1 against an int4. Bounded now in the route schema and in the procedure.

Tests

79 pass. The query on in-process Postgres; the pure module and the legend in Node and jsdom.

DistrictMap.tsx has no test: jsdom has no WebGL and pnpm test runs no browser. Everything decidable without a canvas was moved out of it so the exemption stays narrow — that boundary is the subject of ADR 0015. The preview deployment is the check for this PR, and it is the one thing I could not verify locally.

Two notes for the reviewer:

  • Acceptance criterion "a district with no devices is grey, not red" cannot be seen in the preview: the seed round-robins devices across every district, so none is ever grey. It is covered by tests only.
  • The map is mouse-only — no keyboard or screen-reader route to selecting a district. The table below carries the same data. Worth its own issue rather than scope here.

Documents

  • Spec: docs/superpowers/specs/2026-09-18-district-sync-map-design.md
  • Plan: docs/superpowers/plans/2026-09-18-district-sync-map.md
  • ADR: docs/adr/0015-maplibre-directly-and-an-untested-canvas.md

@vercel

vercel Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
wee-app Ready Ready Preview Sep 18, 2026 10:16am UTC

Request Review

@plmercereau
plmercereau merged commit ade31f9 into main Sep 18, 2026
2 checks passed

This branch was successfully deployed

1 active deployment
Preview — 197b311a Deployed Sep 18, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show sync health per district on a map

2 participants