01
Cloudflare for hosting instead of Vercel/AWS
Cloudflare is generally reachable from Cuban IPs, which matters because the users are in Cuba. Tiles and data are served from the same origin so nothing depends on blocked third parties.
Personal project
Near-real-time Havana blackout map built from a Telegram channel
gha runs the tests, then the ingestor pulls new posts, rules and LLM jobs turn them into events and enrichment, and builders publish fresh static data to Pages.
Click a step to jump to it. Click a component for details.
A public map and Telegram bot that tells Havana residents which blocks and circuits have power. It ingests the utility's Telegram channel and its comment group, extracts outage events with rules plus LLM enrichment, and publishes a static, Cuba-reachable site with analytics, circuit pages and a conversational assistant.
Outage information in Havana is scattered across free-text posts and comments on a Telegram channel. Residents have no structured, searchable view of current state, hours without power per circuit, or history.
01
Cloudflare is generally reachable from Cuban IPs, which matters because the users are in Cuba. Tiles and data are served from the same origin so nothing depends on blocked third parties.
02
Telethon fetches messages since the last stored id on each run, avoiding a paid always-on server. A user MTProto account is required because a bot cannot read the channel.
03
GitHub's own scheduler arrived late on average and overlapping triggers cancelled each other. A component outside GitHub fires workflow_dispatch and monitors freshness, so a GitHub stall cannot hide itself.
04
Official posts are highly regular, so regex rules handle most of them cheaply and predictably. LLM steps are non-blocking and state ages to unknown when there is no news, avoiding confident wrong answers.
05
The vector index was too large to ship as a static file. Keeping it in the database means vectors never leave the server; the worker sends the query and receives only the top-k fragments, using 1024-dim Matryoshka embeddings to fit ivfflat limits.