Files
VacatureRadar/docs/ai/BACKLOG.yaml
T
Jens 67be350283
deploy / deploy (push) Canceled after 0s
Harden live mail OAuth and immutable releases
2026-07-30 02:00:09 +02:00

2374 lines
105 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
schema_version: 1
project: VacatureRadar
updated_at: '2026-07-29'
execution_policy:
order: file-order, then first ready task whose dependencies are done
no_product_questions: true
external_block_rule: finish interface, fixtures, tests, error handling and docs; block only the credential/review
step; continue
completion_gate: ./scripts/codex_verify.sh
status_values:
- done
- ready
- blocked-external
- deferred
tasks:
- id: VR-000
title: Repository, keuzes en autonome overdracht
status: done
priority: P0
requirement_ids:
- NFR-005
- NFR-006
- AC-001
- AC-051
- AC-054
depends_on: []
summary: Maak één self-contained repository met vaste productbeslissingen, documentnavigatie, Codex-instructies
en machineleesbare taakledger.
acceptance_criteria:
- README, CODEX_START_HERE en AGENTS bevatten één consistente startflow.
- Product-, architectuur-, UX-, security-, operations- en qualitydocumenten zijn aanwezig.
- Backlogvalidator detecteert ontbrekende velden, dubbele IDs, onbekende dependencies en cycli.
- Repo-eigen Codex-skill beschrijft dezelfde Definition of Done als AGENTS.md.
verification:
- python scripts/backlog.py validate
- ./scripts/codex_verify.sh
primary_paths:
- AGENTS.md
- CODEX_START_HERE.md
- docs/
- .agents/skills/
- scripts/backlog.py
result:
completed_at: '2026-07-20'
note: Volledige overdrachtsstructuur en documentatieset aangelegd.
- id: VR-001
title: Domeinmodellen en migraties
status: done
priority: P0
requirement_ids:
- PR-001
- PR-003
- PR-010
- PR-024
- PR-025
- PR-027
- PR-043
- PR-053
- PR-054
depends_on:
- VR-000
summary: Implementeer user-scoped profielen, bronnen/runs/raw documents, canonieke vacatures/aliassen/provenance/versies,
scores, feedback, sollicitaties en digest-outbox.
acceptance_criteria:
- Alle domeinobjecten hebben expliciete constraints, statussen en timestamps.
- Persoonsgebonden objecten zijn aan Django User gekoppeld.
- Migraties bouwen een lege database zonder handmatige stap.
verification:
- uv run python manage.py migrate --noinput
- uv run python manage.py makemigrations --check --dry-run
primary_paths:
- apps/*/models.py
- apps/*/migrations/
result:
completed_at: '2026-07-20'
note: Initiële modellen en migraties geïmplementeerd.
- id: VR-002
title: Strikt bronbeleid en veilige fetcher
status: done
priority: P0
requirement_ids:
- PR-011
- PR-012
- PR-013
- PR-014
- NFR-001
- AC-011
- AC-012
- AC-013
depends_on:
- VR-001
summary: Bouw fail-closed source policy, centrale platformdenylist, URL/host/IP-validatie, redirecthercontrole,
conditional requests en responsegrenzen.
acceptance_criteria:
- Private, loopback, link-local, credentialed en niet-toegestane URLs worden vóór request geblokkeerd.
- Iedere redirect wordt opnieuw gevalideerd.
- Denylistplatformen worden ook via redirect geweigerd.
- Fetcher heeft time-, byte-, type- en redirectlimieten en logt geen payload.
verification:
- uv run pytest tests/security/test_url_security.py tests/security/test_policy.py tests/unit/test_fetcher.py
primary_paths:
- apps/sources/services/policy.py
- apps/sources/services/url_security.py
- apps/sources/services/fetcher.py
result:
completed_at: '2026-07-20'
note: Veilige fetchboundary en negatieve tests geïmplementeerd.
- id: VR-003
title: Deterministische bronadapters
status: done
priority: P0
requirement_ids:
- PR-020
- PR-021
- PR-022
- PR-023
- AC-015
depends_on:
- VR-002
summary: Implementeer een gemeenschappelijk extractiecontract en adapters voor JSON-LD JobPosting, generieke HTML,
RSS/Atom en vacaturemail.
acceptance_criteria:
- Adapters schrijven niet naar de database en doen geen netwerkrequests.
- Iedere adapter levert parser key/version, confidence, warnings en veldbewijs.
- HTML wordt gesanitized en unsubscribe-/trackinglinks worden niet als vacature beschouwd.
- Gesaneerde offline fixtures dekken normale en malformed input.
verification:
- uv run pytest tests/unit/test_jsonld_adapter.py tests/unit/test_generic_html_adapter.py tests/unit/test_discovery_rss.py
tests/unit/test_email_adapter.py tests/security/test_sanitize.py
primary_paths:
- apps/sources/adapters/
- fixtures/
- apps/jobs/services/sanitize.py
result:
completed_at: '2026-07-20'
note: Vier adaptertypen, registry en fixtures geïmplementeerd.
- id: VR-004
title: Normalisatie, deduplicatie en provenancepipeline
status: done
priority: P0
requirement_ids:
- PR-024
- PR-025
- PR-027
- PR-030
- PR-031
- PR-032
- PR-033
- AC-010
- AC-020
- AC-021
depends_on:
- VR-001
- VR-003
summary: Bouw CanonicalJobDraft, URL/titel/contract/datum-normalisatie, exact-voor-fuzzy dedupe, werkgeverresolutie,
alias/provenance/versioning en transactionele persistence.
acceptance_criteria:
- Replay van hetzelfde document creëert geen tweede canonieke vacature.
- Een gewijzigde vacature bewaart een historisch snapshot.
- Rechtstreekse werkgever krijgt canonieke voorkeur zonder platformalias te verliezen.
- Field provenance en parserversie blijven auditbaar.
verification:
- uv run pytest tests/unit/test_normalization.py tests/unit/test_canonicalize.py tests/integration/test_pipeline.py
tests/integration/test_dedupe_lifecycle_feedback.py
primary_paths:
- apps/jobs/services/normalization.py
- apps/jobs/services/dedupe.py
- apps/jobs/services/pipeline.py
result:
completed_at: '2026-07-20'
note: Idempotente canonieke pipeline met aliassen en historiek geïmplementeerd.
- id: VR-005
title: Zoekprofielen en uitlegbare deterministische scoring
status: done
priority: P0
requirement_ids:
- PR-001
- PR-002
- PR-004
- PR-040
- PR-041
- PR-042
- PR-043
- PR-044
- AC-022
- AC-023
- AC-024
depends_on:
- VR-004
summary: Implementeer profieldefaults/revisies, harde uitsluitingen, features, gewogen score, recommendation en
positieve/negatieve evidence.
acceptance_criteria:
- Harde uitsluitingen lopen vóór zachte scoring en hebben stabiele codes.
- Onbekende afstand of voorwaarde wordt niet verzonnen.
- ScoreRun bewaart profiel/modelversie, componenten, concerns en evidence.
- Feedbackgewichten blijven binnen vaste grenzen.
verification:
- uv run pytest tests/unit/test_profiles.py tests/unit/test_features_distance.py tests/unit/test_scoring.py
primary_paths:
- apps/profiles/
- apps/jobs/services/features.py
- apps/jobs/services/scoring.py
- apps/jobs/services/feedback.py
result:
completed_at: '2026-07-20'
note: Deterministische score- en profielbasis geïmplementeerd.
- id: VR-006
title: Nederlandstalige kerninterface en gebruikersacties
status: done
priority: P0
requirement_ids:
- PR-050
- PR-051
- PR-052
- PR-053
- PR-056
- NFR-008
- AC-003
- AC-040
- AC-041
- AC-042
- AC-043
depends_on:
- VR-005
summary: Lever dashboard, vacaturelijst/detail, profiel-, bron- en sollicitatiepagina's plus CSRF-beschermde feedbackacties.
acceptance_criteria:
- Kernflows vereisen login en user-scopen mutaties.
- Interessant, bewaren, verbergen en gesolliciteerd zijn één duidelijke actie.
- Applied creëert/bijwerkt één dossier maar verzendt nooit extern.
- UI is responsive, semantisch en zonder externe assets bruikbaar.
verification:
- uv run pytest tests/integration/test_views.py tests/integration/test_tasks_and_more_views.py tests/integration/test_dedupe_lifecycle_feedback.py
primary_paths:
- apps/*/views.py
- templates/
- static/
result:
completed_at: '2026-07-20'
note: Server-rendered MVP-interface en feedback/applications geïmplementeerd.
- id: VR-007
title: Digest-outbox en vacaturelevenscyclus
status: done
priority: P0
requirement_ids:
- PR-054
- PR-055
- NFR-003
- AC-030
- AC-031
- AC-032
- AC-033
- AC-034
depends_on:
- VR-005
- VR-006
summary: Implementeer dagelijkse selectie, idempotente outbox/verzending en overgang active → uncertain/expired/removed.
acceptance_criteria:
- Maximaal één digest per profiel en lokale kalenderdag.
- Verborgen of hard uitgesloten vacatures verschijnen niet.
- Verzonden records worden niet dubbel verstuurd.
- Lifecycle gebruikt valid_through en last_seen met reproduceerbare drempels.
verification:
- uv run pytest tests/integration/test_email_import_notifications.py tests/integration/test_dedupe_lifecycle_feedback.py
primary_paths:
- apps/notifications/
- apps/jobs/services/lifecycle.py
- templates/emails/
result:
completed_at: '2026-07-20'
note: Outbox, digesttemplates en lifecycle geïmplementeerd.
- id: VR-008
title: Docker, Unraid, beheer en kwaliteitsbaseline
status: done
priority: P0
requirement_ids:
- PR-060
- PR-061
- PR-062
- PR-063
- PR-064
- NFR-006
- NFR-009
- NFR-010
- AC-050
- AC-051
- AC-052
- AC-053
- AC-055
depends_on:
- VR-001
- VR-007
summary: Lever settings, healthchecks, Celeryschema, Docker/Compose/Unraidbestanden, bootstrap/back-up/restore
en offline CI-testbasis.
acceptance_criteria:
- Lokale bootstrap maakt een bruikbare demo en draait de volledige gate.
- De kern werkt met AI en IMAP uit.
- Liveness en readiness hebben het gedocumenteerde contract.
- Back-up/restore en Unraidstappen zijn gedocumenteerd zonder secrets.
verification:
- ./scripts/codex_verify.sh
- python -c "import yaml; yaml.safe_load(open('docker-compose.yml')); yaml.safe_load(open('docker-compose.unraid.yml'))"
primary_paths:
- config/
- Dockerfile
- docker-compose*.yml
- scripts/
- docs/operations/
result:
completed_at: '2026-07-20'
note: Self-hosted deployment- en kwaliteitsbasis aangelegd; live Dockerbuild vereist een host met Docker.
- id: VR-009
title: Optionele lokale AI-boundary
status: done
priority: P1
requirement_ids:
- PR-045
- PR-046
- PR-063
- AC-025
depends_on:
- VR-005
summary: Lever een uitgeschakelde-by-default Ollama-client met vast JSON-schema, timeout, beperkte prompt, confidence
en foutfallback.
acceptance_criteria:
- Zonder model of bij fout blijft de deterministische pipeline volledig werken.
- Vacaturetekst wordt als onbetrouwbare data begrensd en modeloutput gevalideerd.
- AI-service heeft geen tools, databasewrite of netwerktoegang buiten de geconfigureerde Ollamahost.
verification:
- uv run pytest tests/unit/test_ai.py
primary_paths:
- apps/jobs/services/ai.py
- config/settings.py
result:
completed_at: '2026-07-20'
note: Ollama-serviceboundary en fallbacktests geïmplementeerd; nog niet in rankingpipeline geïntegreerd.
- id: VR-101
title: Automatische bronontdekking en kandidaatregister
status: done
priority: P0
requirement_ids:
- PR-017
- PR-020
- PR-021
- NFR-003
depends_on:
- VR-008
summary: 'Bouw veilige ontdekking uit bestaande toegestane documenten: same-domain carrièrelinks, sitemaplocaties,
JSON-LD job-URLs, feedlinks en werkgeversdomeinen uit e-mail. Ontdekking maakt uitsluitend candidate/review-records
en fetcht ze niet automatisch.'
acceptance_criteria:
- Discovery heeft pure functies plus persistente kandidaatservice met uniqueness en provenance.
- Alle URL's worden gecanonicaliseerd; off-domain, denylist en private doelen worden verworpen.
- Een confidence/reason bepaalt prioriteit maar nooit policy=allow.
- Management command en bron-UI tonen candidates, bewijs en bulk-safe dismiss/approve-to-trial acties.
- Fixtures dekken HTML, sitemapindex/urlset, feed en e-mail discovery plus replay.
verification:
- uv run pytest tests/unit tests/integration -k 'discover or candidate or sitemap'
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/services/discovery.py
- apps/sources/models.py
- apps/sources/views.py
- templates/sources/
- tests/
result:
completed_at: '2026-07-21'
note: 'Implemented discovery from HTML/JSON-LD/feed/sitemap/email into candidate-only source records, added
provenance persistence with idempotency, added discover_sources command, candidate bulk UI actions, fixtures,
and integration/unit tests. Verification: python -m pytest subset blocked by missing django in this runtime;
./scripts/codex_verify.sh passed.'
- id: VR-102
title: Bronpolicyreview, robotscache en vervaldatum
status: done
priority: P0
requirement_ids:
- PR-011
- PR-017
- PR-018
- NFR-001
- NFR-010
depends_on:
- VR-101
summary: Maak policybeslissingen expliciet en auditbaar. Robots mag geautomatiseerd worden gelezen; voorwaardenreview
blijft een beheerattest met datum, bewijslink/notitie en expiry. Een verlopen of conflicterende review schakelt
automatische fetch fail-closed uit.
acceptance_criteria:
- SourcePolicyReview/versiehistoriek registreert actor, beslissing, scope, reden en expiry.
- Robotsregels worden per origin gecachet met timeout/size/SSRF-beveiliging en user-agentmatching.
- Terms review wordt nooit door AI of heuristiek als juridisch toegestaan verklaard.
- UI toont ontbrekende/verlopen review en maakt veilige allow/trial/pause/deny-overgangen.
- Fetcher/task weigert policy-conflict of verlopen allow en tests bewijzen fail-closed gedrag.
verification:
- uv run pytest tests/security tests/integration -k 'policy or robots or review'
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/models.py
- apps/sources/services/policy.py
- apps/sources/services/robots.py
- apps/sources/views.py
- docs/operations/SOURCE_ONBOARDING.md
result:
completed_at: '2026-07-21'
note: 'VR-102 afgerond: bronpolicyreview-historie met actor/beslissing/scope/reden/expiry toegevoegd; robotscache
per origin met TTL/size/SSRF en user-agent matching; fetcher/task faalveilig op review-conflict/verval; bronlijst
toont reviewstatus en bulkacties allow/trial/pause/deny.'
- id: VR-103
title: Databaseleases, per-domein rate limiting en adaptieve planning
status: done
priority: P0
requirement_ids:
- PR-015
- PR-018
- NFR-003
- NFR-007
- NFR-010
depends_on:
- VR-102
summary: Voorkom dubbele/concurrerende fetches over workers met databaseleases en per-origin minimumintervallen.
Gebruik PostgreSQL als waarheid; Redis mag alleen als optimalisatie dienen.
acceptance_criteria:
- Een SourceLease of equivalente atomische claim heeft token, expiry en crash recovery.
- Max concurrency en minimum interval gelden installatiebreed per origin.
- 429/Retry-After, timeouts en opeenvolgende fouten vergroten gecontroleerd de backoff.
- Succes reset alleen toepasselijke foutstate en plant volgende run met begrensde jitter.
- Tests simuleren twee workers, verlopen lease, 304, 429 en retry zonder dubbel request.
verification:
- uv run pytest tests/integration tests/unit -k 'lease or rate or schedule or retry'
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/models.py
- apps/sources/tasks.py
- apps/sources/services/scheduling.py
- tests/
result:
completed_at: '2026-07-21'
note: Implemented DB-lease claims per-origin interval/backoff, concurrency guard, Retry-After/timeouts, regression
tests, and docs traceability updates.
- id: VR-104
title: Geocodingcontract, cache en importeerbare Belgische postcodegegevens
status: done
priority: P1
requirement_ids:
- PR-002
- PR-024
- PR-041
- PR-042
depends_on:
- VR-005
summary: 'Implementeer provider-onafhankelijke geocoding zonder verplichte externe API: Location/GeoPoint-cache,
conservatieve locatieparser en CLI-import voor een door de beheerder aangeleverde gelicenseerde Belgische postcode/municipality-CSV.
Commit alleen fictieve/minimale testdata.'
acceptance_criteria:
- Providerprotocol en offline CSV-provider hebben versie, confidence en bronmetadata.
- Parser ondersteunt Belgische postcode/gemeente en laat ambiguïteit onbekend.
- Cache voorkomt herhaalde lookups en kan opnieuw worden opgebouwd.
- Importcommand valideert kolommen, ranges, duplicates en licentiemetadata zonder gedeeltelijke writes.
- Zonder dataset blijft scoring werken met unknown distance; UI meldt dat duidelijk.
verification:
- uv run pytest tests/unit tests/integration -k 'geocode or location or postcode'
- ./scripts/codex_verify.sh
primary_paths:
- apps/jobs/services/geocoding.py
- apps/jobs/models.py
- apps/jobs/management/commands/
- config-data/geodata/
- docs/operations/
result:
completed_at: '2026-07-21'
note: Implemented offline CSV geocode provider/import contract with validation, ambiguity semantics (unknown
on ambiguous), atomic import with metadata checks, and command+docs. Added unit/integration tests.
- id: VR-105
title: Afstands- en reistijdschatting in ranking
status: done
priority: P1
requirement_ids:
- PR-002
- PR-040
- PR-041
- PR-042
- AC-022
- AC-024
- NFR-004
depends_on:
- VR-104
summary: Gebruik profielorigin en gecachte jobcoördinaten voor haversineafstand en een expliciet gelabelde, conservatieve
reistijdschatting. Voeg een optioneel providercontract toe voor later OSRM/routergebruik; geen externe route-API
is vereist.
acceptance_criteria:
- Exacte afstand is alleen beschikbaar wanneer beide punten voldoende confidence hebben.
- Geschatte reistijd is herkenbaar als schatting en beïnvloedt geen harde filter tenzij profiel dat expliciet
kiest.
- Onbekend blijft unknown en veroorzaakt geen automatische uitsluiting.
- Rescore wordt gericht getriggerd wanneer locatiecache verandert.
- Tests dekken grensafstand, remote/hybrid, ontbrekende data en tijdzone-onafhankelijkheid.
verification:
- uv run pytest tests/unit tests/integration -k 'distance or commute or geocode or score'
- ./scripts/codex_verify.sh
primary_paths:
- apps/jobs/services/distance.py
- apps/jobs/services/scoring.py
- apps/profiles/models.py
- templates/jobs/
result:
completed_at: '2026-07-21'
note: Implemented distance exactness via cache confidence, conservative commute estimate, explicit commute labels,
no automatic exclusion for unknown distance, cache-triggered rescore, and scoring/coverage updates.
- id: VR-106
title: Gespecialiseerde publieke ATS-adapters
status: done
priority: P1
requirement_ids:
- PR-020
- PR-021
- PR-022
- PR-024
- NFR-005
depends_on:
- VR-003
summary: Voeg adapters toe voor publieke vacatureformaten van Greenhouse, Lever, Recruitee, SmartRecruiters en
Workable, in die volgorde. Gebruik alleen openbare, bedoelde jobpagina's/feeds of officieel gedocumenteerde
publieke endpoints; geen login of reverse-engineered private API.
acceptance_criteria:
- Elke provideradapter detecteert alleen eigen host/markup en valt veilig terug.
- Paginatie/listing en detail worden gescheiden; listings ontdekken kandidaten, details leveren vacaturedata.
- Providerfixtures bevatten meerdere jobs, gesloten job, ontbrekende velden en gewijzigde markup.
- External ID, canonical URL, location, dates en employment type krijgen veldbewijs/confidence.
- Source onboardingdocument noemt providerbeperkingen en rate limits zonder ongeverifieerde juridische claim.
verification:
- uv run pytest tests/unit tests/integration -k 'greenhouse or lever or recruitee or smartrecruiters or workable
or ats'
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/adapters/
- fixtures/ats/
- docs/architecture/SOURCE_ADAPTERS.md
- tests/
result:
completed_at: '2026-07-21'
note: Added specialist ATS adapters voor Greenhouse, Lever, Recruitee, SmartRecruiters en Workable met host-gedreven
listing/detail scheiding, evidencevelddekking en fixture/tests voor gesloten job, multi-job en markup-variatie.
- id: VR-107
title: Handmatige URL-import en bookmarklet
status: done
priority: P1
requirement_ids:
- PR-017
- PR-021
- PR-052
- NFR-001
- NFR-008
depends_on:
- VR-102
summary: Lever een authenticated form en minimale bookmarklet die alleen een URL naar VacatureRadar opent/invult.
De server importeert pas na expliciete gebruikersactie en volledige policy/SSRF-check; gebruikers kunnen ook
gesaneerde tekst plakken wanneer fetch niet is toegestaan.
acceptance_criteria:
- GET-prefill verandert geen state; import is POST+CSRF en user-auditbaar.
- URL-import respecteert dezelfde denylist/policy/redirectlimieten als scheduler.
- Paste-import heeft bytegrens, sanitization en source_type=manual zonder externe fetch.
- Resultaat toont gecreëerd/duplicate/warnings en biedt direct vacaturedetail.
- Bookmarklet bevat geen secret, sessietoken of broninhoud en is in UX-doc gedocumenteerd.
verification:
- uv run pytest tests/integration tests/security -k 'manual or bookmark or import'
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/views.py
- apps/sources/forms.py
- apps/sources/services/manual_import.py
- templates/sources/
- static/js/
result:
completed_at: '2026-07-21'
note: Handmatige URL/paste import toegevoegd (CSRF-post + GET-prefill, policy/SSRF-check op URL-flow, paste
zonder extern fetch), bookmarklet en importresultaat in bronlijst; tests en documentation bijgewerkt.
- id: VR-108
title: Resolutie naar oorspronkelijke werkgever
status: done
priority: P1
requirement_ids:
- PR-032
- PR-051
- NFR-004
depends_on:
- VR-101
- VR-106
summary: Bouw een deterministische resolver die recruiter/platform/e-mailaliassen koppelt aan bestaande of nieuw
ontdekte rechtstreekse werkgeversbronnen via external ID, titel/locatie, employer domain en publieke canonical
metadata. Geen algemene websearch is verplicht.
acceptance_criteria:
- Resolver maakt evidence-rich kandidaatlinks en auto-merge alleen boven conservatieve drempel.
- Directe bron vervangt canonical URL maar alle aliassen/provenance blijven zichtbaar.
- Conflicterende werkgever of locatie resulteert in review, niet merge.
- UI toont waarom een bron als rechtstreeks/recruiter/onbekend is geclassificeerd en laat herstel toe.
- Benchmarkfixtures meten false merge en missed direct source.
verification:
- uv run pytest tests/unit tests/integration -k 'employer or resolver or alias or canonical'
- ./scripts/codex_verify.sh
primary_paths:
- apps/jobs/services/employer_resolution.py
- apps/jobs/services/dedupe.py
- apps/jobs/models.py
- templates/jobs/
result:
completed_at: '2026-07-21'
note: Implemented deterministic direct-employer resolver (apps/jobs/services/employer_resolution.py) with evidence-rich
decisions, conflict review path, and conservative threshold; wired resolver into dedupe/pipeline so ATS/recruiter
source merges resolve to direct employer canonical URL while preserving aliases/provenance; added unit tests
for merge/review/no-resolve and integration pipeline coverage for ATS-to-direct canonical canonicalization.
Added employer_resolution details in alias payload for UI-consumable auditability.
- id: VR-109
title: AI-analyse integreren met schema, cache en evaluaties
status: done
priority: P1
requirement_ids:
- PR-042
- PR-043
- PR-044
- PR-045
- PR-046
- NFR-004
depends_on:
- VR-009
- VR-005
summary: Integreer optionele Ollama-analyse na deterministische features. Bewaar model/prompt/schema/hash, valideer
evidence tegen tekst en laat AI alleen zachte kenmerken/confidence/samenvatting toevoegen. Bij iedere fout volgt
deterministische output.
acceptance_criteria:
- AI-run is gecachet op contenthash+model+promptversie en heeft status/foutcategorie zonder volledige promptlog.
- JSON-schema weigert extra velden, out-of-range waarden en evidence die niet uit brontekst komt.
- AI kan hard_exclusions, source policy, URL fetch, feedback of application niet muteren.
- Een golden evaluation-set vergelijkt disabled, valid, malformed, timeout en prompt-injectionoutput.
- Rankingimpact is opt-in per profiel, begrensd en uitlegbaar in ScoreRun/UI.
verification:
- uv run pytest tests/unit tests/integration tests/security -k 'ai or ollama or prompt or evidence'
- ./scripts/codex_verify.sh
primary_paths:
- apps/jobs/models.py
- apps/jobs/services/ai.py
- apps/jobs/services/scoring.py
- fixtures/ai/
- docs/architecture/SCORING_ENGINE.md
result:
completed_at: '2026-07-21'
note: AI-analyse met schema, cache, foutcategorieën en opt-in weging voltooid; AI-waarden gevalideerd op tekst,
deterministische fallback en score-evidence opgeslagen. Geen UI-explainability aanpassingen hier, die kan
extern in Stitch worden opgepakt.
- id: VR-110
title: Gecontroleerd leren uit feedback
status: done
priority: P1
requirement_ids:
- PR-004
- PR-040
- PR-042
- NFR-004
depends_on:
- VR-005
summary: Maak feedbackleren expliciet, begrensd en resetbaar. Gebruik alleen zachte featuregewichten, minimale
sampledrempels en versieer iedere aanpassing; harde regels en bronpolicy blijven immutable.
acceptance_criteria:
- Learning staat standaard uit totdat de gebruiker het in het profiel activeert.
- Gewichten blijven binnen per-feature min/max en hebben een terugkeer-naar-default actie.
- Verborgen feedback met reden wordt onderscheiden van niet-relevante titel/afstand/werkvorm.
- Een offline evaluator toont scoreverschuiving, top-N churn en mogelijke false negatives vóór activatie.
- UI maakt geleerd versus handmatig gewicht en laatste update duidelijk.
verification:
- uv run pytest tests/unit tests/integration -k 'feedback or learn or weight or revision'
- ./scripts/codex_verify.sh
primary_paths:
- apps/jobs/services/feedback.py
- apps/profiles/models.py
- apps/profiles/services.py
- templates/profiles/
- docs/architecture/SCORING_ENGINE.md
result:
completed_at: '2026-07-21'
note: 'Feedbackleren geïmplementeerd: leren blijft standaard uit, feedback-signalen met minimumsample-drempel,
hidden/niet-learn-categorisering via reason_code, feedbackmetadata logging en een offline evaluatierapport-script.
UI-explainability/resetflow voor learned-vs-manual achterwege gelaten per verzoek.'
- id: VR-111
title: Herinneringen en uitzonderingsmeldingen
status: done
priority: P1
requirement_ids:
- PR-053
- PR-054
- PR-055
- NFR-003
depends_on:
- VR-007
summary: Voeg idempotente reminder-outbox toe voor sluitingsdatum, opvolgdatum en uitzonderlijk sterke nieuwe
match. Respecteer quiet hours, lokale tijdzone en dagelijkse frequentie; geen externe sollicitatieactie.
acceptance_criteria:
- Reminderregels hebben stabiele event keys zodat retries niet dubbel sturen.
- Topmatchmelding vereist score/confidence/drempel en kan per profiel uit.
- Sluitingsreminders worden niet verzonden voor hidden/expired/applied wanneer niet relevant.
- Follow-up gebruikt applicationstatus en user-configured werkdagen, niet alleen kalenderdagen.
- Consolemail- en locmemtests dekken DST, retries, quiet hours en lege recipient.
verification:
- uv run pytest tests/unit tests/integration -k 'reminder or notification or digest or outbox'
- ./scripts/codex_verify.sh
primary_paths:
- apps/notifications/models.py
- apps/notifications/services.py
- apps/notifications/tasks.py
- apps/profiles/models.py
- templates/emails/
result:
completed_at: '2026-07-21'
note: Implemented reminder outbox (closing/follow-up/top-match), idempotent scheduler integration, reminders
templates, and integration coverage for quiet hours/weekdays/DST/skips.
- id: VR-112
title: Bronhealth, quarantaine en observability
status: done
priority: P1
requirement_ids:
- PR-018
- PR-026
- PR-060
- PR-061
- NFR-010
depends_on:
- VR-103
summary: 'Maak source health operationeel: rolling metrics, parserdrift, velddichtheid, nulresultaat-anomalie,
automatische quarantaine/herstel en statusdashboard. Logs blijven gestructureerd en payloadvrij.'
acceptance_criteria:
- Per bron zijn succesratio, latency, HTTP/foutcategorie, extract/duplicate counts en laatste goede parseroutput
zichtbaar.
- Drempels onderscheiden tijdelijke fout, policy/securityfout en parserdrift.
- Automatische quarantaine is fail-closed; herstel gaat altijd via trial en begrensde canaryrun.
- Raw cleanup draait periodiek en behoudt gequarantaineerd bewijs.
- Readiness blijft alleen kritieke dependencies meten; detailhealth staat authenticated op systempagina.
verification:
- uv run pytest tests/unit tests/integration tests/security -k 'health or quarantine or metrics or cleanup or
drift'
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/models.py
- apps/sources/services/health.py
- apps/sources/tasks.py
- apps/core/views.py
- templates/system/
result:
completed_at: '2026-07-21'
note: Implemented source health metrics, quarantining logic, parser drift detection and bounded canary recovery
path; scheduled periodic health enforcement and recovery tasks.
- id: VR-113
title: Uitgebreid sollicitatiedossier en veilige export
status: done
priority: P2
requirement_ids:
- PR-051
- PR-053
- PR-056
- NFR-002
- NFR-008
depends_on:
- VR-006
summary: Breid applications uit met tijdlijn, contactmetadata, notities, vacature-HTMLsnapshot en export naar
ZIP met JSON/CSV/printbare HTML. Voeg geen automatische formulierverzending toe. Bestandsuploads blijven buiten
scope tenzij een aparte threat review en contentvalidatie worden toegevoegd.
acceptance_criteria:
- Applied bevriest een gesaniteerde vacature- en scoresnapshot met bronlinks en tijdstip.
- Statuswijzigingen en notities vormen een user-scoped audit timeline.
- Export bevat alleen het gekozen dossier, veilige filenames en geen secrets/raw mailboxbody.
- Printbare HTML werkt zonder externe assets en is bruikbaar als PDF via browserprint.
- Data-export en dossierverwijdering zijn idempotent en getest op cross-user access.
verification:
- uv run pytest tests/integration tests/security -k 'application or export or timeline or snapshot'
- ./scripts/codex_verify.sh
primary_paths:
- apps/jobs/models.py
- apps/jobs/services/applications.py
- apps/jobs/views.py
- templates/applications/
- docs/operations/
result:
completed_at: '2026-07-21'
note: Implemented application timeline/audit events, contact metadata persistence, snapshot freeze in applied
flow, ZIP+CSV+print export and idempotent user-scoped delete; added integration tests for snapshot, timeline,
export/print and cross-user scope.
- id: VR-114
title: Browser-e2e, accessibility en visuele regressiebasis
status: done
priority: P1
requirement_ids:
- NFR-006
- NFR-008
- AC-002
- AC-003
- AC-051
depends_on:
- VR-107
- VR-111
- VR-113
summary: Voeg een lokale Playwright-suite toe voor de volledige gebruikersflow en een dependency-arme accessibilitycontrole.
Tests gebruiken seeded data, locmem mail en geen internet.
acceptance_criteria:
- E2E dekt login, dashboard, filter/detail, profielupdate, vier feedbackacties, application en manual import.
- Tests lopen op desktop en 360px viewport en gebruiken stabiele role/label-selectors.
- Keyboardtabvolgorde, zichtbare focus, form labels, headings en reduced motion worden gecontroleerd.
- Screenshots bij falen worden als CI-artifact bewaard maar niet in Git gecommit.
- Een snelle HTML/unit-a11ycheck blijft beschikbaar wanneer browsers niet geïnstalleerd zijn; browserjob mag apart
zijn.
verification:
- uv sync --extra browser
- uv run playwright install chromium
- uv run pytest tests/e2e
- ./scripts/codex_verify.sh
primary_paths:
- tests/e2e/
- pyproject.toml
- .github/workflows/ci.yml
- docs/design/ACCESSIBILITY.md
result:
completed_at: '2026-07-21'
note: Added VR-114 e2e accessibility and browser-flow coverage; updated traceability and project state.
- id: VR-115
title: Security- en supply-chainhardening
status: done
priority: P0
requirement_ids:
- NFR-001
- NFR-002
- NFR-003
- NFR-009
- PR-013
- PR-023
- PR-046
- PR-064
depends_on:
- VR-102
- VR-109
summary: 'Hardening voor productie: non-root read-only container waar haalbaar, pinned image digests/releasebeleid,
secret scan, dependency audit, secure proxysettings, uploadverbod, DNS/transportreview en abuse-limieten op
authenticated mutaties.'
acceptance_criteria:
- Container draait als vaste niet-root UID/GID en schrijft alleen naar bedoelde volumes/tmp.
- CI scant repository op secrets en dependencies/images op bekende kwetsbaarheden met een gedocumenteerd severitybeleid.
- Security settings valideren DEBUG/hosts/origins/cookies/secret bij productie-start fail-fast.
- Rate limiting beschermt login en handmatige import zonder normale lokale bediening te breken.
- DNS rebinding-restgevaar is verminderd met transport-level connectcontrole of expliciet geteste mitigatie; threat
model vermeldt restscope.
- Geen gevoelige payload verschijnt in exceptions, admin list displays of exports.
verification:
- uv run pytest tests/security
- ./scripts/codex_verify.sh
- docker build -t vacatureradar:verify .
primary_paths:
- Dockerfile
- config/settings.py
- apps/core/
- apps/sources/services/fetcher.py
- .github/workflows/
- docs/quality/THREAT_MODEL.md
result:
completed_at: '2026-07-21'
note: Security hardening afgerond (production-safe instellingenvalidering, non-root/read-only containers, supply-chain
scans, DNS-rebindcontrole, login/manual import rate limiting, tests en docs).
- id: VR-116
title: Kwaliteits-, dedupe- en performancebenchmark
status: done
priority: P2
requirement_ids:
- NFR-004
- NFR-007
- PR-031
- PR-040
- PR-042
depends_on:
- VR-105
- VR-108
- VR-109
- VR-110
- VR-112
summary: Maak reproduceerbare offline benchmarksets en commands voor parservelddekking, dedupe precision/recall,
hard-filter false positives, ranking top-N en dashboard/pipelineperformance op 25.000 jobs.
acceptance_criteria:
- Datasets zijn synthetisch of geanonimiseerd en hebben expected labels/version.
- Rapport toont precision, recall, false merges, missed merges, top-N churn en onbekende-data-aandeel.
- Performancecommand rapporteert hardware/context, p50/p95, querycount en peak memory.
- NFR-007 wordt alleen als gehaald gemarkeerd bij gemeten p95 <1s op het gedocumenteerde referentieprofiel.
- Regressiedrempels zijn conservatief en blokkeren CI alleen wanneer baseline betrouwbaar stabiel is.
verification:
- uv run python scripts/benchmark.py --quick
- uv run pytest tests/benchmark
- ./scripts/codex_verify.sh
primary_paths:
- scripts/benchmark.py
- fixtures/benchmark/
- tests/benchmark/
- docs/quality/BENCHMARKS.md
result:
completed_at: '2026-07-21'
note: Added offline benchmark script, fixture coverage, benchmark tests, and benchmark docs. Updated traceability/projectstate.
Requires verification result pending.
- id: VR-117
title: Productierelease en Unraid acceptance
status: done
priority: P0
requirement_ids:
- PR-060
- PR-062
- PR-063
- PR-064
- NFR-003
- NFR-009
- NFR-010
- AC-001
- AC-051
- AC-055
depends_on:
- VR-106
- VR-107
- VR-111
- VR-112
- VR-114
- VR-115
- VR-116
summary: 'Maak release 1.0 kandidaat: production Compose, immutable image metadata, migratie-/rollbackcheck, clean-install
smoke, fixture-import, digest, back-up/restore en Unraid runbookvalidatie. Externe domein/mailbox/registrystappen
blijven aparte blocked tasks.'
acceptance_criteria:
- Een schone Dockerstack start, migreert en passeert healthchecks zonder handmatige databaseactie.
- Release-smoke importeert fixture tweemaal, maakt één job/aliascluster, score, feedback, application en digest.
- PostgreSQL-back-up wordt naar tijdelijke nieuwe stack hersteld en modelcounts/smoke blijven correct.
- Release artifact bevat SBOM/checksums, changelog, configdiff en exact upgrade/rollbackpad.
- README en PROJECT_STATE maken eerlijk onderscheid tussen productieklare code en resterende externe configuratie.
verification:
- ./scripts/release_verify.sh
- ./scripts/codex_verify.sh
- python scripts/backlog.py validate
primary_paths:
- scripts/release_verify.sh
- docker-compose.yml
- docker-compose.unraid.yml
- docs/operations/
- CHANGELOG.md
- docs/ai/PROJECT_STATE.md
result:
completed_at: '2026-07-21'
note: Release script, smoke-run, backup/restore and artifact bundle for VR-117 toegevoegd; release artefacten
en Unraid-runbook geactualiseerd; traceability en projectstate bijgewerkt.
- id: VR-118
title: Stitch Intelligence Cockpit production-grade integreren
status: done
priority: P1
requirement_ids:
- NFR-006
- NFR-008
- AC-002
- AC-003
- AC-051
depends_on:
- VR-107
- VR-114
summary: Vertaal de negen aangeleverde Stitch-schermen naar de bestaande server-rendered Django-interface zonder
domeinlogica, securitygrenzen of gebruikersscope te vervangen en zonder fictieve productdata te introduceren.
acceptance_criteria:
- Een consistente responsive cockpit-shell en dark/light tokens bedienen alle kernroutes.
- Dashboard, vacatures, detail, pipeline, profiel, bronnen, systeem en login gebruiken echte backenddata en acties.
- Externe auto-apply, nepmetrics, onbewezen werkgeverinzichten en onbetrouwbare activiteitenfeeds zijn niet overgenomen.
- Zes doelviewports hebben één h1, geen horizontale overflow en werkende mobiele navigatie.
- Stitch-bronnen, integratieplan, screenshots en verificatierapport zijn traceerbaar maar niet onderdeel van de
productiecontainer.
verification:
- uv run pytest tests/e2e tests/integration/test_views.py tests/integration/test_tasks_and_more_views.py
- ./scripts/codex_verify.sh
- Browsercontrole op 1440x900, 1280x800, 1024x768, 768x1024, 390x844 en 360x800
primary_paths:
- templates/
- static/css/app.css
- static/js/app.js
- docs/design/STITCH_INTEGRATION_PLAN.md
- docs/design/stitch-reference/
- docs/design/validation/
result:
completed_at: '2026-07-21'
note: Stitch-visuele taal geïntegreerd in CSP-veilige Django-templates; dark/light, responsive shell, pipeline,
broninteracties en browservalidatie toegevoegd zonder functionele scope-uitbreiding of fictieve data.
- id: VR-119
title: Stitch-schermcompositie dominant doorvoeren
status: done
priority: P0
requirement_ids:
- PR-050
- PR-051
- NFR-008
depends_on:
- VR-118
summary: Herwerk de cockpit na productfeedback zodat de aangeleverde Stitch-frontend niet alleen de visuele tokens
maar ook de schermcompositie, informatiedichtheid en interactiehiërarchie bepaalt, met behoud van echte Django-data,
toegankelijke server-rendered flows en alle bestaande veiligheidsgrenzen.
acceptance_criteria:
- De gedeelde shell, utilitybar en navigatie volgen aantoonbaar de Stitch-compositie op desktop en mobiel.
- Dashboard, vacatureoverzicht en detail nemen de primaire Stitch-layouts vrijwel volledig over met uitsluitend
aantoonbare databasevelden en bestaande veilige acties.
- Pipeline, profiel, bronnen, systeem en login gebruiken dezelfde dichte cockpit-hiërarchie en componentvormen.
- Lege, fout- en een-itemtoestanden behouden de bedoelde compositie zonder grote onverklaarde lege vlakken.
- Zes doelviewports hebben één h1, geen pagina-brede horizontale overflow en werkende toetsenbordnavigatie.
- Geen auto-apply, externe assets, fictieve metrics of onbewezen intelligence wordt toegevoegd.
verification:
- uv run pytest tests/e2e tests/integration/test_views.py tests/integration/test_tasks_and_more_views.py
- ./scripts/codex_verify.sh
- Browsercontrole op 1440x900, 1280x800, 1024x768, 768x1024, 390x844 en 360x800
primary_paths:
- apps/core/context_processors.py
- apps/core/views.py
- apps/jobs/views.py
- templates/
- static/css/app.css
- static/js/app.js
- docs/design/STITCH_INTEGRATION_PLAN.md
- docs/design/validation/
result:
completed_at: '2026-07-21'
note: Stitch-schermcompositie dominant doorgevoerd in shell, dashboard, vacaturefeed/detail, pipeline, profieleditor,
bronnen en systeem; geverifieerd met 146 tests, 82,02% coverage en browsermatrix op zes viewports, dark/light
en mobiele navigatie.
- id: VR-120
title: Begeleid zoekprofiel en functionele livebronnen opleveren
status: done
priority: P0
requirement_ids:
- PR-001
- PR-002
- PR-005
- PR-011
- PR-017
- PR-018
- PR-022
depends_on:
- VR-119
summary: Verwerk de functionele productfeedback door thuislocatie tot postcode te vereenvoudigen, technische JSON-invoer
door selectielijsten en checkboxes te vervangen en minimaal twee actuele publieke werkgeversfeeds end-to-end
te valideren.
acceptance_criteria:
- Het profiel vraagt alleen een viercijferige thuispostcode en leidt gemeente/coördinaten af wanneer lokale geodata
eenduidig beschikbaar is.
- Functietitels, skills, contractvormen, werkmodellen en regio's zijn begeleide keuzevelden die bestaande waarden
veilig behouden.
- Minimaal twee echte werkgeverfeeds hebben een actuele policyreview, parserfixtures en twee succesvolle livecycli.
- Demobronnen zijn niet zichtbaar in het normale bronoverzicht en actuele vacatures stromen door naar ranking.
- Profiel-, adapter-, pipeline-, view- en browsertests plus de volledige verificatiegate slagen.
verification:
- uv run pytest tests/integration/test_profile_preferences.py tests/integration/test_seed_sources.py tests/integration/test_pipeline.py
tests/unit/test_ats_adapters.py
- Volg docs/operations/SOURCE_ONBOARDING.md en controleer twee livecycli per geactiveerde bron
- ./scripts/codex_verify.sh
primary_paths:
- apps/profiles/
- templates/profiles/
- apps/sources/
- config-data/seed_sources.yaml
- docs/operations/SOURCE_ONBOARDING.md
result:
completed_at: '2026-07-21'
note: Postcode-only profiel, begeleide checkboxkeuzes, gereviewde VITO- en Deliverect-feeds met twee livecycli,
employeridentiteit, broninventaris en robotsredirecthardening; 155 tests geslaagd, 2 optioneel overgeslagen,
82,94% coverage en volledige codex_verify-gate groen.
- id: VR-121
title: Regionale werkgevers- en platformalertdekking uitbreiden
status: done
priority: P0
requirement_ids:
- PR-011
- PR-012
- PR-017
- PR-018
- PR-032
depends_on:
- VR-120
summary: Breid de livebroncatalogus uit met publieke werkgeversfeeds in Limburg en aangrenzende Belgische werkregio's,
maak gedeelde ATS-hosts first-class en documenteer de veilige alertingress voor VDAB en Indeed.
acceptance_criteria:
- Minimaal acht bijkomende publieke bronnen hebben een actuele policyreview, parserdekking en twee succesvolle
livecycli voordat ze actief worden.
- De catalogus bevat aantoonbaar regionale dekking voor Hasselt/Genk en aanvullende IT-werkgevers in Brussel,
Gent of Leuven.
- Meerdere werkgevers op één publieke ATS-host kunnen naast elkaar bestaan zonder bronrecords te overschrijven.
- Corda Campus-vacaturekaarten worden deterministisch uitgelezen en off-domain links worden verworpen.
- Indeed en VDAB worden uitsluitend via officiële vacaturealerts/mailimport of handmatige import gebruikt en blijven
op de directe-fetchdenylist.
verification:
- uv run pytest tests/unit/test_regional_adapters.py tests/unit/test_ats_adapters.py tests/unit/test_source_models.py
tests/integration/test_seed_sources.py
- Voer twee livecycli uit voor iedere nieuwe bron en controleer source health, parserwarnings en inventaristelling
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/
- config-data/seed_sources.yaml
- fixtures/pages/corda-campus-jobs.html
- fixtures/ats/smartrecruiters-public-postings.json
- docs/operations/LIVE_SOURCE_CATALOG.md
result:
completed_at: '2026-07-21'
note: Acht extra gereviewde livebronnen, gedeelde ATS-hostidentiteit, Corda-adapter en veilige VDAB/Indeed-alertingress
toegevoegd; twee livecycli per bron, 159 tests, 82,91% coverage en in-app-browsercontrole geslaagd.
- id: VR-122
title: Dagelijkse officiële VDAB-ingang operationaliseren
status: done
priority: P0
requirement_ids:
- PR-012
- PR-016
- PR-018
- PR-064
depends_on:
- VR-121
summary: Verwerk officiële VDAB-jobalerts eenmaal per dag via de bestaande dedicated mailbox, met herkenbare provenance,
begrensde verwerking en een duidelijke route naar de contractueel toegankelijke VDAB Vacature API.
acceptance_criteria:
- De IMAP-ingang draait standaard eenmaal per dag op een configureerbaar tijdstip en blijft idempotent bij replay.
- VDAB-alertmails worden als VDAB-provenance herkend en vacatures stromen zonder automatische linkfetch door de
bestaande normalisatie-, dedupe- en rankingpipeline.
- De mailboxpoll is begrensd op aantal en berichtgrootte; oversized of onleesbare berichten stoppen de batch niet.
- De bronpagina toont de dagelijkse planning, configuratiestatus, laatste VDAB-import en het onderscheid tussen
jobalertingang en de officiële API waarvoor VDAB-goedkeuring vereist is.
- Directe VDAB-scraping, platformlogin en niet-goedgekeurde API-toegang blijven geblokkeerd en dit is getest en
operationeel gedocumenteerd.
verification:
- uv run pytest tests/unit/test_email_adapter.py tests/integration/test_email_import_notifications.py tests/integration/test_tasks_and_more_views.py
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/adapters/email_alert.py
- apps/sources/services/email_import.py
- apps/sources/services/imap_import.py
- apps/sources/tasks.py
- config/settings.py
- templates/sources/list.html
- docs/architecture/adrs/0005-email-alerts-as-platform-ingress.md
result:
completed_at: '2026-07-21'
note: Dagelijkse configureerbare VDAB-jobalertimport met expliciete provenance, begrensde foutgeisoleerde IMAP-poll,
beveiligde handmatige inplanning en heldere officiele API-route; 164 tests, 2 optioneel overgeslagen, 83,55%
coverage en desktop/390px Codex-browsercontrole groen.
- id: VR-123
title: Platformmailboxen veilig in de UI koppelen en frequent synchroniseren
status: done
priority: P0
requirement_ids:
- PR-012
- PR-016
- PR-018
- PR-064
depends_on:
- VR-122
summary: Vervang de globale dagelijkse IMAP-configuratie door gebruikersgescopeerde mailboxkoppelingen per vacatureplatform,
met versleutelde app-wachtwoorden en een eigen frequent synchronisatie-interval.
acceptance_criteria:
- Een ingelogde gebruiker kan voor VDAB en Indeed afzonderlijk een Gmail-, Outlook- of aangepaste IMAP-mailbox
koppelen, wijzigen, pauzeren en direct laten synchroniseren.
- App-wachtwoorden worden met een afzonderlijke roteerbare sleutel versleuteld opgeslagen, nooit teruggetoond
en nooit in logs of taakresultaten opgenomen.
- Iedere mailbox heeft een interval van 5 tot 360 minuten; de scheduler plant alleen verschuldigde actieve mailboxen
en is concurrency- en replayveilig.
- Mailimport bewaart mailbox- en platformprovenance, is per mailbox idempotent en laat een fout in één mailbox
de andere mailboxen niet blokkeren.
- Alle mutaties zijn login-, user-scope- en CSRF-beveiligd; negatieve tests dekken cross-user toegang, ontbrekende
encryptiesleutel, ongeldige host/poort en secretlekken.
- Bronpagina, runbook, threat model, configuratie en migratiedocumentatie zijn bijgewerkt; directe platformfetch
en platformlogin blijven uitgesloten.
verification:
- uv run pytest tests/unit/test_mailbox_credentials.py tests/integration/test_mailbox_connections.py tests/integration/test_email_import_notifications.py
- uv run python manage.py makemigrations --check --dry-run
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/models.py
- apps/sources/forms.py
- apps/sources/services/mailbox_connections.py
- apps/sources/services/imap_import.py
- apps/sources/tasks.py
- apps/sources/views.py
- templates/sources/list.html
- config/settings.py
result:
completed_at: '2026-07-22'
note: 'Per-platform VDAB/Indeed-mailboxen met versleutelde app-wachtwoorden, intervallen van 5-360 minuten,
leases, user-scoped UI, securitytests en documentatie; volledige gate: 178 passed, 2 skipped, 83.56%.'
- id: VR-124
title: LinkedIn en Belgische jobboards via veilige jobalertmail toevoegen
status: done
priority: P0
requirement_ids:
- PR-012
- PR-016
- PR-021
- NFR-001
- NFR-003
depends_on:
- VR-123
summary: Breid de platformmailboxingang uit met LinkedIn, ictjob.be, Jobat, StepStone, EuroBrussels en BrusselsJobs
en beperk iedere parserrun tot vacaturelinks van het expliciet gekozen jobboard.
acceptance_criteria:
- De mailbox-UI biedt naast VDAB en Indeed ook LinkedIn, ictjob.be, Jobat, StepStone, EuroBrussels en BrusselsJobs
met een actuele officiele jobalertlink en dezelfde afzonderlijke mailbox-, interval-, pauze- en syncflow.
- Gesaneerde fixtures en adaptertests bewijzen per nieuw platform titel-, link- en provenance-extractie zonder
live netwerkcall.
- Een platformgebonden mail importeert alleen HTTPS-vacaturelinks op het verwachte jobboarddomein; externe, tracking-,
account-, privacy- en uitschrijflinks worden genegeerd.
- Mailboxrecords, bronprovenance, idempotentie, user scoping, encryptie, leases en foutisolatie blijven voor alle
platformkeuzes behouden.
- Bronbeleid, catalogus, threat model, onboarding, traceability en UI-copy vermelden dat directe platformlogin
en jobboardscraping uitgesloten blijven.
verification:
- uv run pytest tests/unit/test_email_adapter.py tests/integration/test_email_import_notifications.py tests/integration/test_mailbox_connections.py
- uv run python manage.py makemigrations --check --dry-run
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/models.py
- apps/sources/adapters/email_alert.py
- apps/sources/services/email_import.py
- templates/sources/list.html
- fixtures/emails/
- docs/operations/LIVE_SOURCE_CATALOG.md
result:
completed_at: '2026-07-22'
note: LinkedIn, ictjob.be, Jobat, StepStone, EuroBrussels en BrusselsJobs toegevoegd aan platformmailboxen;
domeingebonden HTTPS-parser, zes fixtures, denylist, UI en docs; 192 passed, 2 skipped, 83.61%, desktop/390px
browser groen.
- id: VR-125
title: Brusselse dekking vervangen door regionale werkgevers en Belgische jobplatformen
status: done
priority: P0
requirement_ids:
- PR-011
- PR-012
- PR-017
- PR-018
- PR-021
- NFR-001
- NFR-003
depends_on:
- VR-124
summary: Verwijder de expliciete Brusselse jobboards en werkgevers uit de actieve radar, voeg brede Belgische
jobalertplatformen toe en activeer veilige publieke vacaturelijsten van werkgevers rond Hasselt-Genk.
acceptance_criteria:
- EuroBrussels en BrusselsJobs zijn niet meer configureerbaar of actief; bestaande koppelingen worden veilig uitgeschakeld
en verborgen zonder historische provenance te verwijderen.
- Careerjet, Randstad en Robert Half zijn beschikbaar via hun officiele e-mailalerts en blijven op de directe-fetchdenylist.
- Werkgeversbronnen buiten de regionale scope worden gedeactiveerd en verborgen; bestaande vacaturehistoriek blijft
bewaard.
- Minstens vier lokale werkgeverspagina's uit de kern Hasselt-Genk worden met host- en padgebonden adapters, gesaneerde
fixtures, actuele bronreview en twee succesvolle livecycli toegevoegd.
- Tot een thuispostcode is ingevuld, vermeldt de catalogus expliciet dat Hasselt-Genk als omkeerbaar centrum voor
de 40-km-selectie is gebruikt; ranking blijft de exacte profielafstand toepassen zodra die bekend is.
- Bronbeleid, threat model, onboarding, traceability en gebruikerscopy blijven duidelijk over e-mailingress, robots,
SSRF, off-domain afwijzing en het verbod op platformlogin en scraping.
verification:
- .venv/Scripts/python.exe -m pytest tests/unit/test_regional_adapters.py tests/unit/test_email_adapter.py tests/integration/test_seed_sources.py
tests/integration/test_email_import_notifications.py
- .venv/Scripts/python.exe manage.py makemigrations --check --dry-run
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/adapters/regional.py
- apps/sources/platforms.py
- apps/sources/management/commands/seed_sources.py
- config-data/seed_sources.yaml
- fixtures/pages/
- fixtures/emails/
- docs/operations/LIVE_SOURCE_CATALOG.md
result:
completed_at: '2026-07-22'
note: Brusselse mailboxen en zeven buitenregionale bronnen veilig geretired; Careerjet, Randstad en Robert Half
toegevoegd; ACA, Xplore, UHasselt, PXL en ZOL na host/padreview en twee livecycli actief; 200 passed, 2 skipped,
83.90%, browser desktop/390px groen.
- id: VR-126
title: Werkgeversradar herankeren op postcode 2400 Mol
status: done
priority: P0
requirement_ids:
- PR-002
- PR-011
- PR-017
- PR-018
- PR-021
- NFR-001
- NFR-003
depends_on:
- VR-125
summary: Vervang de tijdelijke Hasselt-Genk-aanname door postcode 2400 Mol en voeg veilige publieke vacaturelijsten
toe van relevante werkgevers binnen ongeveer 40 km, met nadruk op infrastructuur-, systeem- en netwerkfuncties.
acceptance_criteria:
- De actieve profielruntime bewaart postcode 2400 en een maximale afstand van 40 km; ontbrekende gelicenseerde
coördinatendata blijft expliciet zichtbaar als extern restpunt en wordt niet stil ingevuld.
- De broncatalogus en UI noemen Mol als centrum en maken onderscheid tussen geografisch gereviewde bronnen en
exacte vacatureafstand die pas na geocoding kan worden berekend.
- Minstens vijf werkgevers uit Mol, Geel, Westerlo of Turnhout met regelmatig gepubliceerde eigen vacatures worden
host- en padgebonden toegevoegd, inclusief relevante IT-/infrastructuurwerkgevers.
- Iedere nieuwe bron heeft een gesaneerde fixture, positieve adaptertest, off-domain/route-negatie en minstens
twee geslaagde livecycli zonder parserwarnings voor activering.
- Bestaande regionale bronnen blijven alleen actief wanneer hun primaire vestiging of vacaturelocatie indicatief
binnen 40 km van Mol valt; historische vacatures en provenance worden bij retirement behouden.
- Bronbeleid, threat model, livecatalogus, onboarding, traceability en gebruikerscopy documenteren robots-, SSRF-,
sanitization- en locatiegrenzen; login, sollicitatie-endpoints en platformscraping blijven uitgesloten.
verification:
- .venv/Scripts/python.exe -m pytest tests/unit/test_regional_adapters.py tests/integration/test_seed_sources.py
tests/integration/test_profile_preferences.py tests/security/test_policy.py
- .venv/Scripts/python.exe manage.py makemigrations --check --dry-run
- ./scripts/codex_verify.sh
primary_paths:
- apps/sources/adapters/regional.py
- apps/sources/management/commands/seed_sources.py
- config-data/seed_sources.yaml
- fixtures/pages/
- templates/sources/list.html
- docs/operations/LIVE_SOURCE_CATALOG.md
result:
completed_at: '2026-07-22'
note: Profielruntime op postcode 2400 en 40 km gezet; SCK CEN, Cipal Schaubroeck, VanRoey, NTX en Thomas More
met fail-closed Mol-regioadapter, fixtures, docs en twee livecycli geactiveerd; 206 passed, 2 skipped, 84.12%,
browser desktop/360px groen.
- id: VR-201
title: Concrete live-bronnen inventariseren en juridisch/operationeel reviewen
status: done
priority: P0
requirement_ids:
- PR-011
- PR-017
- PR-018
depends_on:
- VR-102
- VR-106
summary: Vul voor Jens de gewenste werkgevers/overheden/instellingen in, controleer per domein publieke toegankelijkheid,
robots, voorwaarden, toegestane paden en frequentie en activeer alleen goedgekeurde bronnen.
acceptance_criteria:
- Iedere actieve bron heeft een actuele review, bewijsnotitie, parserfixture en succesvolle trialruns.
- Geen platformdenylistbron wordt als directe fetchbron geactiveerd.
- Een dekkingsteekproef en gemiste-bronnenlijst zijn gedocumenteerd.
verification:
- Volg docs/operations/SOURCE_ONBOARDING.md per bron
- Controleer source health na minstens twee geplande cycli
primary_paths:
- config-data/seed_sources.local.yaml
- Source admin
- docs/operations/SOURCE_ONBOARDING.md
result:
completed_at: '2026-07-22'
note: Gemeente Mol en zeven Kempen-werkgevers na actuele menselijke review, fail-closed fixtures/tests en twee
livecycli geactiveerd; twaalf interessante regionale werkgevers als niet-scanbare waaklijst toegevoegd; TLS
gebruikt strikt de gepinde certifi-bundel zonder bypass.
- id: VR-202
title: Live IMAP- en SMTP-credentials configureren
status: blocked-external
priority: P0
requirement_ids:
- PR-016
- PR-054
- NFR-002
- PR-064
depends_on:
- VR-111
- VR-115
- VR-123
- VR-124
summary: Configureer de gewenste afzonderlijke platformmailboxen via de beveiligde UI, de Fernet-secretkey en
digestrecipient; test read-only import en mailverzending zonder credentials in Git/logs.
acceptance_criteria:
- Iedere platformmailbox gebruikt TLS, een dedicated alias en read-only mailboxselectie; Microsoft 365 gebruikt
app-only OAuth/XOAUTH2 en geen Basic Auth of app-wachtwoord.
- Dezelfde live testmail importeert per mailbox idempotent en alle geconfigureerde intervallen worden door de
scheduler gerespecteerd.
- SMTP verstuurt één testdigest en outboxstatus klopt.
- OAuth-clientcredentials en de encryptiesleutel staan alleen in de productie-secretstore/.env; eventuele
Gmail/custom-app-wachtwoorden zijn als ciphertext opgeslagen en sleutelrotatie is live getest.
verification:
- Volg Unraid mailboxchecklist
- Inspecteer logs op afwezigheid van secret/payload
primary_paths:
- /mnt/user/appdata/vacatureradar/config/.env
- Bronnen -> Platformmailboxen
external_blocker: De dedicated productie-alias, Entra-appregistratie, admin consent en Exchange-mailboxscope zijn
op 2026-07-30 live ingericht; resterend zijn de productie-uitrol en echte platformalertmails voor de
import-/digestproef.
- id: VR-203
title: Productiedomein, TLS en reverse proxy activeren
status: done
priority: P0
requirement_ids:
- NFR-001
- NFR-009
- PR-064
depends_on:
- VR-115
- VR-117
summary: Koppel het gekozen interne/publieke domein aan een TLS-reverse proxy en vul exacte Django host/origin/securitysettings
in.
acceptance_criteria:
- Alle externe requests gaan via HTTPS en HTTP redirect correct.
- ALLOWED_HOSTS en CSRF origins zijn exact, secure cookies/redirect zijn aan.
- PostgreSQL, Redis, Ollama en adminpoorten zijn niet publiek.
- Login, logout, CSRF POST en health werken achter de proxy.
verification:
- Voer reverse-proxy smoke-test uit vanaf een externe browser
- Controleer headers en TLS-configuratie
primary_paths:
- Unraid reverse proxy
- /mnt/user/appdata/vacatureradar/config/.env
result:
completed_at: '2026-07-29'
note: Publiek domein, HTTP-naar-HTTPS, TLS/securityheaders, DEBUG=False, secure cookies, CSRF-gastlogin, kernroutes
en readiness live bewezen in docs/audit/FINAL_ACCEPTANCE.md op 2026-07-29; interne diensten zijn uitsluitend
containerintern bereikbaar.
- id: VR-204
title: Immutable containerimage publiceren
status: blocked-external
priority: P1
requirement_ids:
- NFR-009
- PR-064
depends_on:
- VR-115
- VR-117
summary: Publiceer de geverifieerde releaseimage naar de gekozen private registry, pin Unraid op tag+digest en
test pull/rollback.
acceptance_criteria:
- Registrytoken heeft minimale push/pullscope en staat alleen in CI/Unraid secretstore.
- Image heeft semver-tag, commitlabel, digest, SBOM en checksum/release notes.
- Unraid gebruikt geen CHANGE_ME of ongecontroleerde latest-tag.
verification:
- Pull image op schone host
- Start smoke stack en rollback naar vorige digest
primary_paths:
- .github/workflows/release.yml
- docker-compose.unraid.yml
external_blocker: Vereist registrykeuze, account en credentials.
- id: VR-205
title: Gelicenseerde Belgische geodatabron laden
status: done
priority: P1
requirement_ids:
- PR-002
- PR-041
- NFR-002
depends_on:
- VR-104
summary: Selecteer een actuele, voor lokaal gebruik en distributie geschikte postcode/municipality-dataset, leg
licentie/versie/checksum vast en laad ze met de reeds geïmplementeerde importer.
acceptance_criteria:
- Herkomst, licentie, versie, download-/reviewdatum en checksum zijn vastgelegd.
- Data bevat alleen noodzakelijke locatievelden en geen persoonsgegevens.
- Importvalidatie en een steekproef voor relevante Belgische regio's slagen.
verification:
- Draai geodata importcommand met --validate-only en daarna normale import
- Voer locatie- en scoretests tegen lokale dataset uit
primary_paths:
- lokale geodatafile
- config-data/geodata/README.local.md
result:
completed_at: '2026-07-22'
note: GeoNames België postcodedataset 2026-04-03 onder CC BY 4.0 gereviewd, checksums vastgelegd, 2781 unieke
rijen gevalideerd en 5562 lookuprecords geïmporteerd; 2400 Mol opgelost naar 51.1919, 5.1166 en actieve profielscores
herberekend.
- id: VR-206
title: Premium Stitch-cockpit en deterministische IT-focus
status: done
priority: P0
requirement_ids:
- PR-040
- PR-050
- PR-051
- NFR-004
- NFR-008
depends_on:
- VR-119
- VR-120
- VR-205
summary: Audit de volledige gebruikersflow in code en browser, voorkom dat niet-IT-vacatures de dagelijkse radar
vervuilen en benut de Stitch-compositie veel dominanter op mobiel, desktop en widescreen.
acceptance_criteria:
- Een deterministische en uitlegbare IT-relevantieregel heeft voorrang op scoring en AI; niet-IT-vacatures zijn
standaard afwezig uit Vandaag en de vacaturefeed maar blijven via een expliciete archiefkeuze inspecteerbaar.
- De vacaturefeed gebruikt echte score-evidence, bruikbare relevantie-/match-/sorteerfilters en toont standaard
de meest relevante IT-kansen in plaats van louter de nieuwste bronrecords.
- Dashboard, vacaturelijst en vacaturedetail nemen de bruikbare Stitch-panelhiërarchie, informatiedichtheid en
actiepatronen over zonder fictieve metrics, quick-apply of externe frontendafhankelijkheden.
- De shell en kernlayouts schalen inhoudelijk tussen 320 en 2560 px; widescreen voegt bruikbare kolommen/panelen
toe en laat de inhoud niet op een smalle 1280px-strook staan.
- Focus, headings, labels, lege toestanden, dark/light contrast, mobiele navigatie en reduced motion blijven toegankelijk;
kernroutes hebben geen horizontale paginaoverflow of browserconsolefouten.
verification:
- uv run pytest tests/unit/test_relevance.py tests/unit/test_scoring.py tests/integration/test_views.py tests/e2e/test_vr114_browser_and_accessibility.py
- ./scripts/codex_verify.sh
- Browsermatrix op 2560x1440, 1920x1080, 1440x900, 1024x768, 390x844 en 320x800
primary_paths:
- apps/jobs/services/relevance.py
- apps/jobs/services/scoring.py
- apps/jobs/views.py
- templates/dashboard/today.html
- templates/jobs/list.html
- templates/jobs/detail.html
- static/css/app.css
- docs/design/STITCH_INTEGRATION_PLAN.md
result:
completed_at: '2026-07-22'
note: 'Volledige code- en browseraudit: deterministische IT-focus, laatste gebruikersscore, premium Stitch-feed/detail
en adaptieve 320-2560px-layout; 225 tests groen en browsermatrix geslaagd.'
- id: VR-207
title: Cv-gestuurd field- en infrastructuurprofiel
status: done
priority: P0
requirement_ids:
- PR-002
- PR-040
- PR-041
- NFR-002
- NFR-004
depends_on:
- VR-206
summary: Breid de begeleide profielconfiguratie uit voor een ervaren IT field-/infrastructuurprofiel en voorkom
dat een brede, relevante skillset de matchscore kunstmatig verlaagt. Persoonlijke cv-data blijft uitsluitend
in de gebruikersdatabase en komt niet in repositoryfixtures of documentatie.
acceptance_criteria:
- Rollen en skills zijn in begrijpelijke categorieën selecteerbaar voor field service, infrastructuur, Microsoft
365/endpoint, netwerk/security, back-up/monitoring, virtualisatie, VoIP en automation.
- Relevante IT-ervaring is via een selectielijst configureerbaar en wordt deterministisch vergeleken met expliciet
gevraagde ervaringsjaren; onbekende ervaring leidt niet tot uitsluiting.
- Ambigue field-/implementatietitels gelden alleen als IT wanneer de vacaturetekst tevens een sterk technisch
contextsignaal bevat; niet-IT field service blijft gefilterd.
- Meer relevante cv-skills aanvinken verwatert de skillscore niet onbeperkt en niet-vermelde voorkeurskills worden
niet als bewezen tekort gepresenteerd.
- Bestaande vrije profielwaarden blijven selecteerbaar en persoonlijke gegevens uit cv's worden niet gecommit.
verification:
- uv run pytest tests/unit/test_relevance.py tests/unit/test_scoring.py tests/unit/test_profiles.py tests/integration/test_profile_preferences.py
- uv run python manage.py makemigrations --check --dry-run
- ./scripts/codex_verify.sh
primary_paths:
- apps/profiles/forms.py
- apps/profiles/models.py
- apps/profiles/taxonomy.py
- apps/jobs/services/relevance.py
- apps/jobs/services/scoring.py
- templates/profiles/edit.html
- static/css/app.css
result:
completed_at: '2026-07-22'
note: Cv-gestuurde gegroepeerde profielconfiguratie, ervaringsband, begrensde skill-evidence, contextgebonden
fieldrelevantie en lokale profielrescore geverifieerd; 232 tests groen en browsercontrole op ultrawide/390
px geslaagd.
- id: VR-208
title: Skillsvraag- en leerkansenradar zonder ervaringsscore
status: done
priority: P0
requirement_ids:
- PR-002
- PR-040
- PR-041
- PR-043
- PR-050
- NFR-004
depends_on:
- VR-207
summary: Maak ervaringsduur volledig informatief en bouw uit de actuele, relevante vacatures een uitlegbare marktvraaganalyse
met profieldekking, skillsfilters en concrete bijleerkansen.
acceptance_criteria:
- Ervaringsjaren en senioriteitslabels hebben geen invloed op score, aanbeveling of harde uitsluiting; de profielwaarde
is uitsluitend informatieve context en bestaande senioriteitsgewichten worden veilig genegeerd en opgeruimd.
- De analyse gebruikt alleen actieve IT-vacatures die voor het actieve profiel niet hard uitgesloten zijn en blijft
strikt gebruikersgescopeerd.
- Een deterministische, uitbreidbare skillcatalogus toont per technologie of capability in hoeveel vacatures een
expliciet tekstsignaal voorkomt en onderscheidt profieldekking van mogelijke leer-/bijscholingskansen.
- Het profiel biedt extra relevante skills als gegroepeerde checkboxes; de inzichtspagina biedt categorie- en
dekkingsfilters en links naar de onderliggende vacatures.
- Feiten, tekstinferenties en onbekende gegevens zijn in de Nederlandstalige UI duidelijk onderscheiden; lege
toestanden en layouts werken van 320 tot 2560 px zonder horizontale paginaoverflow.
verification:
- uv run pytest tests/unit/test_scoring.py tests/unit/test_skill_demand.py tests/integration/test_skill_insights.py
tests/integration/test_profile_preferences.py
- uv run python manage.py makemigrations --check --dry-run
- ./scripts/codex_verify.sh
- Browsercontrole op 2560x1440, 1440x900 en 390x844
primary_paths:
- apps/jobs/services/scoring.py
- apps/jobs/services/skill_demand.py
- apps/jobs/views.py
- apps/profiles/taxonomy.py
- templates/jobs/skill_insights.html
- static/css/app.css
- docs/architecture/SCORING_ENGINE.md
result:
completed_at: '2026-07-22'
note: Ervarings- en senioriteitsinvloed uit score en learning verwijderd; gebruikersgescopeerde Skillsradar
met actuele bronselectie, vraagbewijs, profieldekking, leerkansen, uitgebreide skillfilters en 2560/1440/390-browsercontrole
voltooid.
- id: VR-209
title: Stitch frontendcontract, audit en cockpit-shell
status: done
priority: P0
requirement_ids:
- PR-040
- PR-050
- PR-051
- NFR-004
- NFR-008
depends_on:
- VR-208
summary: Leg de volledige negen-schermenaudit en fidelitymatrix vast en vervang het globale design system, de
shell, navigatie en generieke browserstates door de Stitch Intelligence Cockpit.
acceptance_criteria:
- Contract en integratieplan bevatten alle negen schermen, afmetingen, componenten, route/data-mapping, fidelitydoelen,
responsive/accessibilityrisico's en legacy-opruiming.
- De enige productieshell gebruikt de lokale Stitch-tokens, compacte navigatie, contextbar, mobile drawer, skiplink,
focusstaten en echte statusdata zonder externe runtimeassets.
- Login, meldingen, lege toestanden en generieke foutstates gebruiken dezelfde visuele taal en blijven zonder
JavaScript bruikbaar.
verification:
- uv run pytest tests/integration/test_views.py tests/e2e/test_vr114_browser_and_accessibility.py
- uv run ruff check .
primary_paths:
- docs/design/STITCH_FRONTEND_CONTRACT.md
- docs/design/STITCH_INTEGRATION_PLAN.md
- templates/base.html
- static/css/app.css
- static/js/app.js
result:
completed_at: '2026-07-22'
note: Volledige negen-schermenaudit, fidelitymatrix, bindend frontendcontract en nieuwe lokale Stitch-cockpit-shell
met gesplitst design system, mobile navigatie en generieke foutstates; relevante tests groen.
- id: VR-210
title: Stitch dashboard en vacature-intelligence
status: done
priority: P0
requirement_ids:
- PR-040
- PR-041
- PR-050
- NFR-004
depends_on:
- VR-209
summary: Vervang dashboard, vacatureverkenner en detail door de echte Stitch-composities met database-aggregaties,
uitlegbare scores, provenance en veilige acties.
acceptance_criteria:
- Dashboard toont echte dag-, match-, filter-, duplicaat-, sollicitatie-, activiteit- en brongezondheidsdata met
beste matches als dominante feed.
- De explorer heeft serverfilters, actieve chips, paginering en een brede master/detailcompositie die querystring
en browser-back behoudt.
- Het detail toont scorebewijs, inhoud, provenance, versies, duplicaten, sollicitatiestatus en een responsive
actiedock; ervaring telt nergens als scorefactor en externe links blijven veilig.
verification:
- uv run pytest tests/integration/test_views.py tests/unit/test_scoring.py tests/unit/test_relevance.py
primary_paths:
- apps/core/views.py
- apps/jobs/views.py
- apps/jobs/services/cockpit.py
- templates/dashboard/today.html
- templates/jobs/list.html
- templates/jobs/detail.html
result:
completed_at: '2026-07-22'
note: Dashboard, vacatureverkenner en detail volledig naar Stitch-composities vervangen met echte cockpitaggregaties,
laatste profielscore, master/detailselectie, provenance, versies, duplicaten en veilige acties; relevante
scoring/relevance/viewtests groen.
- id: VR-211
title: Stitch pipeline, radarprofiel en brongezondheid
status: done
priority: P0
requirement_ids:
- PR-002
- PR-050
- PR-051
- NFR-004
depends_on:
- VR-210
summary: Vervang sollicitaties, zoekprofiel en bronnen door de functionele Stitch-pipeline, radarconfigurator
en source-healthinterface.
acceptance_criteria:
- Sollicitaties bieden kanban en lijstfallback, gebruikersgescopeerde POST-statuswijziging, deadlines, contact-
en timelinecontext.
- Het zoekprofiel groepeert echte selecties, toont revisie-informatie en een server-rendered preview uit de laatste
echte match.
- Bronnen tonen policy, runs, fout/succes, volgende planning, parser, tellingen, retry en bestaande beveiligde
import-/mailboxflows.
verification:
- uv run pytest tests/integration/test_applications.py tests/integration/test_profile_preferences.py tests/integration/test_sources_manual_import.py
tests/integration/test_source_health.py
primary_paths:
- apps/jobs/views.py
- apps/profiles/views.py
- apps/sources/views.py
- templates/applications
- templates/profiles
- templates/sources/list.html
result:
completed_at: '2026-07-22'
note: Stitch-kanban met gescopeerde auditbare status-POST, dossiereditor en tijdlijn; gegroepeerde radarconfigurator
met echte scorepreview/revisies; health-first bronnenconsole met policy/runbewijs, retry, mailbox- en importflows.
Relevante tests groen.
- id: VR-212
title: Stitch automation, activiteit en werkgeversintelligence
status: done
priority: P0
requirement_ids:
- PR-040
- PR-050
- PR-051
- NFR-002
- NFR-004
depends_on:
- VR-211
summary: Bouw de ontbrekende activiteit- en werkgeversroutes en vervang systeemstatus door een echte afgeleide
automationcockpit.
acceptance_criteria:
- Automation toont echte pipeline-, run-, score-, notificatie-, scheduling-, database- en configuratiestatus en
labelt niet-beschikbare infrastructuur eerlijk.
- Activiteit combineert betrouwbare, gebruikersgescopeerde gebeurtenissen in een filterbare, gelinkte en gepagineerde
tijdlijn.
- Werkgevers index/detail aggregeren echte werkgever-, vacature-, score-, bron- en sollicitatiedata zonder CRM-
of marktclaims te verzinnen.
verification:
- uv run pytest tests/integration/test_intelligence_views.py tests/integration/test_views.py
primary_paths:
- apps/jobs/services/activity.py
- apps/jobs/services/employer_intelligence.py
- apps/jobs/views.py
- apps/jobs/urls.py
- apps/core/views.py
- templates/activity
- templates/employers
- templates/system/status.html
result:
completed_at: '2026-07-22'
note: Echte automationcockpit met 24u-pipeline en eerlijke runtimeconfiguratie; gepagineerde/filterbare activiteitreadservice;
werkgeversindex/detail met vacature-, score-, bron- en dossieraggregaties. Nieuwe routes, templates en scope-tests
groen.
- id: VR-213
title: Stitch responsive validatie en legacyverwijdering
status: done
priority: P0
requirement_ids:
- NFR-004
- NFR-008
- NFR-009
depends_on:
- VR-212
summary: Rond de high-fidelity replacement af met browsermatrix, accessibility, elf screenshots, legacy-audit,
documentatie en volledige regressiegate.
acceptance_criteria:
- Alle negen schermen en kernflows zijn visueel en functioneel gecontroleerd tussen 360 en 1440 px, met aanvullende
ultrawidecontrole en schone browserconsole.
- Elf verplichte validatiescreenshots bestaan; majeure afwijkingen, accessibility- en querybevindingen staan in
het eindrapport.
- Oude visuele selectors, dode partials/JS en parallelle shellmarkup zijn verwijderd; de Stitch-frontend is de
enige normale productiefrontend.
- De volledige verificatiegate slaagt en backlog, projectstatus, traceability, README en changelog zijn bijgewerkt.
verification:
- ./scripts/codex_verify.sh
- Browsermatrix 1440x900, 1280x800, 1024x768, 768x1024, 390x844 en 360x800
primary_paths:
- static/css/app.css
- static/js/app.js
- tests/e2e
- artifacts/visual-validation
- docs/design/STITCH_INTEGRATION_REPORT.md
result:
completed_at: '2026-07-22'
note: Alle negen Stitch-schermen zijn browsergevalideerd van 360 tot 2560 px; elf screenshots, accessibility-/legacy-/queryaudit
en documentatie afgerond. Volledige gate groen met 248 tests, 2 optionele skips en 84,40% coverage.
- id: VR-214
title: Herstel het Unraid Dockerman-containericoon
status: done
priority: P1
requirement_ids:
- NFR-009
depends_on:
- VR-213
summary: Vervang de fragiele runtime-SVG voor de Dockerman-tegel door een lokale rasterasset en dek het volledige
Unraid-label- en packagingcontract af.
acceptance_criteria:
- Dockerman verwijst via de gepubliceerde webpoort naar een lokale PNG die door collectstatic in de image wordt
opgenomen.
- De browserfavicon blijft lokaal en ongewijzigd beschikbaar.
- Een regressietest controleert de exacte WebUI- en icoonlabels, PNG-signatuur en verwachte afmetingen.
- Het Unraid-runbook beschrijft het cachegedrag en de veilige refreshstap.
verification:
- uv run pytest tests/unit/test_deployment_configuration.py tests/integration/test_views.py
- ./scripts/codex_verify.sh
primary_paths:
- docker-compose.unraid.yml
- static/img/vacatureradar-docker.png
- tests/unit/test_deployment_configuration.py
- docs/operations/UNRAID_DEPLOYMENT.md
result:
completed_at: '2026-07-25'
note: Dockerman-icoon vervangen door lokale 256x256 PNG via exact Unraid-poortlabel; URL, PNG-signatuur en afmetingen
regressiegedekt. Volledige gate groen met 264 tests en 83,47% dekking. Live Unraid-image sha256:799825df1a343b6bee43695850454a5fdc977b5af3366077e6ac6aaeeb94f6f9
gebouwd en gerecreate; container healthy, readiness/liveness groen en PNG via LAN HTTP 200 (7111 bytes).
- id: VR-215
title: Corrigeer Dockermans server-side icoondownload
status: done
priority: P1
requirement_ids:
- NFR-009
depends_on:
- VR-214
summary: Gebruik voor het Dockerman-icoon een concrete server-side URL omdat Unraid placeholders alleen voor WebUI-links
vervangt en niet voor icoondownloads.
acceptance_criteria:
- Het icoonlabel bevat geen IP- of poortplaceholder en is vanaf de Unraid-host bereikbaar.
- Dockerman maakt `VacatureRadar-icon.png` in zijn eigen icooncache aan.
- De Docker-tegel gebruikt de gecachte PNG terwijl WebUI-poortsubstitutie behouden blijft.
- De regressietest en het Unraid-runbook leggen dit onderscheid vast.
verification:
- uv run pytest tests/unit/test_deployment_configuration.py
- Live Unraid-recreate, cachecontrole en HTTP-smoke
- ./scripts/codex_verify.sh
primary_paths:
- docker-compose.unraid.yml
- tests/unit/test_deployment_configuration.py
- docs/operations/UNRAID_DEPLOYMENT.md
result:
completed_at: '2026-07-25'
note: Dockerman gebruikt nu concrete server-side loopback-URL zonder placeholders; live Unraid-container healthy,
HTTP-smoke groen, persistente en RAM-cache bevatten geldige 256x256 PNG en docker.json verwijst naar VacatureRadar-icon.png.
Gericht 5 tests en volledige gate groen met 264 tests en 83,44% dekking.
- id: VR-216
title: Premium UX-verfijning met rustige visuele hiërarchie
status: done
priority: P1
requirement_ids:
- NFR-004
- NFR-008
- NFR-009
depends_on:
- VR-215
summary: Verfijn de bestaande Stitch-interface naar een premium, rustige cockpit met minder visuele ruis, selectiever
kleurgebruik en sterkere informatiehiërarchie zonder server-rendered flows te wijzigen.
acceptance_criteria:
- Donker en licht thema gebruiken gelaagde oppervlakken, zachtere scheidingen en cyan alleen voor primaire signalen
en acties; navigatie en labels gebruiken leesbare humane typografie.
- Dashboard, verkenner, detail, pipeline en profiel hebben een herkenbare eigen compositie met consistente componenten,
zonder nepdata of dode bediening.
- Mobiele KPI's staan compact boven de vouw, filters blijven bruikbaar en de pipeline scrolt intern zonder pagina-overflow
tussen 360 en 1440 px.
- Browsercontrole op 390 en 1280 px dekt donker en licht thema, kernflows en een schone console.
verification:
- uv run pytest tests/e2e/test_vr114_browser_and_accessibility.py tests/integration/test_views.py
- ./scripts/codex_verify.sh
- Browsermatrix 390x844 en 1280x800 in donker en licht thema
primary_paths:
- static/css
- templates/dashboard/today.html
- templates/jobs/list.html
- templates/applications/list.html
- templates/profiles/list.html
- docs/design/STITCH_INTEGRATION_REPORT.md
result:
completed_at: '2026-07-25'
note: Premium calm-intelligence-laag voor dark/light, compacte mobiele KPI's, responsieve filtercommandobar,
intern scrollende pipeline en breed profiel. Bestaande login-CSP-fout opgelost met lokale externe JS. Browsermatrix
390/1280 zonder overflow en schone console; volledige gate groen met 264 tests, 2 optionele skips en 83,44%
dekking.
- id: VR-217
title: Borg Unraid-authenticatie en voeg interactieve radarillustraties toe
status: done
priority: P1
requirement_ids:
- NFR-008
- NFR-009
depends_on:
- VR-216
summary: Maak het bestaande SSH-deploymentprofiel expliciet en voeg een lokale, toegankelijke interactieve radarillustratie
toe op inhoudelijk passende cockpitstates zonder echte data of kernflows te vervangen.
acceptance_criteria:
- Deploymentdocumentatie en helper valideren de geconfigureerde Unraid-hostalias en falen met een concrete herstelmelding
wanneer de verkeerde SSH-identiteit wordt gekozen.
- Een herbruikbare lokale radarillustratie versterkt profiel- en lege radarstates met pointer-/focusrespons en
bevat geen externe asset, fictieve metric of betekenisdragende informatie.
- De illustratie degradeert zonder JavaScript, respecteert prefers-reduced-motion en blijft verborgen voor hulptechnologie;
kernacties en tekst blijven zelfstandig bruikbaar.
- Browsercontrole op 390 en 1280 px in donker en licht thema toont geen overflow, consolefout of concurrerende
visuele hiërarchie; de live Unraid-container is na deployment healthy.
verification:
- uv run pytest tests/unit/test_deployment_configuration.py tests/e2e/test_vr114_browser_and_accessibility.py
- Browsermatrix 390x844 en 1280x800 in donker en licht thema
- Live SSH-, containerhealth- en HTTP-smoke via de geconfigureerde hostalias
- ./scripts/codex_verify.sh
primary_paths:
- scripts/deploy_unraid.ps1
- docs/operations/UNRAID_DEPLOYMENT.md
- templates/components/radar_illustration.html
- templates/profiles/list.html
- static/css/premium.css
- static/js/app.js
result:
completed_at: '2026-07-26'
note: Unraid-authenticatie hersteld via gevalideerde hostalias unraid-itworx met root en dedicated sleutel;
fail-fast deployhelper toegevoegd. Interactieve lokale SVG-radar met pointerparallax, dark/light en reduced-motionfallback
toegevoegd. Browsermatrix 390/1280 zonder overflow of consolefouten; 265 tests groen. Live image sha256:4d30e01e778777d5a2cde4339a9b2ad006edb25cae387293737420152d65069d
healthy en readiness/CSS/JS HTTP 200.
- id: VR-218
title: Personaliseer merkidentiteit en verfijn de globale UX
status: done
priority: P1
requirement_ids:
- NFR-004
- NFR-008
- NFR-009
depends_on:
- VR-217
summary: Vervang het generieke favicon door een herkenbaar radarsymbool, voeg configureerbare eigenaarssignatuur
toe en verfijn shell, oriëntatie, navigatie en micro-interacties tot een coherente persoonlijke premiumervaring.
acceptance_criteria:
- Favicon en hoofdlogo delen één scherp, lokaal en op 16 px herkenbaar radarsymbool met passende light/dark browsermetadata
en zonder externe assets.
- De shell en authenticatieschermen tonen VacatureRadar als product en een configureerbare eigenaarssignatuur
met veilige standaardwaarde Jens; deze branding wordt niet uit gebruikersdata of nepdata afgeleid.
- De topbar geeft compacte paginaoriëntatie, navigatie-/zoekinteracties hebben duidelijkere focus- en hoverstates
en mobiele bruikbaarheid blijft intact zonder extra bediening of JavaScriptafhankelijkheid.
- Browsercontrole op dashboard, verkenner, profiel en login bij 390 en 1280 px in donker en licht thema toont
geen overflow, consolefout of onduidelijke hiërarchie; live container en assets zijn healthy na deployment.
verification:
- uv run pytest tests/e2e/test_vr114_browser_and_accessibility.py tests/integration/test_auth_login.py tests/integration/test_views.py
- Browsermatrix 390x844 en 1280x800 in donker en licht thema
- Live favicon-, logo-, readiness- en containerhealth-smoke
- ./scripts/codex_verify.sh
primary_paths:
- apps/core/context_processors.py
- static/favicon.svg
- static/img/vacatureradar-logo.svg
- templates/base.html
- templates/registration
- static/css/premium.css
- static/css/auth.css
result:
completed_at: '2026-07-26'
note: Persoonlijke Jens-branding, vernieuwd radarbeeldmerk en favicon, contextuele bovenbalk en verfijnde navigatie/zoekfocus
zijn regressiegedekt, responsief in de browser gevalideerd en live uitgerold als healthy image sha256:5f25f00c9b7efb166587901ff39b02c56c98fb9946ddef0a4546a22f18dc0802.
- id: VR-219
title: Herstel ultrawide uitlijning en versterk persoonlijke merklock-up
status: done
priority: P1
requirement_ids:
- NFR-004
- NFR-008
depends_on:
- VR-218
summary: Breng de cockpit op brede schermen terug naar één voorspelbaar horizontaal grid en maak de persoonlijke
Jens-signatuur tot een herkenbaar onderdeel van de productbranding in plaats van losse metadata.
acceptance_criteria:
- Header, filters, hoofdpanelen en onderliggende secties delen op desktop en ultrawide hetzelfde startpunt en
dezelfde contentbreedte; er ontstaat geen grote toevallige lege linkerkolom.
- Verkenner en automatisering benutten 1920- en 3840-pixelbreedtes evenwichtig zonder uitgerekte leesregels, losgekoppelde
panelen of documentoverflow.
- Sidebar en bovenbalk tonen één consistente VacatureRadar-by-Jens-merklock-up; authenticatie en mobiele shell
behouden dezelfde eigenaarssignatuur zonder gebruikersnaam als merk te presenteren.
- Browsercontrole op 390, 1280, 1920 en 3840 px bevestigt consistente ankers, bruikbare paneelverhoudingen, schone
console en intacte toetsenbord-/mobiele flows.
verification:
- Browsermatrix dashboard, verkenner, automatisering en login op 390/1280/1920/3840 px
- uv run pytest tests/integration/test_auth_login.py tests/integration/test_views.py
- ./scripts/codex_verify.sh
primary_paths:
- templates/base.html
- static/css/layout.css
- static/css/premium.css
- static/css/responsive.css
result:
completed_at: '2026-07-26'
note: Ultrawide hoofdsecties delen één links verankerd 2800px-grid; explorer- en automationverhoudingen zijn
begrensd en Personal intelligence by Jens is de consistente lock-up. Browsermatrix 390/1280/1920/3840 schoon;
267 tests groen; live image sha256:86836f82cc543a7adb414e47b9667e9123bb9ceba10d629a53086273aaaae03f healthy
met readiness en asset-smokes.
- id: VR-220
title: Integreer de officiële ITWorx-merkidentiteit
status: done
priority: P1
requirement_ids:
- NFR-004
- NFR-008
- NFR-009
depends_on:
- VR-219
summary: Vervang de tijdelijke tekstuele Jens-branding door de door de eigenaar aangeleverde officiële ITWorx.tech-wordmark
en cloud-check-identiteit, met VacatureRadar herkenbaar als product binnen dat merk.
acceptance_criteria:
- Sidebar, login en herstelpagina's gebruiken de transparante officiële ITWorx.tech-wordmark uit het aangeleverde
asset pack; VacatureRadar blijft duidelijk als productnaam aanwezig.
- Browserfavicon en app-/Dockericoon gebruiken de officiële cloud-check-symboliek in een compacte transparante,
lokaal gehoste en voor klein formaat geoptimaliseerde variant.
- Merkassets hebben betekenisvolle alt-/toegankelijkheidslabels, laden zonder externe runtimebron en blijven scherp
en leesbaar in donker/licht thema en op mobiel.
- Browsercontrole op login, dashboard en verkenner bij 390, 1280 en 1920 px toont correcte assets, geen overflow
of consolefouten; de live container levert brandingassets en readiness met HTTP 200.
verification:
- Controleer afmetingen, transparantie en bestandsgrootte van de afgeleide merkassets
- uv run pytest tests/integration/test_auth_login.py tests/integration/test_views.py tests/unit/test_deployment_configuration.py
- Browsermatrix 390/1280/1920 voor login, dashboard en verkenner
- Live asset-, favicon-, readiness- en containerhealth-smoke
- ./scripts/codex_verify.sh
primary_paths:
- static/img/itworx-wordmark.png
- static/img/itworx-app-icon.png
- static/img/vacatureradar-docker.png
- templates/base.html
- templates/registration
- static/css/premium.css
- static/css/auth.css
result:
completed_at: '2026-07-26'
note: Officiële aangeleverde ITWorx.tech-wordmark geïntegreerd in sidebar, topbar, login en herstel; cloud-check
exact afgeleid voor 512px favicon/app-icon en 256px Dockermanicoon. Browsermatrix 390/1280/1920 schoon, 267
tests groen en live image sha256:daf34407813b37cdf2d0fc65a482ded65375f89eedd3f0144a8c0ce206d41565 healthy
met readiness/PNG-smokes.
- id: VR-221
title: Scheid appmerk van ontwikkelaarsbranding
status: done
priority: P1
requirement_ids:
- NFR-004
- NFR-008
- NFR-009
depends_on:
- VR-220
summary: Herstel VacatureRadar als zelfstandig productmerk met een nieuw professioneel radarlogo en favicon, en
plaats de aangeleverde ITWorx.tech-identiteit uitsluitend als subtiele ontwikkelaarscredit.
acceptance_criteria:
- VacatureRadar gebruikt een zelfstandig, vectorvriendelijk beeldmerk dat radar, detectie en een gevonden kans
combineert, scherp blijft op 16 px en visueel niet met het ITWorx-cloud-check-logo concurreert.
- Sidebar, login, favicon en Dockerman tonen het VacatureRadar-productmerk; ITWorx.tech staat alleen op geschikte
secundaire plaatsen als `Ontwikkeld door ITWorx.tech`.
- De ontwikkelaarscredit gebruikt de officiële aangeleverde ITWorx-wordmark lokaal en blijft ondergeschikt, toegankelijk
en leesbaar in donker/licht thema en op mobiel.
- Browsercontrole op login, dashboard en verkenner bij 390, 1280 en 1920 px toont correcte merkhiërarchie, geladen
assets, geen overflow of consolefouten; live container en alle assets zijn healthy.
verification:
- Inspecteer VacatureRadar-SVG op viewBox, elementeenvoud en klein-formaat-signatuur
- uv run pytest tests/integration/test_auth_login.py tests/integration/test_views.py tests/unit/test_deployment_configuration.py
- Browsermatrix 390/1280/1920 voor login, dashboard en verkenner
- Live logo-, favicon-, ontwikkelaarswordmark-, readiness- en containerhealth-smoke
- ./scripts/codex_verify.sh
primary_paths:
- static/favicon.svg
- static/img/vacatureradar-logo.svg
- static/img/vacatureradar-docker.png
- static/img/itworx-wordmark.png
- templates/base.html
- templates/registration
- static/css/premium.css
- static/css/auth.css
result:
completed_at: '2026-07-26'
note: VacatureRadar heeft een zelfstandig professioneel open-radar-logo, SVG-favicon en 256px Dockermanicoon;
officiële ITWorx.tech-wordmark staat alleen als Ontwikkeld door-credit. Twee beeldconcepten verkend, finale
geometrie handmatig als vijf-elementen-SVG gebouwd. Browsermatrix 390/1280/1920 schoon, 267 tests groen en
live image sha256:4184aeff33759b7a205637b0a0333b751b599141fe691a61965d2f1c56ca984a healthy met alle asset-smokes.
- id: VR-222
title: Voer een integrale premium visuele audit en herstelroadmap uit
status: done
priority: P1
requirement_ids:
- NFR-004
- NFR-008
- NFR-009
depends_on:
- VR-221
summary: Audit de volledige cockpit als één designsysteem en herstel merkhiërarchie, uitlijning, informatiedichtheid,
interactiedoelen, responsief gedrag en motion tot een consistente premium productervaring.
acceptance_criteria:
- Een gedateerd auditrapport bevat geprioriteerde bevindingen, concreet gevolg, herstelactie en volledige roadmap
voor alle hoofdschermen, login en herstel.
- Topbar en hoofdcontent delen voorspelbare horizontale ankers; dashboard en activiteit zijn aantoonbaar compacter
zonder echte informatie te verbergen of controles onbruikbaar te maken.
- VacatureRadar blijft het enige primaire appmerk; ITWorx.tech staat uitsluitend als subtiele ontwikkelaarscredit
en geen concept- of chroma-keybeeld wordt als productasset geleverd.
- Controls, focus, reduced motion, dark/light en 390/768/1280/1440/1920/3840 px zijn gecontroleerd zonder overflow,
consolefouten of regressie in de server-rendered kernflow.
- De live container is healthy en levert het finale logo, favicon en de relevante CSS met HTTP 200.
verification:
- Browsermatrix voor alle hoofdschermen plus login in dark/light en 390/768/1280/1440/1920/3840 px
- uv run pytest tests/integration/test_auth_login.py tests/integration/test_views.py
- ./scripts/codex_verify.sh
- Live readiness-, containerhealth- en assetsmokes
primary_paths:
- docs/design/VISUAL_AUDIT_2026-07-26.md
- templates/base.html
- templates/dashboard/today.html
- templates/activity/list.html
- static/css/premium.css
- static/css/pages.css
- static/css/responsive.css
result:
completed_at: '2026-07-26'
note: 'Integrale audit en roadmap uitgevoerd: gedeeld contentframe, vijf dashboardmatches, compacte activiteit,
subtiele ITWorx-credit, grotere klikdoelen, reduced-motion, CSS-cacheversies en herstelde mobiele login. Browsermatrix
50 checks plus light/login schoon; 268 tests groen, 2 skips, 83,45% dekking. Live image sha256:7e1688db80241813a04e27038ef5e4afb64748868b6a97e353346f077be50b70
healthy; readiness en assets HTTP 200.'
- id: VR-223
title: Verfijn transparant productlogo en professionele widescreenshell
status: done
priority: P1
requirement_ids:
- NFR-004
- NFR-008
- NFR-009
depends_on:
- VR-222
summary: Herstel de resterende merk- en shellfrictie uit de gebruikersscreenshot met een transparant cleaner productlogo,
één rustige sidebarfooter zonder dubbele accountidentiteit en beter benutte widescreenruimte.
acceptance_criteria:
- Het VacatureRadar-logo heeft geen donkere tegelachtergrond en blijft als eenvoudige vector scherp en herkenbaar
op dark/light, login, sidebar en klein formaat; favicon en Dockerman blijven doelgeschikt.
- De sidebar toont onderaan één samenhangende status-/ontwikkelaarszone en herhaalt de demo- of accountidentiteit
niet; accountacties blijven bereikbaar via het bestaande topbarmenu.
- De cockpit benut 1920, 2560 en 3840 px evenwichtiger zonder uitgerekte leesregels, losstaande topbaracties of
horizontale documentoverflow; mobiel en laptop blijven intact.
- Een gerichte vervolgcheck identificeert en herstelt bijkomende zichtbare shellproblemen, inclusief light/dark,
korte viewport en toetsenbord-/interactiestates.
- De live container is healthy en levert logo, favicon, CSS en readiness met HTTP 200.
verification:
- Browsermatrix dashboard, verkenner, automatisering, login op 390/1280/1920/2560/3840 px en korte sidebarviewport
- uv run pytest tests/integration/test_auth_login.py tests/integration/test_views.py tests/unit/test_deployment_configuration.py
- ./scripts/codex_verify.sh
- Live readiness-, containerhealth- en assetsmokes
primary_paths:
- static/img/vacatureradar-logo.svg
- static/css/layout.css
- static/css/premium.css
- static/css/responsive.css
- templates/base.html
result:
completed_at: '2026-07-27'
note: Transparant vier-elementenlogo zonder donkere tegel; één compacte sidebarfooter zonder dubbele accountidentiteit;
monochrome dark-mode ITWorx-credit en widescreenframes van 2200/2480 px. Browsermatrix 18 shellchecks plus
dark/light/login schoon; volledige gate tweemaal groen met 268 tests, 2 skips en 83,45% dekking. Live image
sha256:ea9e61a1febca59eb906bfdebcd9fd2b2c2b000189a8772f4abf09012722e921 healthy; readiness en assets HTTP
200.
- id: VR-301
title: Multi-tenant SaaS, teams en billing
status: deferred
priority: P3
requirement_ids:
- NFR-005
depends_on:
- VR-117
summary: Niet nodig voor de persoonlijke installatie. Alleen heroverwegen bij een apart productbesluit met tenantisolatie,
privacy, support en billingarchitectuur.
acceptance_criteria:
- Nieuwe productbeslissing en ADR vereist vóór implementatie.
verification:
- Niet uitvoeren binnen huidige scope.
primary_paths:
- docs/product/SCOPE_AND_NON_GOALS.md
- id: VR-224
title: Maak de repository-README functioneel en user-first met actuele screenshots
status: done
priority: P1
requirement_ids:
- NFR-008
- NFR-009
depends_on:
- VR-223
summary: Herbouw de repository-ingang rond het gebruikersprobleem, de dagelijkse workflow en een veilige quickstart,
ondersteund door compacte actuele productbeelden uit de echte server-rendered cockpit.
acceptance_criteria:
- De README begint bij doel, doelgroep en dagelijkse gebruikersflow; installatie, beheer, architectuur en agentoverdracht
volgen in een duidelijke progressieve volgorde zonder bestaande essentiële informatie te verliezen.
- Minstens vier actuele screenshots tonen verschillende functionele hoofdschermen, desktop en mobiel en dark/light;
ze bevatten geen secrets of persoonlijke gegevens en zijn lokaal, geoptimaliseerd en correct gelinkt.
- Quickstarts, poorten, lokale credentials, veiligheidsgrenzen en operationele documentatielinks zijn aantoonbaar
correct en maken duidelijk wat demo-, ontwikkel- en productiegebruik betekent.
- README-links en repositorydocumentatie valideren, de beelden zijn visueel gecontroleerd zonder overflow of consolefouten
en de volledige kwaliteitsgate slaagt.
verification:
- Browsercontrole van de vastgelegde routes en viewports
- python scripts/validate_repository.py
- ./scripts/codex_verify.sh
primary_paths:
- README.md
- docs/screenshots/readme/
- docs/quality/TRACEABILITY_MATRIX.md
- docs/ai/PROJECT_STATE.md
result:
completed_at: '2026-07-27'
note: User-first README met gecontroleerde quickstarts en vier actuele dark/light desktop-/mobielscreenshots;
browsermatrix zonder overflow of consolewaarschuwingen, repositoryvalidatie groen en volledige gate met 268
tests, 2 skips en 83,48% dekking.
- id: VR-302
title: Automatisch sollicitaties invullen of versturen
status: deferred
priority: P3
requirement_ids:
- PR-056
- AC-043
depends_on:
- VR-117
summary: Expliciet niet bouwen. Menselijke eindcontrole en verzending via het oorspronkelijke kanaal blijven een
vaste veiligheidsgrens.
acceptance_criteria:
- Er bestaat geen submitendpoint, browserbot of taak die extern solliciteert.
verification:
- Codezoekreview op submit/auto-apply; ADR-0006 blijft accepted.
primary_paths:
- docs/architecture/adrs/0006-no-automatic-applications.md
- id: VR-303
title: Publieke mobiele app en algemene externe API
status: deferred
priority: P3
requirement_ids:
- NFR-005
- NFR-009
depends_on:
- VR-117
summary: Server-rendered single-user UI voldoet. Alleen uitvoeren bij concrete integratiebehoefte, met auth/scopes/versioning
en een nieuwe ADR.
acceptance_criteria:
- Geen externe API-oppervlakte toevoegen zonder consumer en threat model.
verification:
- Niet uitvoeren binnen huidige scope.
primary_paths:
- docs/api/openapi.yaml
- docs/architecture/adrs/0008-server-rendered-design.md
- id: VR-225
title: Hard publieke reverse-proxydeployment en gasttoegang uit
status: done
priority: P0
requirement_ids:
- NFR-001
- NFR-006
- NFR-009
depends_on:
- VR-224
summary: Maak de bestaande persoonlijke installatie veilig en reproduceerbaar bereikbaar achter Nginx Proxy Manager,
herstel publieke host- en CSRF-configuratie en voorkom dat een gedeeld demoaccount persistente data wijzigt.
acceptance_criteria:
- Eén publieke HTTPS-URL configureert hostvalidatie, CSRF, secure cookies, SSL-detectie en redirect zonder de
interne containerpoort in de externe origin op te nemen.
- Productie start fail-fast bij debugmodusgerelateerde onveiligheid, een zwakke secret, onveilige cookies, ontbrekende
HTTPS-origin of een schrijfbare publieke demo.
- Login- en importlimieten gebruiken in productie een gedeelde cache; forwarded client-IPs worden alleen vanaf
expliciet vertrouwde proxy-CIDRs geaccepteerd.
- Het gastaccount is server-side alleen-lezen, heeft een begrensde sessie, kan afmelden en toont de beperking
zichtbaar.
- Unraid-envpad, Nginx Proxy Manager, healthchecks, noindex, heruitrol en terugdraaien zijn exact gedocumenteerd.
verification:
- PYTHONPATH=/mnt/data/vr_windows_site/site-packages pytest -q
- python manage.py check
- python manage.py makemigrations --check --dry-run
- python scripts/validate_repository.py
- bash -n scripts/deploy_docker.sh scripts/entrypoint.sh scripts/unraid_aio_entrypoint.sh
- Live Nginx-, TLS-, CSRF-, Dockerhealth- en restore-smoke op de doelserver
primary_paths:
- config/settings.py
- apps/core/middleware.py
- apps/core/network.py
- apps/core/health.py
- scripts/configure_public_url.py
- docker-compose.unraid.yml
- docs/operations/NGINX_PROXY_MANAGER.md
- docs/quality/PRODUCTION_AUDIT_2026-07-27.md
result:
completed_at: '2026-07-27'
note: Publieke host/CSRF/HTTPS-configuratie, gedeelde Redis-rate-limiting, proxy-IPvertrouwen, cache-readiness,
noindex en read-only gastdemo geïmplementeerd. 295 tests groen met 2 correcte Playwrightskips; Django check,
migratiecheck, repositoryvalidatie, YAML-, syntax- en packagechecks groen. Live servervalidatie blijft extern.
- id: VR-226
title: Verdiep de user-first README met een volledige productgalerij
status: done
priority: P1
requirement_ids:
- NFR-006
- NFR-008
- NFR-009
depends_on:
- VR-225
summary: Maak de productpresentatie overtuigender met een logisch opgebouwde, actuele galerij die de volledige
gebruikersreis toont zonder de README traag, repetitief of marketingmatig te maken.
acceptance_criteria:
- De README bevat minstens acht actuele beelden die dashboard, zoeken/analyse, skills, sollicitatieopvolging,
profiel, bronnen, automatisering en mobiel gebruik als één samenhangende productreis tonen.
- Desktopbeelden gebruiken een consistente professionele viewport en rustige uitsnede; dark/light en mobiel zijn
doelbewust verdeeld, zonder overgangsoverlays, overflow, consolefouten, secrets of persoonlijke gegevens.
- De galerij heeft korte taakgerichte captions, een scanbare compositie en compacte lokale assets; duplicatieve
beelden of losse decoratieve screenshots worden verwijderd of vervangen.
- De eerder aangetroffen VR-225-baselinefouten in lint en platformafhankelijke bestandsmoduscontrole zijn hersteld;
repositoryvalidatie en de volledige kwaliteitsgate slagen.
verification:
- Browsercontrole van alle vastgelegde routes op desktop en mobiel in dark/light
- uv run pytest tests/unit/test_public_configuration.py
- python scripts/validate_repository.py
- ./scripts/codex_verify.sh
primary_paths:
- README.md
- docs/screenshots/readme/
- scripts/configure_public_url.py
- tests/unit/test_public_configuration.py
- docs/quality/TRACEABILITY_MATRIX.md
- docs/ai/PROJECT_STATE.md
result:
completed_at: '2026-07-28'
note: README verdiept tot een klikbare user-first productreis met negen actuele beelden op 1920x1080 en 390x844
in dark/light; alle routes zonder overflow of consolewaarschuwingen. VR-225-lint en Windows-modusassertie
hersteld; 296 tests groen, 2 skips en 83,44% dekking.
- id: VR-227
title: Professionaliseer VacatureRadar integraal voor release 0.3.13
status: done
priority: P0
requirement_ids:
- NFR-001
- NFR-006
- NFR-007
- NFR-008
- NFR-009
- NFR-010
depends_on:
- VR-226
summary: Voer de integrale responsive, UX-, accessibility-, performance-, observability-, security- en operationsroadmap
uit en vervang optionele browsercontrole door een verplichte releasegate.
acceptance_criteria:
- Hoofdcontent en topbar delen een gecentreerd adaptief frame; gastbanner, sticky elementen en pipeline blijven
bruikbaar van 390 tot 3440 px zonder documentoverflow.
- De vacatureflow is begrensd gepagineerd, globale zoekcopy is eerlijk, mobiel pipelinegebruik is verticaal en
demomutaties veroorzaken geen controlmuur.
- Playwright Chromium draait verplicht in CI op zes viewports, faalt op console/page errors en controleert focus,
kernreis en documentoverflow zonder skips.
- Automatisering toont een echte worker/beat-heartbeat en markeert niet-meetbare queuediepte eerlijk; benchmarkparserdekking
is volledig en reproduceerbaar.
- Baseline, performance, architectuur, operations, testing, traceability, externe acties en finale acceptance
zijn actueel en de volledige repositorygate slaagt.
verification:
- python -m scripts.benchmark --quick --skip-performance --json
- python -m pytest tests/e2e/test_vr114_browser_and_accessibility.py
- python -m pytest tests/unit/test_runtime_observability.py tests/unit/test_generic_html_adapter.py
- docker compose config
- ./scripts/codex_verify.sh
primary_paths:
- static/css/
- static/js/app.js
- templates/base.html
- apps/core/services/automation.py
- apps/core/tasks.py
- tests/e2e/test_vr114_browser_and_accessibility.py
- docs/audit/
- USER_INPUT_REQUIRED.md
result:
completed_at: '2026-07-29'
note: Release 0.3.13 professionaliseert responsive layout, mobiele gastflow, begrensde vacature-UX, verplichte
zes-viewport-Playwrightgate zonder skips, echte runtimeheartbeat, parserbenchmark, authdekking, SBOM en integrale
documentatie; volledige gate 312 tests groen, 84,16% dekking.
- id: VR-228
title: Optimaliseer de importpipeline voor release 0.3.14
status: done
priority: P0
requirement_ids:
- NFR-007
- NFR-008
- NFR-009
depends_on:
- VR-227
summary: Profileer de PostgreSQL-import reproduceerbaar, verwijder aantoonbare N+1- en overbodige writes en lever
de geverifieerde optimalisatie veilig op zonder wijziging aan deduplicatie, scoring of datakwaliteit.
acceptance_criteria:
- Een fail-closed runner meet een disposable PostgreSQL-database met vaste fixture, warm-up en drie herhalingen.
- De geoptimaliseerde import reduceert queryvolume en doorlooptijd aantoonbaar tegenover 0.3.13 en rapporteert
p50, p95, throughput, geheugen en queryfamilies.
- Parserdekking blijft 12/12, dedupeprecision en -recall blijven 1,0, rankingchurn blijft nul en historische ScoreRuns
plus veldprovenance blijven intact.
- Regressietests begrenzen het queryvolume; de volledige kwaliteitsgate slaagt tweemaal en productieacceptatie
bewijst health, beperkte importsmoke, publieke kernflows en rollbackgereedheid.
verification:
- python -m scripts.benchmark_import --jobs 250 --iterations 3
- uv run pytest tests/integration/test_pipeline.py tests/unit/test_import_benchmark.py
- ./scripts/codex_verify.sh
primary_paths:
- apps/jobs/services/pipeline.py
- scripts/benchmark.py
- scripts/benchmark_import.py
- tests/integration/test_pipeline.py
- docs/audit/IMPORT_PERFORMANCE_FINAL.md
result:
completed_at: '2026-07-29'
note: 'Release 0.3.14: geïsoleerde PostgreSQL-benchmark reduceert importduur 44,74% en queries minstens 63,73%;
twee volledige gates met 318 tests groen; productie healthy op image sha256:1ee84241, transactionele importsmoke
teruggerold en rollbackimage 0.3.13 beschikbaar.'