Case study · Automated sourcing system
Automating the search for underpriced listings.
I built it for my own resale operation, where the bottleneck is sourcing: in this niche the best listings are gone within minutes. It watches 12 second-hand marketplaces in 9 European countries, classifies what is really for sale, values each listing against observed market references and sends the few worth acting on to my phone.
The system, in production
Captured automatically from the live system every morning; the date is in the bottom-right corner. Figures are system throughput, not trading margins.
In resale markets, an attractive listing only becomes useful when it can be compared quickly with reliable market references, and the best ones are gone within minutes. Doing that by hand across thousands of new listings a day, in several languages, does not scale.
The system handles the repetitive part: collecting listings, classifying them, comparing them with observed references and prioritising the small subset that deserves manual review.
The pipeline runs automatically from collection to classification, valuation, ranking and alerting. The production implementation remains private.
| Capture at scale | 12 marketplaces in 9 countries, at two speeds: catalog cycles every few hours keep the price database complete, and 34 radars re-scan the focus categories every 1 to 30 minutes. |
|---|---|
| Understanding | Classifies what is really for sale (a whole PC, a single part, an empty box) and extracts the model and components, with one dictionary per language: 8 so far. |
| Relative valuation | Compares each item with observed market references rather than relying on the seller's asking price alone. |
| Opportunity ranking | Scores listings against configurable thresholds so the strongest candidates reach the top of the review queue. |
| Alerts | Sends shortlisted opportunities to mobile with the relevant valuation context and target price for manual decision making. |
Collection was straightforward. Reliable valuation was harder because marketplace data is noisy, incomplete and often mispriced. The first version produced too many false positives.
The next iterations focused on identifying distorted references, improving data quality and recalibrating the scoring rules. The result was a much smaller review queue, with each candidate supported by market references and a configurable margin threshold.
One rule matters more than any threshold: labels, not filters. A price far below normal is flagged “verify in person”, never hidden. Cheap is not the same as fake, and a filter that removes scams also removes the best deals.
Precision matters more than the number of alerts. A smaller set of well-supported candidates is more useful than a large list of false positives.
The core pipeline stays the same; sources, classification rules and valuation logic change by vertical.
The system separates the reusable pipeline from the rules that are specific to each market. A new marketplace is a configuration file and a language dictionary, not a new program; a new vertical needs its own classification and valuation logic.
Reusable pipeline
Collection, deduplication, classification, valuation, scoring and alerting follow the same core workflow across categories.
Vertical-specific rules
Each vertical has its own classification and valuation logic, including cases where component value matters more than the whole item.
New verticals
The same architecture fits other sourcing problems with structured market references and ranking criteria.
Four local AI agents run on my own server (Qwen 2.5 14B through Ollama), with no data sent to cloud AI services. The rule that took me longest to learn: code detects and calculates; the model translates between people and code. Every time a model was asked to judge, or to produce a figure, false data appeared.
| Data agent | Answers business questions in plain language over the whole database (what a part is going for, where it is cheapest, how fast it sells). It never invents figures or links and never writes to the database. |
|---|---|
| Inventory verifier | Lists what is in the box of a complete-PC listing: parts present, missing or broken. It never decides whether it is a deal; the code values the parts. |
| Listing verifier | Decides what is actually being sold before a bike deal is reported, instead of guessing from keywords. |
| Ops agent | Reports system health and hardware sensors and runs a short list of maintenance actions from a closed catalog, each one only after my confirmation. |
The data agent is a cascade ordered by trust. I built the three classic patterns and kept all three; each question stops at the first tier that can answer it:
Code first
Valuations, the operations ledger and system status are answered by deterministic code, with no model in the path.
Typed tools
The model picks a tool and its arguments; every argument is validated and the query behind it is parametrized and read-only.
Verified query catalog
26 hand-written queries the model can select and fill in, including charts and watchlist alerts.
Model-written SQL, as a last resort
Only when nothing above can answer: a read-only role, a SELECT-only validator, a forced row limit and a timeout. Every question that lands here is logged, so the catalog grows from real use.
The model decides what to ask; the code decides what is allowed to run. Answers are written from the rows that came back, and any link that is not in them is stripped before the message is sent.
65+ scheduled jobs and 7 always-on services run on one Windows server. The monitoring is built around one question: did each step produce, not just run?
| Monitoring | 51 checks every 15 minutes that test output: rows still arriving per marketplace, radar passes completed, sold-detection still firing. Each one is tested against old broken logs. |
|---|---|
| Actionable alerts | Every alert carries the command to diagnose it and how to read the result, resolves itself when the condition clears and is written to an incidents table. |
| Self-healing | Hung collectors are killed, a cycle blocked by a site gets one automatic retry, stale locks are cleared and radars brake themselves. After a power cut, the server brings the whole system back with nobody logged in. |
| Data safety | A run that returns far less than the stored catalog cannot overwrite it. The database is dumped nightly to two physical disks, and a restore is tested automatically every week. |
An empty run once overwrote a 142,632-listing catalog, with exit code 0 and clean locks. Since then, every file that accumulates has an anti-wipe guard.
I am not a software engineer by training. I orchestrate the whole system, from the architecture and the product rules to every risk decision and its day-to-day operation, and I program it with AI, specifically Claude, under a protocol I set and enforce:
Diagnose first
Measure against the real data before touching anything or adding a rule.
Complete, safe changes
Each change is a complete script with a backup, a marker so it cannot apply twice and anchors that abort unless they match exactly once.
Verify the real output
I run it on the production server and check what it really printed. Nothing counts as done until the output shows it.
Write down the why
Every change ends with a commit that explains why and a changelog row: 500+ commits since July 2026, with wrong hypotheses written down so each mistake is paid for once.
From me. Some of the most valuable started as me correcting the AI's design: never hide a deal for being cheap, and treat a missing part as a reason to value a listing again, not to discard it.