Files
Jens b8091e59bd
deploy / deploy (push) Canceled after 0s
Initial deploy setup
2026-07-21 14:00:00 +02:00

4.4 KiB

Datamodel

Entity-relatiemodel

erDiagram
  USER ||--o{ SEARCH_PROFILE : owns
  SEARCH_PROFILE ||--o{ PROFILE_REVISION : versions
  SEARCH_PROFILE ||--o{ SCORE_RUN : evaluates
  SEARCH_PROFILE ||--o{ DIGEST_OUTBOX : receives

  SOURCE ||--o{ SOURCE_RUN : executes
  SOURCE ||--o{ RAW_DOCUMENT : retrieves
  SOURCE_RUN ||--o{ RAW_DOCUMENT : produces
  RAW_DOCUMENT ||--o{ JOB_SOURCE_ALIAS : evidences
  RAW_DOCUMENT ||--o| EMAIL_MESSAGE_RECORD : wraps

  EMPLOYER ||--o{ JOB_POSTING : publishes
  JOB_POSTING ||--o{ JOB_SOURCE_ALIAS : aliases
  JOB_POSTING ||--o{ FIELD_PROVENANCE : fields
  JOB_SOURCE_ALIAS ||--o{ FIELD_PROVENANCE : proves
  JOB_POSTING ||--o{ JOB_VERSION : versions
  JOB_POSTING ||--o{ SCORE_RUN : scored
  JOB_POSTING ||--o{ FEEDBACK : receives
  JOB_POSTING ||--o{ APPLICATION : tracked
  USER ||--o{ FEEDBACK : gives
  USER ||--o{ APPLICATION : owns

Entiteiten

SearchProfile

Bevat harde/soft voorkeuren, locatie, drempels, digesttijd en version. De JSON-velden blijven schematisch gedocumenteerd in docs/api/INTERNAL_CONTRACTS.md en gevalideerd in service/formcode.

Belangrijke invarianten:

  • unieke naam per user;
  • recommendation threshold ≤ top threshold;
  • gewichten numeriek, niet-negatief en met positieve som;
  • coördinaten binnen bereik;
  • precies één actief profiel per user via activate()-serviceflow.

Source

Bronregister met source_type, status en onafhankelijk policy.

Status betekent operationele toestand; policy betekent toestemming:

  • candidate — ontdekt, niet actief;
  • trial — beperkte proefcontrole;
  • active — normaal gepland;
  • quarantined — automatisch/manual geïsoleerd;
  • paused/disabled — niet plannen;
  • allow/review/deny — netwerktoegangsbesluit.

Een deny-bron mag niet active zijn.

RawDocument

Tijdelijke immutable-ish fetchsnapshot. Bevat alleen begrensde tekstbody, headers op allowlist, hash, parserresultaat en retentie. Quarantaine verhindert cleanup tot inspectie.

Employer

Genormaliseerde werkgever/recruiteridentiteit. Uniek op normalized name + domain. is_direct_employer en is_recruiter zijn confidencegedreven kenmerken, geen juridisch oordeel.

JobPosting

Canonieke vacature met UUID, canonical key, content hash, status en genormaliseerde velden. De canonical key wordt uit external ID/URL of fallbackidentiteit afgeleid. De exacte key is uniek; fuzzy matching is alleen een kandidaatbeslissing.

Statusflow:

new -> active -> uncertain -> removed
                \-> expired
active/uncertain -> duplicate/quarantined (beheerflow)

JobSourceAlias

Verbindt alle bronvermeldingen met één canonieke vacature. Bewaart externe ID, bronURL, parser, confidence en beperkte payload. De alias is het anker voor veldprovenance.

FieldProvenance

Per veld: extractiemethode, confidence, evidenceexcerpt en parserversie. Evidence is begrensd en mag geen geheime mailinhoud bevatten.

JobVersion

Snapshot per unieke contenthash. Bij inhoudswijziging wordt de vorige toestand bewaard; de huidige toestand krijgt eveneens een versie.

ScoreRun

Append-only score voor één job + profielversie. Bevat componentbijdragen, confidence, recommendation, redenen en evidence. Meerdere runs maken algoritme- en profielvergelijking mogelijk.

Feedback

Append-only useractie. Geen laatste-statekolom; views kunnen de laatste actie afleiden. Hierdoor blijft correctiehistorie behouden.

Application

Eén dossier per user/job. snapshot bewaart wat de gebruiker zag toen hij solliciteerde. document_manifest bevat alleen metadata/paden, geen willekeurige externe URL-executie.

DigestOutbox

Idempotente meldingseenheid met unieke dedupe key. Statusovergangen: pending → sent/failed; skipped bij ontbrekende recipient/configuratie.

Indexstrategie

Bestaand:

  • job title + region;
  • job status + valid_through;
  • alias source + external ID;
  • alias canonical URL;
  • source + raw contenthash;
  • profile + score descending + created_at;
  • bron next_run_at en healthdatums.

Toekomstig bij meetbare noodzaak:

  • trigram/index voor fuzzy title/employer (PostgreSQL);
  • partial index op actieve vacatures;
  • latest score materialisatie;
  • JSON GIN uitsluitend voor werkelijk bevraagde keys.

Migratiebeleid

  • schemawijzigingen via Django migrations;
  • destructieve wijzigingen in twee fasen;
  • grote backfills chunked en restartable;
  • productieback-up vóór migratie;
  • migratiecheck in CI;
  • rollback of forward-fix expliciet in taskplan.