Skip to content

Decision records

Every non-obvious structural choice in JobHub is written down as an ADR before it is built. New records start from 0000-adr-template.md and take the next free number.

Numbering quirks

The sequence is not perfectly dense. There are two 0009s (ghosted alert and interview reminders, written in parallel), no 0010, and 0004-test-cases.md is a companion test-case document rather than a decision. Numbers are never reused or renamed once merged, because other ADRs, commit messages and tickets link to them.

Grouped by area, newest first within each group.

Crawling and enrichment

ADR Decision Status
0032 Shutdown-safe crawler scheduling and trigger-run visibility Proposed
0029 Crawl-run visibility: log-level policy, per-target new counts, live progress Accepted
0021 Location normalization at crawl-write time Accepted
0017 Multiple locations per job post Accepted
0016 Crawl until N new posts, not N sources Accepted
0006 Cooperative cancellation for admin-triggered passes Accepted
0004 Config-driven LLM provider registry for enrichment (test cases) Proposed
0003 Admin-only trigger for crawl and enrichment passes Accepted

Job search and companies

ADR Decision Status
0030 Saved filters are per-user server state; compensation filter leaves the UI Accepted
0026 Automatic company enrichment (crawler infers, job-service writes derived) Superseded by story #484
0025 Admin company enrichment: manual-edit override and admin endpoints Accepted
0024 Company logo resolution: job-service derives it Revised (2026-07-25)
0023 Company as a first-class entity: schema ownership, identity slug Accepted
0020 Facet cache invalidated by a crawl-data generation stamp Accepted
0018 Best-effort totals: estimate above a threshold, short-TTL cache Accepted
0005 Job-post query performance: indexes and full-text search Accepted
0001 Filter-aware (drill-down) facets for GET /jobs/facets Accepted

Identity and security

ADR Decision Status
0028 Unconfigured OAuth providers are a first-class state; just-in-time names Accepted (amended)
0027 Social login (Google, GitHub) via OAuth authorization-code Accepted
0022 Apply-profile answer bank in auth-service Accepted
0019 Admin trigger gated by the admin's own 2FA Accepted
0012 TOTP two-factor authentication Accepted
0002 Email-code account verification (verify before login) Accepted

Notifications and applications

ADR Decision Status
0031 Notification category derived from notification type Accepted
0015 Freeze company logo and name on the application job-post snapshot Proposed
0014 Notification cards carry company and job title via enrich-at-read Accepted
0013 Resolve the per-application reminders routing collision in the contract Accepted
0011 Custom reminders and the channel-gating fix Accepted
0009 Interview reminders (24h + 1h): idempotency, internal endpoint, preferences Proposed
0009 Ghosted alert via a service-key-authenticated internal status update Proposed
0008 Weekly digest email: cross-service communication and design Proposed
0007 notification-service: architecture and preferences API Accepted

Status is the record's own claim

Several ADRs still read Proposed even though the work shipped: the status field was not always updated at merge. Treat the code and the architecture overview as authoritative for what is live, and the ADR as the reasoning behind it.