Skip to content
Work
Case file 02Independent build · 2026

Globe News
Atlas.

World events, coverage, and provenance — with the limit stated in the interface.

Role
Product design + full-stack
Scope
UI, ingestion, pipeline, API, deploy
Stack
React 19, Vite, globe.gl / Three.js, FastAPI, Parquet
Status
Live on Render Free
Globe News Atlas live UI showing a 3D globe with country labels, event markers, bilateral arcs, category filters, and time-window controls
Live atlas · 24h window · 400 of 620 events shown · captured 24 Oct 2026Free-tier demo · first load may take a minute
10
source families
4
time windows
14
category taxonomy
400
event display cap

01 / The brief

A map is a claim about where something happened.

Breaking-news maps are easy to fill and hard to trust. A dot can come from one unreviewed headline, a geocoder guessing from an adjective, or a demo dataset padded to look busy. Each of those teaches the reader something false about the world.

Globe News Atlas starts from the opposite rule: only plot what can be placed, and always show the evidence behind the place. Public feeds are normalized into a Parquet lake, clustered into events, and served with outlet counts, coverage flags, and source links attached.

The interface is allowed to say “not enough data.” It is not allowed to invent it. When the globe can only draw 400 events, the dock reports the true window total instead of pretending the cap is the world.

01

No synthetic rows

Every event in the public snapshot came from a live feed. There is no sample-data mode, and no random fallback coordinates.

02

Free-tier arithmetic

Optional APIs are budgeted before they are called: 8 LLM summaries per run, 10 NewsAPI requests per day, 120 crawl URLs per run. An exhausted quota degrades the product; it does not crash ingestion.

03

Coverage is not consensus

Outlet counts and left / centre / right columns show who is reporting. Single-source and coverage-gap flags stay visible. The atlas does not average disagreement into a false middle.

If it cannot be placed, it is not plotted. If it cannot be corroborated, it is labelled.

02 / The build

The globe is the index. The evidence is underneath.

The map is a way into three kinds of proof: the event, the country, and the coverage around it. Each has its own surface, and each surface keeps the same source links attached.

01 / Scale-aware geography

Labels that know when to leave.

A world map that keeps every label visible becomes wallpaper. The atlas treats labels, markers, and arcs as zoom-dependent evidence rather than permanent decoration.

  • Numbered markers group stories at one location and hold a constant screen size across zoom.
  • Country labels sit at Natural Earth label points, collision-cull to the view, and hand off to state names only at deeper zoom.
  • Trade, diplomacy, sanctions, security, and aid arcs recede once the reader moves to a regional scale.
  • NASA day/night imagery sits under a boundary layer; disputed areas are tinted neutrally.
Close view of the Globe News Atlas globe showing numbered event markers, country labels, and bilateral relation arcs
Globe detail · numbered location clusters · bilateral arcsFree-tier demo · first load may take a minute
Globe News Atlas country desk for China showing eight ranked dispatches with outlet counts, categories, timestamps, and the dock reporting 400 of 621 events
Live country desk · China · 8 dispatches · captured 24 Oct 2026Free-tier demo · first load may take a minute

02 / The country desk

A briefing, not a dropdown.

Clicking a country opens a ranked briefing for the active window. Latest holds the top ten across all topics; Briefing, Protest, Conflict, and Technology narrow the desk without losing the selected country.

  • Latest top 10, then focused sections capped at 10 rows each.
  • Outlet counts, alignment split, category, and timestamp on every row.
  • Country briefs union shorter windows, so a display cap never makes a wider window report fewer dispatches.
  • The dock states 400 of 621 events: the cap is visible next to the true window total.

03 / Beyond the globe

Four ways to read the same evidence.

01

Watchline

Pin up to eight countries and storylines. The return brief shows what moved since the last visit.

02

Storylines

Recurring bilateral relations with the dispatches that keep them alive.

03

Thin File

Dispatches resting on one outlet, one side of the rated press, or a rewritten summary.

04

Rewind

Replay up to 30 days of archived 24h snapshots and rank events whose coverage is thickening.

Dossiers carry APA and BibTeX citations, canonical links, per-event share metadata, and frameable embed cards. Reader accounts are optional and isolated from the data plane: Argon2id hashes, signed sessions, TOTP, Google OIDC, and an active-session ledger.

03 / The pipeline

A batch lake is a feature, not a shortcut.

The system separates what happened from how it is shown. Ingestion and modeling can fail, backfill, or replay without the reading surface depending on a live database. FastAPI is the only door between the lake and the browser.

01

Sources

10 feed families

02

Bronze

raw Parquet parts

03

Silver

normalized + geocoded

04

Gold

clustered events

05

Serving

JSON + SQLite FTS5

06

Atlas

React + WebGL

Hugging Face mirrors the lake at the same paths. The browser never reads Parquet.

0110 feeds

Ingest

GDELT 2.0, RSS, Reddit, Bluesky, USGS, and ReliefWeb; NewsAPI and ACLED optional. One failing source never stops a run.

02120 / 180s

Crawl

An allowlisted crawler honours robots.txt and per-host pacing, skips paywalled publishers, and stops at 120 URLs or 180 seconds.

03cosine + gate

Model

TF-IDF/LSA embeddings feed agglomerative clustering with a title-token gate, then scoring and an extractive fallback.

04atomic + SSE

Serve

FastAPI reads JSON and SQLite FTS with an mtime cache. Writes are atomic; SSE tells connected browsers to refetch.

01

Parquet is the audit trail

Bronze payloads, silver records, and gold events stay as immutable, date-partitioned Parquet parts. Any snapshot can be traced back to the files that produced it.

Trade-off · Freshness is a pipeline property, so every surface reports its snapshot time instead of implying live.

02

Cluster before summarizing

TF-IDF/LSA embeddings and a title-token coherence gate build an event before a summary exists. With no LLM key, the pipeline extracts publisher sentences and never invents text.

Trade-off · A strict gate can split a developing story a person would merge.

03

Accounts never touch the lake

Reader accounts live in SQLite locally and TiDB in production, with signed sessions and first-party cookies. The serving store is read-only and mtime-cached; writes are atomic.

Trade-off · A second stateful system to operate, kept deliberately separate from the evidence path.

04 / The evidence

Every event can be interrogated.

Provenance is not a footer link. It is a set of visible states the interface has to be able to show, including the unflattering ones.

01

Outlets

A count, not a logo wall. Every source is listed and linked.

02

Spectrum

Left, centre, right, and unrated counts for the active event.

03

Single source

Flagged when one outlet carries the story.

04

Coverage gap

Flagged when an event leans on one side of the rated press.

05

Summary origin

LLM-generated or extractive, labelled in the dossier.

06

Location precision

City, admin, country, or region. Unresolved stays off the map.

07

Citations

APA and BibTeX, plus a canonical dossier URL.

08

Share

Per-event metadata and a frameable embed card.

The UI also says when it has no data. Failed requests surface an error banner instead of substituting sample content, and empty coverage states stay empty.

This is the harder half of a news product: a blank state is a feature, not a bug to be filled with decoration. The atlas keeps “no sources found” separate from “sources found, but not yet corroborated.”

05 / Limits

What the atlas will not pretend.

A live data product is more credible when its edges are in the interface. These are the limits stated now, and the ones imposed by the current environment.

Stated in the interface

  • Display cap: 400 events per window. The dock reports the true total — 621 in the country-desk capture in this case file.
  • Country desks show the top 10 per section and label the section count.
  • Rewind is sampled: at most 120 frames over 30 days, 50 events and 18 arcs per frame.
  • Summaries are labelled LLM-generated or extractive; absent evidence is never filled in.
  • Stories with unresolved locations are omitted rather than assigned a fallback point.
  • Headlines and excerpts belong to publishers; the app links out and never serves article bodies.

Imposed by the environment

  • Render Free sleeps; the first request can take up to a minute.
  • Source freshness varies: GDELT is rate-limited upstream, and NewsAPI's free tier is delayed 24 hours and capped at 10 requests per day.
  • Optional feeds only appear when credentials exist; no source is simulated in their absence.
  • LLM summaries stop at 8 per run, then fall back to deterministic extraction.
  • The crawler stops at 120 URLs or 180 seconds per run.
  • One web replica with an in-process rate limiter; scaling out needs shared state.
  • Search index and crawl text are private; the public surface exposes summaries and source links.

Shipped

  • 3D globe and accessible list with four windows, category filters, spectrum filtering, and search.
  • Country desks, event dossiers, citations, canonical links, and embed cards.
  • Watchline, Storylines, Thin File, and Rewind editions.
  • Reader accounts with email/password, TOTP, Google OIDC, and session review.
  • Bronze → silver → gold Parquet pipeline, Hugging Face mirror, FastAPI serving layer, Docker/Render deployment.

Next, honestly

  • Geocoding confidence: a city-level mismatch is still possible; the next step is a visible precision score on every marker.
  • Clustering evaluation: a labelled sample to measure merge and split quality instead of trusting the coherence gate alone.
  • Search ranking: click-through telemetry and an offline evaluation set for the FTS index.
  • Scheduling: move ingestion to a queue with idempotent run IDs when one replica stops being enough.

Read the world, with receipts.

The live build is the same product shown above. Counts move with each pipeline run; the interface reports the snapshot it is showing.