Case study

Job-Search Intelligence App

A single-user Python and SQLite application that ingests job postings through a third-party data API, scores them against a weighted rubric that shows its reasoning, and tracks the pipeline through a single confirmed-write path.

Role
Sole developer
Organization
Personal project
Status
Shipped
  • Python
  • SQLite
  • SQL
  • JavaScript
  • HTML5
  • CSS
Walkthrough

Screens

  • Dashboard overview with four headline tiles (200 jobs tracked, 30 found today, 19 strong and unapplied, 58.7 average score), a filter row, and a Needs Action list ranking postings by match score with a note on each saying why it needs attention.
    The morning view. Headline numbers, filters, and a Needs Action list that says why each posting is there. Company names in every screenshot are anonymized to Employer NN placeholders.
  • Job detail drawer showing a score of 99 and a "Why this score" panel that breaks it into title 45 of 45, skills 35 of 35 with the matched terms listed, seniority 10 of 10 and location 9 of 10, above the status and notes form.
    Every score comes with its reasons. The four components and their denominators are stored with the row and shown here, so a number can be argued with.
  • Pipeline board with columns for New, Applied, Phone Screen, Interview, Offer and No Response. Each card shows the job title, company, a score chip and a score bar; some cards carry a repost tag.
    The pipeline board. Drag a card to change its status; the drop is the confirmation and undo is one click away. Every transition is logged by a database trigger.
  • Three cards side by side. Match score distribution as horizontal bars by score band; jobs found per day as a bar chart over the last 14 days; scan health listing three configured scans with their last run result and an ok or never-run status.
    Scan telemetry and score distribution. Every chart has a table twin, and a scan that has never run is shown explicitly rather than missing.
  • Pipeline composition panel with a banner reading "Descriptive only. This panel reports what the scans brought in; it does not recommend what to search for or apply to." followed by a per-scan table and bar breakdowns of role mix and location.
    The analytics describe and never recommend. The guard rail is stated in the interface, and breakdowns refuse to report a percentage below a minimum sample.

In one minute

A local desktop app that replaced a broken Excel job tracker. Every weekday morning it pulls new postings, scores each one against a rubric that explains itself, and puts the ones worth acting on at the top of a board.

The problem

  • An Excel workbook fed by third-party scheduled scans. Both halves failed at once: the scan triggers were deleted, and the workbook could not be written to while it was open.
  • No record of status changes, so funnel and velocity questions could not be answered.
  • Match scores were an opaque number nobody could interrogate or correct.

What I built

  • Own the acquisition. Postings are ingested through a third-party data API on a schedule, with spend treated as a correctness concern: a monthly budget pre-flight can refuse a run, and a dry-run mode prints the worst-case cost before spending anything.
  • A rubric that shows its work. 100 points across title (45), skills (35), seniority (10) and location (10). The score and its reasons are stored together and shown in the UI and every export. Missing evidence lowers confidence rather than raising the score.
  • One way to change a row. Status edits, drag-and-drop and undo all go through the same backend plan → confirm → apply path; a database trigger writes the history so no code path can skip it.
  • Analytics that know when to stay quiet. Conversion rates return “not available” with a reason instead of 0% over an empty sample, and the composition panel describes the pipeline without recommending anything.
  • Application materials from a locked template. Documents are assembled by copying a template and rewriting only the wording paragraphs; the fact paragraphs are locked and the assembler raises if anything tries to write to them.

Rules the whole system enforces

  • A number never travels without its denominator.
  • Unknown is a state, not a zero.
  • History is never rewritten: a posting keeps the search title that found it, permanently.
  • Anything irreversible needs confirmation; anything reversible gets undo instead.

Outcome

  • Its own export produced the market read behind this site’s positioning: Power BI and SQL led the tracked postings, and governance vocabulary (NIST, GRC, SOX, ISO 27001) appeared often enough to be the differentiator rather than a footnote.
  • Runs unattended on weekday mornings; every planned item shipped.
  • No accuracy or time-saved figure is claimed, because nothing in the app measures one. That is the same rule the app applies to itself.

Stack

Python 3.13 · SQLite (WAL, triggers, CHECK constraints) · hand-written HTML/CSS/JS with no framework · pywebview desktop window · no build step.