MZQMohd Zamin Quadri
All work

Job search and ranking

Where the Weighted Average Ran Out of Room

A job search tool that reads employer sites directly.

Role
Author
Classification
Engineering prototype
Inspect repository
The seven scoring weights, with the flat penalties applied on two of them drawn on the same axis - which is how you can see they are longer than the terms they belong to.The scoring model's seven weighted components drawn at true proportion on one axis - technical 26, location 20, freshness 16, experience 15, language 13, domain 6, education 4, totalling a hundred points. Two of them, location and language, are marked as carrying a flat penalty, and those penalties extend beneath their own bars from the same origin and on the same axis: 26 points for a role outside your location tiers, 30 for one requiring native German. Both are longer than the weighted term they sit beside, and the overrun is outlined - the part of the penalty the weighted term could never have reached, which is the whole reason a flat deduction exists. The language ladder follows, 8 points for B2, 22 for C1 and above, 30 for native. Then the only four conditions that discard a posting outright, each of which answers whether the opportunity exists rather than whether the candidate is good enough. The sequence closes on reach: nine adapters covering 87 employers, and a probe in which 102 of 279 candidate employers did not answer their own endpoint.
  1. Problem

    Most job results are senior, expired or ineligible.

  2. How it was solved

    It discards what you cannot take, then scores the rest.

    1. Sources
    2. Discard
    3. Score
    4. Rank
  3. Result

    321

    employers, 117 with a verified feed

  4. Built with

    • Python
    • FastAPI
    • TypeScript
    • React
    • PostgreSQL
    See the evidence on GitHub
The scoring model's seven weighted components drawn at true proportion on one axis - technical 26, location 20, freshness 16, experience 15, language 13, domain 6, education 4, totalling a hundred points. Two of them, location and language, are marked as carrying a flat penalty, and those penalties extend beneath their own bars from the same origin and on the same axis: 26 points for a role outside your location tiers, 30 for one requiring native German. Both are longer than the weighted term they sit beside, and the overrun is outlined - the part of the penalty the weighted term could never have reached, which is the whole reason a flat deduction exists. The language ladder follows, 8 points for B2, 22 for C1 and above, 30 for native. Then the only four conditions that discard a posting outright, each of which answers whether the opportunity exists rather than whether the candidate is good enough. The sequence closes on reach: nine adapters covering 87 employers, and a probe in which 102 of 279 candidate employers did not answer their own endpoint.

Personal product / Search and ranking

If a job advert is a wish list rather than a minimum, a search tool should rank rather than filter. So what do you do with the two requirements that really are disqualifying?

Penalties larger than their own weight2 of 7 components

Rank rather than filter, and name every deduction

not an opportunitykeptlonger than the terms beside themNine adaptersOne per applicant-trackingsystem, read directly rather…Discard, narrowlyOnly where the opportunitydoes not exist, or is not this…Not a postingThe only thing removedoutright rather than ranked…PostingsKept with their enrichment, soa score can be recomputed.Weighted sumSeven components, with theweights held in configuration.Flat penaltiesFor the two requirements noweight can express as a matter…Shown with its reasonsEvery deduction named on thejob rather than used to remove…
Discarding is the narrow exception and ranking is the main path, because an advert is a wish list rather than a minimum. The return edge is where the weighted average ran out of room.

This diagram in words

  1. Nine adapters source — One per applicant-tracking system, read directly rather than scraped generically.
    Python
  2. Discard, narrowly gate — Only where the opportunity does not exist, or is not this profession.
  3. Not a posting sink — The only thing removed outright rather than ranked down.
  4. Postings store — Kept with their enrichment, so a score can be recomputed.
    PostgreSQL
  5. Weighted sum process — Seven components, with the weights held in configuration.
    YAML
  6. Flat penalties gate — For the two requirements no weight can express as a matter of degree.
  7. Shown with its reasons sink — Every deduction named on the job rather than used to remove it.
    TypeScript · React

01 / 7Seven components, a hundred pointsTechnical 26, location 20, freshness 16, experience 15, language 13, domain 6, education 4.

Components
7, totalling 100
Largest
technical 26
Smallest
education 4
The scoring model's seven weighted components drawn at true proportion on one axis - technical 26, location 20, freshness 16, experience 15, language 13, domain 6, education 4, totalling a hundred points. Two of them, location and language, are marked as carrying a flat penalty, and those penalties extend beneath their own bars from the same origin and on the same axis: 26 points for a role outside your location tiers, 30 for one requiring native German. Both are longer than the weighted term they sit beside, and the overrun is outlined - the part of the penalty the weighted term could never have reached, which is the whole reason a flat deduction exists. The language ladder follows, 8 points for B2, 22 for C1 and above, 30 for native. Then the only four conditions that discard a posting outright, each of which answers whether the opportunity exists rather than whether the candidate is good enough. The sequence closes on reach: nine adapters covering 87 employers, and a probe in which 102 of 279 candidate employers did not answer their own endpoint.
Read the full background

Problem

Why this work exists

A search for machine learning roles in one country returns thousands of results, almost all of them senior, expired, part-time or somewhere you cannot legally work. Reading them is the actual work. The obvious fix - filter hard - throws away the roles a recent graduate should be applying to, because an advert lists what an employer would like rather than what it requires.

Contribution

What I can claim

Built the whole application: one adapter per applicant-tracking system rather than one scraper per company, a scoring model that penalises instead of filtering, and the interfaces around them. Then fixed the model where it could not say what needed saying - two requirements now carry a flat penalty because a weighted term could not carry it.

Method

When a preference turns out to be a constraint

The tool is built on one claim: a job advert is a wish list, not a minimum, so a search should rank rather than filter.

  1. Read

    Employers rent their career pages from a handful of applicant-tracking systems, each with a public endpoint.

  2. Keep

    Only four conditions throw a posting away, and each asks whether the opportunity exists or is in this profession.

  3. Penalise

    Everything else lowers the score and is named on the job.

  4. Fail

    Then two roles scored in the high seventies that nobody could take: one requiring native German, one on another continent.

  5. Separate

    A weighted term can only move the total by its own weight, so no setting of those weights could express unavailability.

  6. What this does not show

    The weights are one person's judgement about their own search, calibrated against nothing: there is no outcome data behind them, and the premise that a graduate should apply at roughly sixty percent of a posting is an argument rather than a finding. Coverage is uneven - manually watched employers are not monitored automatically - and the tool never applies on anyone's behalf.

How it was built

System

Workflow and decisions

Adapters for 9 applicant-tracking systems reaching 87 configured employers, a matching engine with seven weighted components and explicit penalties, and a full application over the top: setup, review queues, an application pipeline, employer management, automation and analytics.

  1. 1Read employer systems through 9 adapters, one per applicant-tracking system
  2. 2Discard a posting only where the opportunity does not exist or is not this profession
  3. 3Score the rest as a weighted sum over seven components
  4. 4Apply flat penalties where a weighted term cannot express unavailability
  5. 5Name every deduction on the job rather than removing the job
  • Python
  • FastAPI
  • TypeScript
  • React
  • PostgreSQL
  • YAML

Evidence

What is actually versioned

Penalties larger than their own weight2 of 7 components

location is worth 20 points of the score and is docked up to 26 when the job is outside your tiers; language is worth 13 points of the score and is docked up to 30 when the job is native German required. A weighted term can only move the total by its own weight, so neither could express "you cannot take this job" - a mandatory German native role and a role on another continent both scored in the high seventies on technical merit before the flat penalties were added. The full ladders are German B2 8, German C1 and above 22, German native 30 and outside your tiers 26, outside, but remote 10.

Conditions that discard a posting4

not full-time, not this field, clearly outside Europe, older than the age limit. Each answers whether the opportunity is available or in this profession, never whether the candidate is good enough. Everything else is a penalty, which is visible on the job and can be argued with, where a filter is silent.

Employers wired to a real endpoint87 across 9 adapters

Large employers rent one of a handful of applicant-tracking systems, each with a public endpoint, so there is one adapter per system rather than one scraper per company and adding an employer is a line of configuration. The repository reports probing 279 plausible-looking candidates before writing the shipped list, of which 102 - 37% - did not exist; the tool that checked them ships with it.

How the work is checked

Quality controls

How the work is checked

  • Rejection is reserved for four conditions about the opportunity, so a poor match is ranked down and explained rather than disappearing
  • Every deduction is named on the job, which is what makes the ranking arguable instead of merely obeyed
  • Employers were probed against their real endpoints before being configured, and the verification tool is in the repository so the next expansion can be checked the same way
  • Candidate match and field relevance stay separate measures rather than being folded into one number
  • It never applies on anyone's behalf, and the coverage document states which employers are monitored automatically and which remain manual

Limitations

Where the evidence stops

  • The weights are one person's judgement about their own search. Nothing here is calibrated against outcomes, because the outcome data is a handful of applications and cannot support calibration
  • Manual watchlist employers are not automatically monitored, so coverage is uneven in a way the dashboard has to state rather than hide
  • Field relevance is graded from the title and description together, which recovers roles a title-only rule discarded and still makes mistakes in both directions
  • A personal product with one user. It has not been tested against anybody else's search, and the 60% premise it is built on is an argument rather than a measurement
What this changed in my practice

What this changed in my practice

A weighted average is a statement that every consideration is tradeable against every other, and some are not. Both failures looked like scoring bugs and were actually a modelling error: no setting of a thirteen-point language weight makes a native-German requirement disqualifying, because thirteen points is the most it can ever remove. The fix was to stop pretending that constraint was a preference.

Next evidence milestone: Calibrate the weights against something. They currently encode an argument about how graduates should apply, and the honest version of that argument needs outcomes behind it - which means recording what happened to the applications, not tuning the numbers until the ranking looks right.