OpenWatch: Building an AI-Powered Security Intelligence Platform for Nigeria
Nigeria faces a complex and fragmented security landscape – kidnapping, terrorism, armed robbery, communal violence – spread across 36 states and reported by dozens of sources in varying levels of detail. I built OpenWatch to turn that noise into signal: a real-time intelligence dashboard that ingests raw news, extracts structured incident data using AI, deduplicates it semantically, and presents it on an interactive tactical map with daily intelligence briefs.
The problem
Security information in Nigeria is scattered across news sites, social media, and word of mouth. There's no single source of truth. Reports are often duplicated across outlets, written in a mix of formal English and Pidgin, and lack structured metadata like exact coordinates, incident categories, or severity assessments. Journalists, researchers, and security professionals have to manually piece together the picture.
How it works
OpenWatch runs a fully automated intelligence pipeline:
Ingestion
RSS scrapers pull articles from major Nigerian outlets (Punch, Vanguard, Premium Times, and others) on a cron schedule. A Twitter scraper monitors security-focused accounts for breaking reports.
AI extraction
Each article is sent to OpenAI's GPT models with a heavily tuned system prompt that understands Nigerian geography (all 36 states + FCT), Nigerian English and Pidgin slang, and a taxonomy of 12 incident types (terrorism, kidnapping, armed robbery, communal violence, cattle rustling, etc.). The model returns structured data: location, date, severity, fatality counts, and a narrative summary – with strict rules to reject personal recounts, aftermath stories, and non-Nigerian incidents.
Semantic deduplication
The same incident reported by five outlets shouldn't appear five times. OpenWatch generates vector embeddings for each extracted incident and uses pgvector's cosine distance to find semantically similar records within a 72-hour window. A multi-signal fusion score combines semantic similarity, geographic proximity, and temporal closeness. Duplicates are merged, and new sources are linked to existing incidents – improving confidence over time.
Confidence scoring
Each incident gets a composite confidence score based on source tier (Tier A outlets like Punch score higher than unverified social media), the number of corroborating sources, extraction clarity, and location specificity.
Geocoding
Extracted locations are resolved to coordinates for map plotting, with geohash-based spatial indexing for efficient proximity queries.
Daily intelligence briefs
Every day, an AI analyst prompt synthesises the day's incidents into an executive brief: headline, threat level assessment, hotspot regions, key developments, and incident breakdowns by type. These briefs are stored, browsable by date, and update in real time via Supabase subscriptions.
Automated Twitter posting
A bot auto-tweets individual high-severity incidents and publishes daily, weekly, and monthly summary images with trend data and threat assessments.
The stack
Design decisions worth noting
pgvector for dedup, not just search
Most projects use vector databases for RAG or search. Here, embeddings are the core of a deduplication engine – turning a fuzzy “is this the same incident?” question into a quantifiable similarity score fused with spatial and temporal signals.
Security-first data model
Every table uses Supabase Row-Level Security. Public writes are routed through server-side API routes with validation. Service role keys never touch the client. This isn't optional when you're handling sensitive security data.
Domain-specific AI prompting
The extraction prompt isn't generic – it encodes Nigerian geography, distinguishes between Nigerian English and Pidgin, enforces a strict incident taxonomy, and includes rules to reject common false positives (celebrity recounts, aftermath stories, court proceedings). Classification accuracy comes from domain specificity, not model size.
Responsive intelligence UI
The dashboard adapts from a desktop split-pane layout (map + feed + detail panel) to a mobile-first bottom sheet interface. The daily brief component works as both an inline feed element and a floating pill with a drop-up panel.
What I learned
Building OpenWatch pushed me on the intersection of AI, data engineering, and product design. The hardest problems weren't technical – they were domain problems: teaching an LLM the difference between a bandit attack and an armed robbery in the Nigerian context, handling the ambiguity of “unknown gunmen” reports, and deciding when a confidence score is high enough to publish automatically.
The technical work – pgvector dedup, real-time subscriptions, pipeline orchestration – was the foundation, but the intelligence layer on top is what makes the platform useful.