I run online stores as a side project, and the catalog was always the part that quietly broke: supplier prices and stock change constantly, so the listings drift out of date until a customer orders something that's actually unavailable or mispriced. I wanted to remove the manual checking entirely and only spend human attention on the cases that really need it.
So I built a small automation that keeps the catalog in sync on its own. Here's what it does, the stack, and — more importantly — what I learned along the way.
What it does
- Pulls catalog, stock, and price data from the supplier source
- Normalizes messy product fields and matches them to the store's listings
- Aligns stock and price automatically when there's a confident match
- Flags exceptions for review — unmatched SKUs, suspicious price jumps, items going out of stock
- Runs on a schedule, so the catalog stays current without anyone watching it
The stack
- n8n — orchestration and scheduled workflows
- Ollama (local LLMs) — cleaning/normalizing unstructured product fields, cost-free and offline
- Python — data handling and the deterministic checks around the LLM
- MCP connectors — to wire the tools together
-
Environment variables — all credentials stay in
.env, nothing secret in the code
How it works (high level)
- A scheduled n8n workflow triggers the run.
- Supplier data is fetched and passed through a cleaning step — the LLM where the data is messy, plain rules where it isn't.
- Items are matched to existing store listings.
- Confident matches get their stock/price updated automatically; everything uncertain goes to an exceptions list for a quick human pass.
What I learned
- Orchestrating reliable scheduled jobs in n8n instead of one-off scripts.
- Running LLMs locally with Ollama — what they're genuinely good at (cleaning fuzzy data) and where they're not.
- When not to trust the model. I also do paid AI-output evaluation, and that habit shaped this build: anything that touches price or stock goes through deterministic checks, not the LLM alone.
- Designing for the exception path, not just the happy path.
Top comments (0)