Skip to content

AutoLens LK

A full-stack platform that watches Sri Lanka's car listings across three sources, tracks price trends, and scores deals against genuine comparables — with per-source isolation so one broken scraper never takes the pipeline down.

vehicle-platform-one.vercel.app
vehicle-platform-one.vercel.app

Case preview

AutoLens LK

Vehicle-market intelligence, scraped twice a day, scored by comparison.

ReactViteTypeScript

The Problem

Buying a used car in Sri Lanka means guessing. Listings sit on three big sites, prices drift, and there's no way to know whether the one in front of you is a fair price or an optimistic one. The information exists — it's just never assembled.

AutoLens LK assembles it: it watches the market continuously and answers the buyer's real question — is this a good price, compared to cars actually like it?

Averages lie. A "good deal" only means something against comparables — same make, same segment — not against the whole market.

The System

A FastAPI backend on Fly.io scrapes vehicle listings from Ikman, Riyasewana, and Patpat, normalizes them into Postgres, and surfaces price trends, deal scoring, and market insight through a React front end on Vercel. Scraping runs twice a day inside GitHub Actions — entirely in the cloud, no server babysitting.

Fig. 1 — Parallel, isolated multi-source scraping pipeline.

GitHub Actions2×/day
Ikmanisolated job
Riyasewanaisolated job
Patpatisolated job
Normalize + scoreFastAPI · Postgres

The Build

The Proof

Fig. 2Pipeline and deployment at a glance.
3
sources scraped
2×/day
in GitHub Actions
per-source
fault isolation
CI/CD
Fly.io + Vercel

Full continuous deployment — backend auto-ships to Fly.io, front end to Vercel on every push — and the live platform is linked from Suven's profile. It's the pattern behind the whole market-intelligence family: scrape reliably, normalize honestly, score usefully.

Margin Notes

  • What broke first: duplicate listings across sources. The same car posted to two sites had to be de-duplicated before scoring, or the "market" was double-counting itself.
  • What I'd redo: capture raw scraped payloads before normalization from the start — when a parser is wrong, you want to reprocess history, not re-scrape it.
  • What shipped anyway: the fault isolation. It's invisible when everything works, and the entire reason the data is still fresh the week a source changes its HTML.

Next — 01

SEOS