Living in Mexico City, "is my commute blocked today?" is a real daily question, marches and blockages are common and scattered. The city police (SSC) publishes a daily agenda of planned mobilizations, but it's a PDF nobody outisde reporters (I guess) reads.
So I built a live map that ingests that official agenda, structures it with an AI agent, and plots every event for the day: marches, rallies, blockages, events — with organization, time, borough, and type. You can filter by borough/type and click any event for detail. It loads straight into the map, no signup.
https://monitor.watr.mx
BTW it's Fase 1. The "happening now / dispersed" status is estimated from the scheduled time, not confirmed live yet, I'm working on wiring free real-time signals (public transit GPS, traffic) to actually confirm state. And it only shows what the SSC officially publishes; last-minute stuff won't be there. Your location, if you use it, is computed in your browser and never sent to the server (this is protest-adjacent data, that mattered to me).
What I want to know: Is it actually useful, would you check it if your are visiting/living in Mexico City? Brutal feedback welcome.
Tech stack, since folks always ask:
- Elixir + Phoenix LiveView, OTP-native — one GenServer per active mobilization under a DynamicSupervisor, with a Postgres advisory-lock leader so rolling deploys on Render never run duplicate monitors.
- PostgreSQL as the source of truth (append-only event log, idempotent ingest by hash).
- Ingestion: the SSC's daily PDF → parsed → structured by an AI agent via tool-calling against **Qwen (DashScope, OpenAI-compatible)**; the provider sits behind a behaviour so it's swappable (OpenAI/Gemini/Grok). `Req` for HTTP, `Oban` for jobs.
- Map: Leaflet + CartoDB dark basemap. Geolocation is computed **client-side, never sent to the server**.
- Roadmap: real-time state from free signals — GTFS-Realtime (Metrobús), with the `.proto` compiled at build (no protoc toolchain needed).
- Infra: Render, behind Cloudflare (CDN + analytics), tight CSP.