I kept losing hours of my own job search to listings that didn't fit — so I built the tool I wished existed. iampro is a candidate-side job platform: paste a URL or just describe yourself, and it shows you live, matched openings with honest feedback on fit. I build and run it alone, end to end.

The problem

Job platforms optimize for engagement, not outcomes. Aggregators recycle stale listings, salary is missing from most postings, and "matching" usually means keyword overlap. For a candidate, the real questions are simple: is this job still open, does it actually fit me, what does it pay, and who around me is hiring? Answering those four questions honestly turned out to be a full data-engineering problem.

What I built

A multi-service platform around one shared PostgreSQL core:

  • Ingestion across 20 countries — public employment APIs (France Travail, EURES and national PES feeds), commercial aggregators, and ATS-direct connectors (Greenhouse-style career pages), reconciled and deduplicated into a single index with per-source health monitoring and an anti-stall watchdog.
  • A liveness layer — postings are re-confirmed against their source so ranking favors verifiably-open jobs, not just recently-scraped ones.
  • A 3-layer salary engine — official statistics (Eurostat-class sources), an LLM extraction pass over job descriptions with a per-country regex canary that alerts when parsing quality drops, and a geographic ML fallback. Result: a salary estimate on the large majority of displayed offers, each labeled with its provenance.
  • An employer substrate map — tens of millions of geocoded establishments across the US and Europe, rendered as vector tiles. The naive version scanned 44.9M rows per viewport and died in 502s; the fix was a dedicated read-model table that answers the same question in milliseconds. That map powers a "who is hiring near you" layer and door-to-door canvassing tours for non-desk job seekers.
  • Multi-LLM routing — analysis quality where it matters, cheap models where it doesn't, at ~$0.02 per full job analysis.
flowchart LR
    A[Job sources<br>20 countries] --> B[Ingestion + dedup<br>+ liveness]
    B --> C[(PostgreSQL core)]
    E[Establishment registries<br>US + EU] --> F[Employer map<br>read-model + tiles]
    F --> C
    C --> D[Candidate app<br>match / salary / map]
    C --> G[MCP server]
    G --> H[User's own LLM<br>Claude · ChatGPT · Grok]

The decision I'd defend in an interview

Making the platform agent-native instead of chasing every feature myself. iampro exposes an MCP server: users connect their own Claude, ChatGPT or Grok, and their assistant can search jobs, benchmark salaries, log applications, tailor CVs against an evidence vault — and write pages like this one. The LLM cost rides on the user's existing subscription, not my margin; my job becomes providing trustworthy data and safe, reversible write-tools (every agent mutation returns an undo token). This very article was drafted by an AI agent reading the repository, under an employer-confidentiality guardrail baked into the tool itself.

Honest numbers

Metric Value
Countries with live job ingestion 20
Geocoded establishments (US + EU substrate) 40M+
Cost per full job analysis ~$0.02
Backend test suite 1,450+ tests
Team size 1

What went wrong and what I learned

I over-engineered the first version into microservices, then collapsed it back to a modular monolith — shipping speed beats architecture purity pre-product-market-fit. I burned a week on a map that scanned the whole substrate per viewport before accepting that the correct fix was a boring precomputed table. And I learned to treat my own job search as the test bench: I'm the platform's heaviest user, which keeps the roadmap honest.

Stack: Python · FastAPI · PostgreSQL/pgvector · Redis · SQLAlchemy · Docker · GitLab CI · Claude/OpenAI/Mistral/DeepSeek · Protomaps/MapLibre · Stripe · MCP