Firas Mohammed
← All work
Data pipeline · AI cost engineering

679,162 free public records from the chaos of Arabic social media

Families in Sudan were searching Facebook groups post by post for one chassis number. This pipeline ingests, transcribes and scores tens of thousands of Arabic posts into a registry anyone can query, and it had to be re-engineered until it could afford to run. The interesting part is what it cost to make it work, and what the metrics were hiding.

Personal project · Python, Claude and OpenAI APIs, Google Cloud Vision · 2026

Context

The project started for a private reason: a family vehicle was taken during the war in Sudan, and the only trace of vehicles like it is in Arabic-language Telegram channels and Facebook groups — recovery lists, auction posts, photographs of paperwork. Thousands of posts a week, no search, no structure, and a real answer hiding somewhere inside them.

It stopped being a private project quickly. The same posts that might contain one vehicle contain tens of thousands of others, each one somebody else's. So the system now maintains a searchable registry that other families can query — by partial chassis number, plate, Arabic or Latin digits, or free text.

What I did

679,162 records · 106,595 posts · 133,161 media items

Collected, transcribed, scored and made searchable. Every image in the corpus has been transcribed exactly once.

The gate that earned its keep

Coverage was measured per post, which looked healthy and was hiding a disaster: a single list containing 684 vehicles could return 401 of them and still score a perfect pass, because the post itself had been processed. That shape of error had silently lost on the order of 130,000 records.

The fix was a shortfall gate that compares records emitted against chassis-shaped numbers present in the source, and flags the gap rather than blocking on it — because a list of bare tracking codes legitimately yields zero vehicles, and a gate that cries wolf gets switched off. A second fix mattered as much: the grounding check originally validated against post text alone, which would have discarded every identifier recovered from a photograph. On one wave that was 537 identifiers.

Where the corpus goes before it reaches a paid model (figures from the earlier processing run; the live collection has since grown to 106,595 posts)

Collected 79,680 posts
Scored 43,136 posts

The difference is not lost work. It is posts removed by the deterministic identifier scan, the relevance gate and content-hash deduplication — none of which cost an API call, and none of which discard information.

What I would tell you in an interview

Every expensive decision on this project was one I made before I measured. The vision-first architecture, the model choice, the coverage metric — each felt obviously right, and each was wrong in a way only a benchmark or a reconciliation exposed. The habit I took from it is the one I would bring to any operation: instrument the thing, compare what it claims against what actually landed, and treat a green metric you have not audited as an untested assumption.

Where this transfers

What it means for an employer: I turn chaotic multilingual data into a registry people can rely on, report honestly even when the dashboard says green, and manage model and cloud cost like a budget line. This is a document-processing pipeline with a cost ceiling and a correctness requirement, which describes a great deal of commercial work: claims intake, KYC and onboarding documents, invoice and receipt capture, compliance review. The pattern generalises directly — filter deterministically before you filter probabilistically, transcribe once, tier your models, and never trust a completion rate you have not reconciled against the source.