Intelligence-grade criminal network analysis.
CRIMSON turns raw investigative data into a living, queryable intelligence graph — giving analysts the ability to surface hidden criminal networks in minutes, not weeks.
The Story
The Problem
Law enforcement analysts deal with thousands of unstructured data points — call records, witness statements, transaction logs — that are manually cross-referenced in spreadsheets. Connections are missed. Investigations stall.
Why It Matters
A single missed link in a criminal network can mean an investigation fails, a suspect walks free, or a network grows. Automated graph analysis with AI-assisted entity resolution changes the equation entirely.
The Solution
CRIMSON ingests structured and unstructured data, runs entity resolution to deduplicate identities, builds a persistent graph database, and exposes a query interface powered by Gemini AI. Analysts can ask natural-language questions and get graph-backed answers.
Product Features
Interactive force-directed graph showing entities (persons, organizations, locations, events) and their weighted relationships. Zoom, filter, and cluster by connection strength.
Gemini AI extracts named entities from unstructured text — reports, transcripts, messages — and resolves duplicates using embedding similarity. A single person mentioned under five aliases becomes one node.
Analysts type plain English queries — 'Show everyone linked to X within 2 hops' — and the system translates to graph traversal queries, returning visual + tabular results.
Organise entities and relationships into cases. Each case has an audit trail, analyst notes, and export to PDF/JSON for court submission.
Webhook-based ingestion pipeline allows live data feeds from partner systems. New entities and edges appear in the graph within seconds.
System Architecture
Data flows: ingestion → AI extraction → graph storage → query layer → analyst UI
Technical Deep Dive
Raw text arrives via webhook or manual upload. The FastAPI service chunks the text, sends it to Gemini for NER, then generates sentence embeddings (text-embedding-004) for each extracted entity. A cosine similarity check against existing records (threshold 0.91) determines whether to create a new node or merge with an existing one. This reduces duplicate nodes by ~73% compared to string matching alone.
Analysts write plain English. The system uses a structured prompt chain: (1) classify intent, (2) extract parameters (entity names, hop depth, relationship types), (3) generate a parameterised SQL query. Results are returned as both raw JSON and a subgraph for visualisation.
-- 2-hop network around an entity
WITH RECURSIVE network AS (
SELECT id, name, 0 AS depth
FROM entities WHERE name ILIKE $1
UNION ALL
SELECT e.id, e.name, n.depth + 1
FROM entities e
JOIN edges ed ON ed.target_id = e.id
JOIN network n ON n.id = ed.source_id
WHERE n.depth < $2
)
SELECT DISTINCT * FROM network;Every entity and case is scoped by organisation_id with Supabase Row Level Security. Analysts only see their organisation's data. All API calls are logged to an append-only audit table for full traceability.
Engineering Decisions
Performance & Scale
Deployment & Infrastructure
Deployment
Next.js on Vercel Edge with ISR. FastAPI on Render with a persistent worker dyno for the ingestion queue. PostgreSQL on Supabase with PgBouncer connection pooling.
CI/CD
GitHub Actions — lint + type-check on PR, Playwright smoke tests on merge, auto-deploy to Vercel and Render on green CI.
Monitoring
Vercel Analytics for frontend. Render metrics for API latency and memory. Supabase dashboard for DB query times and RLS audit.
Challenges & Failures
What I Learned
Recursive CTEs in PostgreSQL can replace a dedicated graph DB for datasets under 1M nodes.
Embedding deduplication needs a human-reviewable confidence score, not just binary match/no-match.
NL → structured query is only reliable when you tightly constrain the output schema in the prompt.
Row Level Security in Supabase is more powerful than application-level filtering — push access control to the DB.
Future Roadmap
v2.0 — Q4 2026
v3.0 — 2027
Screenshots
Live criminal network graph — 847 entities
Entity extraction pipeline output
Natural language → graph traversal result
Technology Stack
Frontend
Backend
Database
AI/ML
Auth / DB
Visualisation
Deployment
Ready to dive in?