docs: complete Stitch frontend replacement
This commit is contained in:
@@ -1717,7 +1717,7 @@ tasks:
|
||||
groen.
|
||||
- id: VR-213
|
||||
title: Stitch responsive validatie en legacyverwijdering
|
||||
status: ready
|
||||
status: done
|
||||
priority: P0
|
||||
requirement_ids:
|
||||
- NFR-004
|
||||
@@ -1744,6 +1744,10 @@ tasks:
|
||||
- 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-301
|
||||
title: Multi-tenant SaaS, teams en billing
|
||||
status: deferred
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Projectstatus
|
||||
|
||||
- Laatst bijgewerkt: 2026-07-22
|
||||
- Repositoryversie: 0.2.13 persoonlijke skillsvraag- en leerkansenradar
|
||||
- Repositoryversie: 0.3.0 volledige Stitch Intelligence Cockpit
|
||||
- Uitvoeringsmodus: autonome backlog
|
||||
- Eerste uitvoerbare taak: controleer met `python scripts/backlog.py next`
|
||||
|
||||
@@ -14,11 +14,33 @@ De repository bevat een uitvoerbare Django-MVP met:
|
||||
- JSON-LD-, HTML-, RSS/Atom- en e-mailadapters;
|
||||
- normalisatie, sanitization, werkgeverresolutie, dedupe, aliassen, provenance en versies;
|
||||
- deterministische features, harde exclusions, scores en optionele uitgeschakelde Ollama-boundary;
|
||||
- responsive dark/light cockpitdashboard, vacaturelijst/detail, sollicitatiepipeline, profiel-, bron- en systeemschermen;
|
||||
- volledige responsive dark/light Stitch-cockpit met negen functionele hoofdschermen, skillsradar, login en foutstates;
|
||||
- feedbackacties, applicationdossiers, lifecycle en dagelijkse digest-outbox;
|
||||
- Celeryworker/scheduler, healthchecks, Docker/Unraidconfiguratie en back-up-/herstelscripts;
|
||||
- offline unit-, integratie- en securitytests.
|
||||
|
||||
## Laatste frontendvervanging
|
||||
|
||||
VR-209 tot en met VR-213 vervangen de oude browserfrontend integraal:
|
||||
|
||||
- één nieuwe lokale Stitch-shell en design system zonder CDN of clientframework;
|
||||
- echte dashboard-/vacature-intelligence, sollicitatiepipeline, profielconfigurator en source-healthinterface;
|
||||
- nieuwe activiteit- en werkgeversroutes/read models en een eerlijke automationcockpit;
|
||||
- standaard IT-relevantie, persoonlijke scorecontext en user-scoped mutaties blijven intact;
|
||||
- browsermatrix van 360 tot 2560 px, elf actuele screenshots, schone console en geen documentoverflow;
|
||||
- bronhealth-N+1 verwijderd: twee queries voor alle bron/runmetingen, 23 totale queries voor het representatieve automationscherm.
|
||||
|
||||
Het volledige scherm- en afwijkingsrapport staat in `docs/design/STITCH_INTEGRATION_REPORT.md`.
|
||||
|
||||
VR-209–213-verificatie op 2026-07-22:
|
||||
|
||||
- 248 tests geslaagd, 2 optionele Playwrightvarianten overgeslagen en 84,40% branch-aware codedekking;
|
||||
- Ruff, Django system check, migratiecheck, backlogvalidatie en repository-/documentvalidatie geslaagd via `scripts/codex_verify.sh`;
|
||||
- alle negen routes in de geïntegreerde browser gecontroleerd zonder consolewaarschuwingen, kapotte assets of documentoverflow;
|
||||
- browsermatrix: 360×800, 390×844, 768×1024, 1024×768, 1280×800, 1440×900, 1920×1080 en 2560×1440;
|
||||
- elf actuele beelden onder `artifacts/visual-validation/`; artifacts en Stitch-referenties blijven buiten de productieimage;
|
||||
- volgende uitvoerbare taak: geen; alleen de bestaande externe credentials-/infrastructuurblokkades en uitgestelde productkeuzes resteren.
|
||||
|
||||
## Laatste geverifieerde baseline
|
||||
|
||||
Release-audit op 2026-07-21:
|
||||
|
||||
@@ -1,73 +1,42 @@
|
||||
# Toegankelijkheid
|
||||
|
||||
Doel: WCAG 2.2 AA voor de kernflows.
|
||||
Doel: WCAG 2.2 AA voor alle kernflows van de server-rendered Stitch-cockpit.
|
||||
|
||||
## Semantiek
|
||||
## Productiecontract
|
||||
|
||||
- één `h1` per pagina, hiërarchische headings;
|
||||
- navigatie in `<nav>` met duidelijke accessible name;
|
||||
- lijsten/tabellen voor werkelijke lijst-/tabulaire data;
|
||||
- formulieren met expliciete `<label>`;
|
||||
- statusmetadata als definition list waar passend;
|
||||
- externe links herkenbaar in tekst/accessible label.
|
||||
- Skiplink, `aside`/`nav`, `header`, één `main` en één `h1` per pagina.
|
||||
- Headingniveaus volgen de visuele hiërarchie; tabulaire data gebruikt echte headers.
|
||||
- Formulieren hebben expliciete labels, hints, gekoppelde errors en servervalidatie.
|
||||
- Status gebruikt tekst naast kleur; score en datakwaliteit zijn afzonderlijk benoemd.
|
||||
- Icon-only controls hebben een toegankelijke naam; lokale decoratieve SVG's zijn verborgen.
|
||||
- Externe vacaturetekst is gesanitized; links gebruiken veilige attributen en geen verborgen automatische actie.
|
||||
|
||||
## Toetsenbord
|
||||
## Toetsenbord en progressive enhancement
|
||||
|
||||
Alle functies moeten zonder muis werken. Focusvolgorde volgt visuele volgorde. `:focus-visible` heeft een contrastvolle ring. Geen keyboard traps. Na server-POST landt focus logisch via heading/message; toekomstige modals herstellen focus.
|
||||
Alle routes, filters, feedback, dossiers, statuswijzigingen en profiel-/bronforms werken zonder JavaScript. JavaScript verbetert uitsluitend drawer, disclosure, viewtoggle, zoekfocus en thema. De mobiele drawer beheert `aria-expanded`, focus en sluitactie. Focus is zichtbaar; er zijn geen tijdslimieten of keyboard traps. `prefers-reduced-motion` reduceert alle transities.
|
||||
|
||||
## Kleur en contrast
|
||||
## Contrast, zoom en reflow
|
||||
|
||||
- bodytekst minimaal 4,5:1;
|
||||
- grote tekst minimaal 3:1;
|
||||
- focus en componentgrenzen minimaal 3:1 waar vereist;
|
||||
- status nooit alleen via kleur;
|
||||
- light/dark afzonderlijk toetsen.
|
||||
De donkere en lichte tokensets bewaren tekst-, focus- en componentcontrast. Metadata is gedempt maar niet de enige informatiedrager. Content heeft geen vaste teksthoogte. Op 360 px en bij 200% zoom blijft het document binnen het viewport; alleen intrinsiek brede pipeline-/tabeldata gebruikt een gelabelde interne scroller.
|
||||
|
||||
## Zoom en reflow
|
||||
## Browservalidatie VR-213
|
||||
|
||||
- bruikbaar op 320 CSS px breed;
|
||||
- 200% zoom zonder verlies van acties/tekst;
|
||||
- geen vaste hoogte voor tekstkaarten;
|
||||
- lange URL's en woorden breken;
|
||||
- horizontale scroll alleen voor intrinsiek brede data met alternatief.
|
||||
Op 22 juli 2026 zijn de negen hoofdervaringen met echte lokale data gecontroleerd:
|
||||
|
||||
## Forms en fouten
|
||||
- viewports: 1440×900, 1280×800, 1024×768, 768×1024, 390×844 en 360×800;
|
||||
- aanvullende widescreencontrole: 1920×1080 en 2560×1440;
|
||||
- op iedere gecontroleerde route: één `h1`, skiplink, hoofdlandmark, geen kapotte images en geen documentbrede overflow;
|
||||
- mobiele sidebar is gesloten buiten gebruik, opent met `aria-expanded=true` en sluit terug naar `false`;
|
||||
- dark/light wisselt met de correcte actienaam; de initiële naam volgt nu ook een opgeslagen voorkeur;
|
||||
- pipeline en automationtabellen scrollen lokaal zonder de pagina te verbreden;
|
||||
- browserconsole bevatte geen errors of warnings.
|
||||
|
||||
- foutsummary bovenaan bij meerdere fouten;
|
||||
- inline fout bij veld;
|
||||
- `aria-invalid` en `aria-describedby`;
|
||||
- voorbeeld en vereiste syntax als hint;
|
||||
- geen placeholder als enige label;
|
||||
- validatie niet alleen on blur.
|
||||
De elf bewijsscreenshots staan onder `artifacts/visual-validation/`. De optionele pytest-Playwrightvariant blijft lokaal overgeslagen wanneer Playwright niet geïnstalleerd is; de HTML/a11y-probe en de geïntegreerde Codex-browseraudit vormen samen het uitgevoerde bewijs.
|
||||
|
||||
## Dynamiek
|
||||
## Handmatige reviewchecklist
|
||||
|
||||
- server-rendering heeft geen verborgen loading state;
|
||||
- async updates gebruiken live regions spaarzaam;
|
||||
- successmessages niet alleen tijdelijk visueel;
|
||||
- motion respecteert reduced motion;
|
||||
- tijdslimieten bestaan niet in gebruikersflows.
|
||||
|
||||
## Vacaturetekst
|
||||
|
||||
Gesanitized HTML behoudt headings, paragraphs, lists en links waar veilig. Verwijder scripts, forms, iframes, eventhandlers en gevaarlijke URL-schema's. Voeg waar nodig `rel="noopener noreferrer"` toe aan externe links.
|
||||
|
||||
## Testen
|
||||
|
||||
Per zichtbare taak:
|
||||
|
||||
1. keyboard-only;
|
||||
2. browser zoom/reflow;
|
||||
3. automatische HTML/accessibilityscan waar beschikbaar;
|
||||
4. screenreader smoke test voor dashboard, vacaturedetail en profiel;
|
||||
5. contrastcontrole;
|
||||
6. test met lange/lege/unknown content.
|
||||
|
||||
## VR-118 browservalidatie
|
||||
|
||||
- Dashboard gecontroleerd op 1440×900, 1280×800, 1024×768, 768×1024, 390×844 en 360×800.
|
||||
- Op alle zes viewports: exact één `h1`, geen documentbrede horizontale overflow en de juiste desktop/mobile navigatiestatus.
|
||||
- Mobiel menu opent met `aria-expanded=true`, sluit met Escape/sluitactie en is buiten de focus-/accessibilityflow wanneer gesloten.
|
||||
- Themawisselaar blijft bruikbaar wanneer browseropslag niet beschikbaar is; de UI geeft dan geen consolefout.
|
||||
- Dashboard, vacaturelijst/detail, sollicitatiepipeline, profielen/editor, bronnen en systeem zijn met echte seeded data en zonder externe assets gevalideerd.
|
||||
- Screenshots staan onder `docs/design/validation/` en zijn via `.dockerignore` uitgesloten van de productiecontainer.
|
||||
1. Tabvolgorde en zichtbare focus op dashboard, detail, profiel en pipeline.
|
||||
2. Screenreader-smoke voor shelllandmarks, scorelabels en formuliererrors.
|
||||
3. Dark/light contrast en status zonder kleur.
|
||||
4. 200% zoom, lange titels, lege/unknown states en 360 px reflow.
|
||||
5. Fout/success na POST en terugkeer naar een logisch heading- of messagepunt.
|
||||
|
||||
+42
-114
@@ -1,130 +1,58 @@
|
||||
# Design system
|
||||
# VacatureRadar design system
|
||||
|
||||
> Geactualiseerd voor VR-118. De volledige Stitch-mapping en bewuste afwijkingen staan in
|
||||
> `docs/design/STITCH_INTEGRATION_PLAN.md`.
|
||||
Dit document beschrijft de enige normale productiefrontend vanaf versie 0.3.0. De visuele bron van waarheid is de Stitch Intelligence Cockpit; het bindende contract en de schermmapping staan in `STITCH_FRONTEND_CONTRACT.md` en `STITCH_INTEGRATION_REPORT.md`.
|
||||
|
||||
## 1. Merkgevoel
|
||||
## Visuele identiteit
|
||||
|
||||
Rustig, betrouwbaar, helder en technisch precies. De interface voelt als een professionele intelligence-cockpit:
|
||||
donker marineblauw als standaard, signaalcyaan voor primaire interactie en tonale lagen in plaats van zware schaduwen.
|
||||
De lichte variant behoudt dezelfde hiërarchie. Geen confetti, fictieve grafieken, eindeloze badges of agressieve notificatiekleuren.
|
||||
De standaardervaring is een donkere, technische navycockpit. Signal Cyan markeert focus en primaire acties, Emerald aantoonbaar positieve of gezonde status, Intelligence Indigo automatisering en Amber/Coral aandacht of fout. Tonale oppervlakken en fijne borders vormen de hiërarchie; glows zijn beperkt tot focus en sterke signalen.
|
||||
|
||||
## 2. Visuele tokens
|
||||
De productietokens staan uitsluitend in `static/css/tokens.css`:
|
||||
|
||||
De implementatie staat in `static/css/app.css`. Gebruik semantische custom properties in plaats van losse kleuren in componenten.
|
||||
- oppervlakken: `--surface-lowest`, `--surface`, `--surface-low`, `--surface-container`, `--surface-high`, `--surface-highest`, `--surface-bright`;
|
||||
- tekst: `--text`, `--text-strong`, `--text-muted`, `--text-faint`;
|
||||
- signalen: `--cyan`, `--cyan-dim`, `--emerald`, `--indigo`, `--amber`, `--coral`, `--danger`;
|
||||
- structuur: `--outline`, `--outline-strong`, `--sidebar-width`, `--topbar-height`, `--content-gutter`, radii en `--shadow-signal`.
|
||||
|
||||
Geïmplementeerde tokenrollen omvatten onder meer:
|
||||
De light variant gebruikt dezelfde semantische tokens en informatiehiërarchie. Component-CSS bevat geen eigen hardcoded palette; uitzonderingen zijn alleen documentmetadata zoals `theme-color` en e-mailtemplates buiten de cockpit.
|
||||
|
||||
```css
|
||||
--bg
|
||||
--bg-deep
|
||||
--surface
|
||||
--surface-low
|
||||
--surface-high
|
||||
--surface-bright
|
||||
--text
|
||||
--text-soft
|
||||
--muted
|
||||
--border
|
||||
--border-strong
|
||||
--primary
|
||||
--primary-strong
|
||||
--positive
|
||||
--warning
|
||||
--danger
|
||||
--signal-glow
|
||||
--radius-sm
|
||||
--radius
|
||||
```
|
||||
## Typografie en iconen
|
||||
|
||||
Donkere modus is de productstandaard. De gebruiker kan lokaal wisselen via `data-theme`; opslag is progressief en
|
||||
mag in een afgeschermde browsercontext uitvallen zonder de bediening te breken.
|
||||
- Headlines: lokale systeemstack die Geist benadert (`Segoe UI Variable Display`, Aptos Display, Segoe UI).
|
||||
- Body: `Segoe UI Variable Text`, Aptos en systeemfallbacks.
|
||||
- Technische metadata: Cascadia Mono, SFMono/Consolas.
|
||||
- Geen externe font- of iconrequest; iconen komen uit één lokale inline SVG-sprite.
|
||||
- Score, datum en metadata blijven tekstueel leesbaar en steunen nooit alleen op kleur of vorm.
|
||||
|
||||
## 3. Typografie
|
||||
## Layoutsysteem
|
||||
|
||||
- systeemfontstack, geen externe fontrequest;
|
||||
- basis 16px;
|
||||
- body line-height ongeveer 1,55;
|
||||
- compacte metadata 0,8–0,9rem maar nooit onder bruikbare leesgrootte;
|
||||
- titels met duidelijke schaal, niet alleen gewicht;
|
||||
- cijfers voor scores mogen tabular nums gebruiken.
|
||||
- Vaste technische sidebar van 256 px en contexttopbar op desktop.
|
||||
- Flexibel datacanvas met een maximum van 2240 px; op 1920/2560 px benutten feeds en intelligencepanelen de extra breedte.
|
||||
- Bij 1180 px stapelen de zwaarste rails; bij 820 px wordt de sidebar een drawer met mobiele tabbar; bij 560 px worden cards, forms en intelligenceblokken éénkoloms.
|
||||
- Kanban, pipeline en datatabellen mogen alleen binnen een gelabelde lokale container horizontaal scrollen. Het document zelf heeft geen horizontale overflow.
|
||||
- Sticky actions houden rekening met de mobiele tabbar en bedekken geen essentiële informatie.
|
||||
|
||||
## 4. Spacing en layout
|
||||
## Kerncomponenten
|
||||
|
||||
- 4/8px-gebaseerde schaal;
|
||||
- contentcontainer maximaal 2240px; vanaf 1850px gebruikt de cockpit extra resultaatkolommen en
|
||||
contextpanelen in plaats van alleen langere tekstregels;
|
||||
- kaarten met consistente padding 20–24px desktop, 16px mobiel;
|
||||
- minimaal 44×44px touch targets voor primaire interactie;
|
||||
- vaste zijbalk van 272px boven 900px, toegankelijke uitschuifnavigatie daaronder;
|
||||
- grids breken rond 1850px, 1350px, 1180px, 900px en 680px logisch af;
|
||||
- vaste/sticky elementen mogen content niet bedekken.
|
||||
- `cockpit-sidebar`, `cockpit-topbar`, `mobile-tabbar`: globale shell en navigatie.
|
||||
- `cockpit-heading`, `section-heading`, `eyebrow`, `section-kicker`: informatiehiërarchie.
|
||||
- `stat-card`, `panel`, `tonal-panel`, `result-card`: tonale contentlagen.
|
||||
- `pill-*`, `status-beacon`: status met zichtbare tekst naast kleur.
|
||||
- `intelligence-score`, `hero-score`, `score-components`: match en datakwaliteit als afzonderlijke begrippen.
|
||||
- `filter-console`, `active-filters`: server-side filters en deelbare querystrings.
|
||||
- `pipeline-board`, `activity-timeline`, `data-table-wrap`: taakgerichte datapatronen met toegankelijke fallback.
|
||||
- `form-section`, `choice-field`, `profile-preview`: echte Django-formulieren met begeleide selecties en server-rendered bewijs.
|
||||
- `empty-state`, `toast-stack`, fouttemplates: consistente lege, success-, fout- en onbekende staten.
|
||||
|
||||
## 5. Componenten
|
||||
## Interactie
|
||||
|
||||
### Button
|
||||
Vanilla JavaScript is alleen progressive enhancement voor drawer, disclosures, viewtoggle, zoekshortcut en thema. Alle links, filters, formulieren, statuswijzigingen en mutaties werken server-side. Motion is functioneel, kort en uitgeschakeld via `prefers-reduced-motion`.
|
||||
|
||||
Varianten:
|
||||
## Reviewchecklist
|
||||
|
||||
- primary — één primaire actie per context;
|
||||
- secondary — normale navigatie/opslaan;
|
||||
- ghost — lage nadruk;
|
||||
- danger — destructief met bevestiging;
|
||||
- compact icon+label — vacaturefeedback.
|
||||
|
||||
States: hover, focus-visible, active, disabled, busy. Disabled blijft leesbaar en verklaarbaar.
|
||||
|
||||
### Badge/status pill
|
||||
|
||||
Bevat altijd tekst. Rollen: strong, possible, weak, hidden, active, review, deny, quarantined, expired. Gebruik niet alleen rood/groen.
|
||||
|
||||
### Card
|
||||
|
||||
Semantische header/body/footer. Hele kaart niet klikbaar wanneer er meerdere interne acties zijn; titel/link is de primaire link.
|
||||
|
||||
### Score
|
||||
|
||||
Score = getal/100 + recommendationtekst. Confidence wordt als “Datakwaliteit hoog/middel/laag” of exact percentage in detail getoond. Geen cirkeldiagram nodig voor één waarde.
|
||||
|
||||
### Form
|
||||
|
||||
- label boven veld;
|
||||
- hint vóór fout;
|
||||
- fout gekoppeld via `aria-describedby`;
|
||||
- required expliciet;
|
||||
- JSON-achtige lijstvelden uiteindelijk vervangen door chips/multi-select;
|
||||
- opslaan bevestigt, maar verliest scroll/focus niet onnodig.
|
||||
|
||||
### Alert
|
||||
|
||||
Info/success/warning/error met icoon, titel en tekst. Alerts zijn `role=status` of `role=alert` afhankelijk van urgentie.
|
||||
|
||||
### Table/list
|
||||
|
||||
Kolomkoppen semantisch; op mobiel cards of stacked definition list. Actiekolom niet te breed.
|
||||
|
||||
## 6. Motion
|
||||
|
||||
- alleen functionele transities 120–200ms;
|
||||
- respecteer `prefers-reduced-motion`;
|
||||
- geen automatische carrousels, pulserende scores of decoratieve parallax.
|
||||
|
||||
## 7. Iconen
|
||||
|
||||
Gebruik eenvoudige inline SVG's met `aria-hidden=true` naast zichtbare tekst. Geen externe iconfont. Een icon-only button vereist accessible label/tooltips.
|
||||
|
||||
## 8. Datavisualisatie
|
||||
|
||||
Gebruik balken voor scorecomponenten met numerieke tekst. Kleur ondersteunt, maar label/waarde draagt betekenis. Grafieken zijn niet nodig zolang data laag-volume is.
|
||||
|
||||
## 9. Designreviewchecklist
|
||||
|
||||
- primaire taak binnen één scherm duidelijk;
|
||||
- geen ruwe technische identifiers in dagelijkse UI;
|
||||
- empty/error/loading states aanwezig;
|
||||
- focusvolgorde logisch;
|
||||
- contrast en zoom 200% gecontroleerd;
|
||||
- mobiel 320px breed bruikbaar;
|
||||
- lange titels/werkgevers/URL's breken veilig;
|
||||
- Nederlands consistent;
|
||||
- scoreverklaring niet verstopt achter kleur.
|
||||
- één duidelijke primaire taak en één `h1` per pagina;
|
||||
- echte data of expliciet “Niet gemeten/Onbekend/Niet geconfigureerd”;
|
||||
- geen controls zonder serveractie;
|
||||
- consistente focusring, tekstlabels en minimaal bruikbare touch targets;
|
||||
- reflow zonder documentoverflow op 360 px en dynamische benutting tot 2560 px;
|
||||
- lange Nederlandse labels, werkgeversnamen en URL's breken veilig;
|
||||
- geen externe runtimeassets, oude shell of parallel frontendpad.
|
||||
|
||||
@@ -13,8 +13,8 @@ De ontvangen ZIP `stitch_vacatureradar_intelligence_cockpit.zip` is geïnventari
|
||||
| Zoekprofiel editor | 1600×1280 | configuratiestappen met vaste radarpreview | `/profiles/<id>/` · `profiles/edit.html` |
|
||||
| Bronnenbeheer & gezondheid | 1600×1340 | bronstatusrijen, disclosures en integriteitspanelen | `/sources/` · `sources/list.html` |
|
||||
| Automatisering centrum | 1540×1600 | pipelinefasen, operationele KPI's, brontabel en lograil | `/system/` · `system/status.html` |
|
||||
| Activiteitenlogboek | 1600×1441 | filterbare technische tijdlijn met samenvatting | `/activity/` · `activity/list.html` |
|
||||
| Werkgevers intelligence | 1600×931 | employer table met intelligence-detailrail | `/employers/` en `/employers/<id>/` · employer templates |
|
||||
| Activiteitenlogboek | 1600×1441 | filterbare technische tijdlijn met samenvatting | `/jobs/activity/` · `activity/list.html` |
|
||||
| Werkgevers intelligence | 1600×931 | employer table met intelligence-detailrail | `/jobs/employers/` en `/jobs/employers/<id>/` · employer templates |
|
||||
|
||||
## Tokens en herbruikbare bouwstenen
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# Stitch-integratierapport
|
||||
|
||||
## Resultaat
|
||||
|
||||
VacatureRadar 0.3.0 gebruikt één normale productiefrontend: de functionele Django-vertaling van de negen Stitch Intelligence Cockpit-schermen. De voormalige MVP-shell, monolithische stylesheet en pagina-indelingen zijn vervangen. Backendregels, named routes, user scoping, CSRF, sanitization, bronbeleid en servervalidatie blijven leidend.
|
||||
|
||||
Startcommit: `029df89`. Branch: `codex/stitch-frontend-replacement`.
|
||||
|
||||
## Schermmapping en fidelity
|
||||
|
||||
| Stitch-scherm | Productie-implementatie | Fidelity | Bewuste afwijking |
|
||||
| --- | --- | --- | --- |
|
||||
| Dashboard overzicht | `/` · `templates/dashboard/today.html` | Zeer hoog | Geen fictieve trends; dagconclusie en KPI's zijn echte aggregaties. |
|
||||
| Nieuwe matches | `/jobs/` · `templates/jobs/list.html` | Zeer hoog | Server-side master/detail en paginering vervangen prototype-state. |
|
||||
| Vacature intelligence detail | `/jobs/<uuid>/` · `templates/jobs/detail.html` | Hoog | Geen quick apply, kaart of salaris wanneer backenddata ontbreekt. |
|
||||
| Sollicitatie pipeline | `/jobs/applications/` · applicationtemplates | Zeer hoog | Select+POST en lijstfallback in plaats van drag-only kanban. |
|
||||
| Zoekprofiel editor | `/profiles/<id>/` · profieltemplates | Hoog | Preview gebruikt laatste echte score en ververst na server-save. |
|
||||
| Bronnenbeheer & gezondheid | `/sources/` · `templates/sources/list.html` | Zeer hoog | Veiligheids-, import- en mailboxflows blijven zichtbaar en progressief. |
|
||||
| Automatisering centrum | `/system/` · `templates/system/status.html` | Hoog | Worker/AI/browserstatus is eerlijk onbekend of niet geconfigureerd. |
|
||||
| Activiteitenlogboek | `/jobs/activity/` · `templates/activity/list.html` | Zeer hoog | Multi-model read service; geen nieuw fictief auditmodel. |
|
||||
| Werkgevers intelligence | `/jobs/employers/` en detail · employertemplates | Zeer hoog | Geen verzonnen sector, contactfinder of CRM-data. |
|
||||
|
||||
Ook login, 403/404/500, messages, empty states, dossieredit en skillsradar gebruiken dezelfde componenttaal.
|
||||
|
||||
## Implementatie
|
||||
|
||||
### Templates en assets
|
||||
|
||||
Vervangen of fundamenteel herschikt: `base.html`, dashboard, jobs list/detail/skills, applications list/edit, profiles list/edit, sources list, system status en registration login. Nieuw: activity, employer index/detail en generieke fouttemplates.
|
||||
|
||||
`static/css/app.css` is alleen de ingang voor `tokens.css`, `base.css`, `layout.css`, `components.css`, `pages.css` en `responsive.css`. `static/js/app.js` bevat alleen progressive enhancement. Iconografie is één lokale SVG-sprite. Er zijn geen externe fonts, iconfonts, Tailwind/CDN of clientframeworks.
|
||||
|
||||
### Services, views en routes
|
||||
|
||||
- `apps/jobs/services/cockpit.py`: dashboard- en vacature-intelligence.
|
||||
- `apps/jobs/services/activity.py`: begrensde, user-safe multi-model tijdlijn.
|
||||
- `apps/jobs/services/employer_intelligence.py`: werkgeveraggregaties en detailreadmodel.
|
||||
- `apps/core/services/automation.py`: eerlijke operationele cockpit.
|
||||
- `apps/jobs/services/applications.py`: auditbare statuswijziging via POST.
|
||||
- Nieuwe named routes: `jobs:activity`, `jobs:employers`, `jobs:employer-detail`, `jobs:application-status`.
|
||||
|
||||
Er waren geen nieuwe modellen of migraties nodig. Bestaande bronhealth is geoptimaliseerd met een per-bron geslicete prefetch.
|
||||
|
||||
## Echte data en security
|
||||
|
||||
Alle KPI's komen uit `JobPosting`, laatste `ScoreRun`, `Application`, `Source`, `SourceRun`, outbox- of profieldata. Persoonlijke feedback, dossiers, notificaties en profielrevisies zijn gebruikersgescopeerd. Vacature-HTML blijft de gesanitized backendwaarde. Externe links en POST-acties behouden bestaande securitycontracts. Er is geen automatische sollicitatie, platformloginbot, CAPTCHA-omzeiling of directe denylistcrawl toegevoegd.
|
||||
|
||||
## Responsive en browservalidatie
|
||||
|
||||
Gecontroleerd met de echte app en representatieve lokale fixtures op 360×800, 390×844, 768×1024, 1024×768, 1280×800 en 1440×900; dashboard, explorer en werkgevers ook op 1920×1080 en 2560×1440. Alle negen schermen zijn op desktop en 390 px doorlopen.
|
||||
|
||||
Resultaat:
|
||||
|
||||
- geen documentbrede horizontale overflow;
|
||||
- mobiele sidebar en tabbar functioneren;
|
||||
- profile preview respecteert de gridkolom;
|
||||
- brede automationpipeline en tabellen scrollen alleen intern;
|
||||
- geen kapotte images;
|
||||
- geen browserconsole-errors of warnings;
|
||||
- dark/light actielabel en opgeslagen voorkeur zijn consistent.
|
||||
|
||||
Screenshots:
|
||||
|
||||
- `artifacts/visual-validation/dashboard-desktop.png`
|
||||
- `artifacts/visual-validation/matches-desktop.png`
|
||||
- `artifacts/visual-validation/job-detail-desktop.png`
|
||||
- `artifacts/visual-validation/applications-desktop.png`
|
||||
- `artifacts/visual-validation/profile-desktop.png`
|
||||
- `artifacts/visual-validation/sources-desktop.png`
|
||||
- `artifacts/visual-validation/automation-desktop.png`
|
||||
- `artifacts/visual-validation/activity-desktop.png`
|
||||
- `artifacts/visual-validation/employers-desktop.png`
|
||||
- `artifacts/visual-validation/dashboard-mobile.png`
|
||||
- `artifacts/visual-validation/job-detail-mobile.png`
|
||||
|
||||
De afbeeldingen en Stitch-referenties zijn via `.dockerignore` uit de productieimage gehouden.
|
||||
|
||||
## Accessibility
|
||||
|
||||
De shell heeft skiplink en expliciete landmarks; iedere hoofdroute heeft één `h1`. Status gebruikt tekst, formulieren behouden echte labels/servererrors, mutaties werken zonder JavaScript en motion respecteert reduced motion. De drawer is met toetsenbord-/ARIA-state getest. Wide data heeft focusbare lokale scrollcontainers. De HTML/a11y-probe slaagt; de optionele externe pytest-Playwrightvariant is alleen beschikbaar wanneer Playwright lokaal geïnstalleerd is.
|
||||
|
||||
## Performance
|
||||
|
||||
Representatieve volledige paginaquerymetingen: dashboard 16, explorer 17, detail 15, pipeline 5, profiel 6, bronnen 14, activiteit 10 en werkgevers 14. Automation daalde door het verwijderen van de bronhealth-N+1 van 63 naar 23 queries. `collect_source_health()` is regressiegedekt op exact twee queries voor meerdere bronnen. Grote tijdlijnen en detailsets zijn begrensd; lijsten gebruiken annotaties, `select_related` en prefetching.
|
||||
|
||||
## Legacy-audit
|
||||
|
||||
Er is geen oude shell, alternatieve feature flag of parallelle frontendroute. Oude componentselectors, kleuren en monolithische pagina-opbouw zijn verwijderd. Alleen HTML-e-mailtemplates behouden bewust hun zelfstandige inline mailstijl; zij zijn geen browserfrontend. Bestaande historische validatiebeelden blijven documentair bewijs, maar worden niet gerenderd of in de productiecontainer opgenomen.
|
||||
|
||||
## Verificatie en beperkingen
|
||||
|
||||
De volledige `scripts/codex_verify.sh`-gate is zowel vóór als na ledgerafronding groen: Ruff, Django system check, `makemigrations --check --dry-run`, 248 geslaagde tests, 2 optioneel overgeslagen Playwrightvarianten, 84,40% branch-aware coverage, backlogvalidatie en repository-/documentvalidatie.
|
||||
|
||||
Bekende externe beperkingen wijzigen de frontend niet: live mailbox-/SMTP-credentials en productie-infrastructuur blijven afzonderlijke `blocked-external` taken. Niet-bestaande backenddata wordt bewust als onbekend getoond.
|
||||
+39
-143
@@ -1,171 +1,67 @@
|
||||
# UX-specificatie
|
||||
|
||||
## 1. Ervaringsprincipe
|
||||
## Ervaringsprincipe
|
||||
|
||||
VacatureRadar voelt niet als een zoekmachine maar als een rustige persoonlijke inbox. De gebruiker ziet eerst beslisbare informatie en pas daarna technische details. Bronbeheer en parserproblemen blijven beschikbaar, maar domineren de dagelijkse flow niet.
|
||||
VacatureRadar is een persoonlijke intelligence-cockpit: eerst beslisbare informatie, daarna bewijs en technische details. Het product claimt alleen wat uit echte vacatures, scores, bronruns en gebruikersacties kan worden afgeleid. Ervaring en senioriteitslabels zijn context, nooit een blokkerende scorefactor.
|
||||
|
||||
## 2. Informatiearchitectuur
|
||||
## Informatiearchitectuur
|
||||
|
||||
Hoofdnavigatie:
|
||||
De desktopnavigatie groepeert:
|
||||
|
||||
1. **Vandaag** — beste matches en kernstatus;
|
||||
2. **Vacatures** — volledige doorzoekbare lijst;
|
||||
3. **Sollicitaties** — dossiers en opvolging;
|
||||
4. **Profiel** — voorkeuren en drempels;
|
||||
5. **Bronnen** — source health en retries;
|
||||
6. **Systeem** — health, versies en beheercontext.
|
||||
1. Overzicht;
|
||||
2. Nieuwe matches en het volledige vacaturearchief;
|
||||
3. Skillsradar;
|
||||
4. Sollicitatiepipeline;
|
||||
5. Werkgeversradar;
|
||||
6. Zoekprofiel;
|
||||
7. Bronnen;
|
||||
8. Automatisering;
|
||||
9. Activiteit.
|
||||
|
||||
Op mobiel wordt dit een compacte uitklapbare navigatie; primaire vacatureacties blijven binnen duimbereik.
|
||||
Mobiel blijven Overzicht, Matches, Pipeline en Profiel in de vaste tabbar; alle routes blijven bereikbaar via de toegankelijke drawer.
|
||||
|
||||
## 3. Dashboard “Vandaag”
|
||||
## Schermgedrag
|
||||
|
||||
### Doel
|
||||
### Overzicht
|
||||
|
||||
Binnen 30 seconden weten of er iets relevants is.
|
||||
Toont echte dag-KPI's, beste recente radarselectie, dagconclusie, open opvolging, recente auditgebeurtenissen en bronstatus. Beste matches zijn visueel dominant; onbekende trends worden niet gesimuleerd.
|
||||
|
||||
### Volgorde
|
||||
### Vacatureverkenner en detail
|
||||
|
||||
1. paginatitel + korte samenvatting;
|
||||
2. KPI's: nieuwe vandaag, actieve vacatures, open dossiers, ongezonde bronnen;
|
||||
3. kaarten, descending score;
|
||||
4. lege toestand met concrete uitleg;
|
||||
5. subtiele link naar alle vacatures/bronnen.
|
||||
De verkenner combineert serverfilters, sortering, actieve filterchips, paginering en op breed scherm een geselecteerd intelligencepaneel. Standaard worden alleen aantoonbaar IT-relevante, niet hard uitgesloten vacatures getoond. Het volledige bronarchief blijft expliciet bereikbaar.
|
||||
|
||||
### Matchkaart
|
||||
Het detail scheidt matchscore, recommendation en datakwaliteit; toont componentbewijs, positieve signalen, concerns, skills, vacaturetekst, provenance, bronnen, versies en dossierstatus. Externe bronlinks zijn veilig en nooit een automatische sollicitatie.
|
||||
|
||||
Boven de vouw:
|
||||
### Sollicitatiepipeline
|
||||
|
||||
- recommendationlabel;
|
||||
- score als `86/100` en confidence apart;
|
||||
- functietitel;
|
||||
- werkgever;
|
||||
- locatie + werkvorm;
|
||||
- maximaal twee kernpluspunten;
|
||||
- maximaal één belangrijkste concern;
|
||||
- acties: bekijken, interessant, bewaren, verbergen, gesolliciteerd.
|
||||
Kanban is de visuele standaard; de lijstweergave en statusselectie zijn de toegankelijke fallback. Statuswijzigingen zijn echte CSRF-beveiligde POST-acties en schrijven een tijdlijnevent. Dossieredit toont snapshot, contact, notities, documentenstatus en activiteit.
|
||||
|
||||
Regels:
|
||||
### Zoekprofiel en skillsradar
|
||||
|
||||
- geen score zonder label/uitleg;
|
||||
- onbekende data als “Niet vermeld” of “Nog niet berekend”;
|
||||
- hard uitgesloten jobs niet op Vandaag;
|
||||
- dubbele aliassen niet als aparte kaart.
|
||||
De configurator groepeert profielbasis, rollen, technologiesignalen, regio, werkvorm en overige voorkeuren. Postcode volstaat; gemeente en coördinaten komen uit de gelicenseerde lokale dataset. Rollen en skills zijn selecties/checkboxes, geen ruwe JSON. De preview gebruikt de laatste echte score en revisiehistoriek.
|
||||
|
||||
## 4. Vacaturelijst
|
||||
De skillsradar toont vraagvolume, profieldekking, expliciet skillveldbewijs versus tekstsignalen en niet-blokkerende leerkansen.
|
||||
|
||||
Filters:
|
||||
### Bronnen en automatisering
|
||||
|
||||
- vrije tekst;
|
||||
- relevantiefocus: standaard aantoonbare IT-titels, met expliciet volledig bronarchief;
|
||||
- radarselectie: standaard geen harde uitsluitingen of verborgen score, met aparte inspectiefilters;
|
||||
- status;
|
||||
- recommendation/scoreband;
|
||||
- werkvorm;
|
||||
- regio;
|
||||
- werkgeverstype;
|
||||
- feedbackstatus.
|
||||
Bronnen tonen policy en operationele status apart, plus laatste run, volgende planning, parser, tellingen, retry, imports en gebruikersgescopeerde platformmailboxen. Directe crawling van denylistplatformen blijft verboden.
|
||||
|
||||
Desktop gebruikt een compacte filterbalk; mobiel een disclosurepanel. Filters blijven in querystring zodat bookmarks en back navigation werken.
|
||||
Automatisering toont de echte 24-uursketen, database/readiness, bronruns, scoring en notificaties. Worker-, AI- of browserstatus wordt als niet gemeten/niet geconfigureerd gelabeld wanneer geen betrouwbare probe bestaat.
|
||||
|
||||
De standaardvolgorde is persoonlijke matchscore, niet importtijd. Niet-IT-inhoud wordt niet
|
||||
verwijderd: ze blijft uitsluitend via `Volledig archief` bereikbaar. Een beschrijvingshit alleen
|
||||
mag nooit een niet-IT-titel promoveren.
|
||||
### Activiteit en werkgevers
|
||||
|
||||
Tabel of kaarten kiezen op breedte. Geen horizontale scroll voor kernvelden.
|
||||
Activiteit is een gepagineerde, filterbare tijdlijn uit bronruns, vacatureversies, feedback, dossiers, notificaties en profielrevisies. Persoonlijke events zijn gebruikersgescopeerd.
|
||||
|
||||
## 5. Vacaturedetail
|
||||
Werkgevers combineert genormaliseerde werkgever-, vacature-, score-, bron- en dossierdata in een index/detailervaring. Sector, contact of marktclaims worden niet verzonnen.
|
||||
|
||||
Secties:
|
||||
## States en copy
|
||||
|
||||
1. titel, werkgever, status, canonical link;
|
||||
2. score-overzicht met componenten;
|
||||
3. “Waarom aanbevolen” en aandachtspunten;
|
||||
4. harde uitsluitingen indien via directe link geopend;
|
||||
5. vacaturetekst (gesanitized);
|
||||
6. voorwaarden/skills/locatie;
|
||||
7. bronnen en provenance;
|
||||
8. wijzigingshistorie;
|
||||
9. sollicitatiestatus/notities.
|
||||
- Empty: verklaart waarom en biedt één relevante vervolgstap.
|
||||
- Unknown: “Niet vermeld”, “Niet gemeten” of “Niet geconfigureerd”.
|
||||
- Error/partial/stale: toont impact en een veilige retry waar ondersteund, nooit een stacktrace.
|
||||
- Success: servermessage in een `aria-live` toast en blijvende nieuwe toestand.
|
||||
- Copy is Nederlands, direct en niet-oordelend: “Mogelijke match” en “Niet teruggevonden” in plaats van absolute geschiktheidsclaims.
|
||||
|
||||
Bronbewijs wordt technisch maar scanbaar getoond: veld, methode, confidence, excerpt en bron.
|
||||
## Responsiveness
|
||||
|
||||
## 6. Profielwizard/editor
|
||||
|
||||
De eerste onboarding wordt in maximaal vijf logische stappen opgezet:
|
||||
|
||||
1. rollen en ongewenste titels;
|
||||
2. skills en ongewenste verplichte skills;
|
||||
3. regio, afstand en werkvorm;
|
||||
4. contract en employerpreferences;
|
||||
5. digest en samenvatting.
|
||||
|
||||
De bestaande editor mag één pagina blijven voor MVP, maar groepeert velden visueel en geeft voorbeeldsyntax. JSON mag in de interne modelvorm bestaan; de eindgebruiker ziet uiteindelijk chips/checkboxes, geen ruwe JSON.
|
||||
|
||||
Opslaan toont:
|
||||
|
||||
- welke harde regels actief zijn;
|
||||
- scoregewichten in begrijpelijke labels;
|
||||
- profielversie;
|
||||
- mogelijkheid om learning uit/reset te zetten.
|
||||
|
||||
## 7. Bronnen
|
||||
|
||||
Bronkaart/-rij toont:
|
||||
|
||||
- naam en domein;
|
||||
- type;
|
||||
- policy en operationele status apart;
|
||||
- laatste succes/fout;
|
||||
- volgende run;
|
||||
- parser/confidence;
|
||||
- laatste tellingen;
|
||||
- retryknop indien policy niet deny.
|
||||
|
||||
Kleur is nooit de enige indicator. `deny`, `review`, `quarantined` hebben tekst en icoon/patroon.
|
||||
|
||||
## 8. Sollicitaties
|
||||
|
||||
Kanban is niet noodzakelijk. Een duidelijke lijst met status, werkgever, functie, applied date, follow-up date en eerstvolgende actie is beter voor laag volume.
|
||||
|
||||
Dossierdetail/editor bevat:
|
||||
|
||||
- immutable vacaturesnapshot;
|
||||
- huidige bronlink/status;
|
||||
- contact;
|
||||
- notities;
|
||||
- documentenmanifest;
|
||||
- tijdlijn van statuswijzigingen (backlog);
|
||||
- opvolgdatum.
|
||||
|
||||
## 9. Meldingen
|
||||
|
||||
Digestcopy:
|
||||
|
||||
```text
|
||||
2 sterke matches
|
||||
4 mogelijke matches
|
||||
11 automatisch uitgesloten
|
||||
1 opgeslagen vacature sluit binnenkort
|
||||
```
|
||||
|
||||
Elke vacature heeft titel, werkgever, locatie, score, twee redenen, één aandachtspunt en originele link. Geen volledige vacaturetekst in mail.
|
||||
|
||||
## 10. States
|
||||
|
||||
Iedere pagina specificeert:
|
||||
|
||||
- loading: alleen nodig bij async enhancement; serverrender toont normale response;
|
||||
- empty: leg uit waarom en geef één relevante actie;
|
||||
- error: concrete fout + veilige retry, geen stacktrace;
|
||||
- partial: bron/resultaten beschikbaar met warning;
|
||||
- stale: toon laatste succesvolle tijd en dat vernieuwing faalde;
|
||||
- unauthorized: login en geen informatielek.
|
||||
|
||||
## 11. Copyrichtlijnen
|
||||
|
||||
- Nederlands, direct en niet-oordelend;
|
||||
- “Mogelijke match” in plaats van “Je bent geschikt”;
|
||||
- “Niet teruggevonden” in plaats van “Je mist”;
|
||||
- “Rechtstreekse werkgeversbron” in plaats van absolute garantie;
|
||||
- percentages alleen wanneer betekenis duidelijk is;
|
||||
- technische bronfout in beheer, eenvoudige impacttekst op dashboard.
|
||||
Desktop bewaart de Stitch-kolomverhoudingen. Tablet stapelt intelligence-rails onder de hoofdtaak. Mobiel herschikt kaarten en forms; wide data gebruikt een lokale scroller. De browsermatrix omvat 360×800, 390×844, 768×1024, 1024×768, 1280×800, 1440×900 en aanvullende 1920/2560px-controles.
|
||||
|
||||
@@ -63,7 +63,7 @@ Legenda: **I** = geïmplementeerd en getest in de huidige MVP; **P** = gedeeltel
|
||||
| NFR-005 | I | domeinapps/services/adapters/ADRs | continue review |
|
||||
| NFR-006 | I | offline pytest + coveragegate | VR-114 verbreedt e2e |
|
||||
| NFR-007 | P | `scripts/benchmark.py`, `tests/benchmark/test_benchmark.py` | VR-116 |
|
||||
| NFR-008 | I | semantische Stitch-dominante templates, zes viewports, dark/light en toetsenbordmenu | `tests/e2e/test_vr114_browser_and_accessibility.py`, `docs/design/validation/`, VR-118/119 |
|
||||
| NFR-008 | I | volledige negen-schermen-Stitch-cockpit, acht viewports, dark/light, toetsenborddrawer en elf actuele screenshots | `tests/e2e/test_vr114_browser_and_accessibility.py`, `tests/integration/test_intelligence_views.py`, `artifacts/visual-validation/`, VR-209–213 |
|
||||
| NFR-009 | I | lokale SQLite en Docker/Unraidconfig, release-smoke en restore | VR-117 afgerond |
|
||||
| NFR-010 | I | `apps/sources/services/health.py`, `apps/sources/tasks.py`, `apps/core/views.py`, `config/settings.py` | `tests/integration/test_source_health.py` | VR-112 observability |
|
||||
|
||||
@@ -101,3 +101,4 @@ Iedere backlogtaak die een requirement wijzigt, werkt in dezelfde commit deze ma
|
||||
- VR-206 voegt een titelgestuurde IT-relevantiegrens vóór scoring/AI toe, maakt de persoonlijke radarselectie de standaard en benut Stitch-panelen dynamisch tot 2560 px. Bewijs staat in `apps/jobs/services/relevance.py`, de score-/viewtests en `docs/design/validation/VR-206_AUDIT.md`.
|
||||
- VR-207 breidt het profiel uit met gegroepeerde field-/infrastructuurrollen, cv-skills en een ervaringsband. Skill-evidence is op vier treffers begrensd, afwezigheid wordt niet als tekort gepresenteerd en ambigue fieldtitels vereisen een onafhankelijk IT-contextsignaal. Persoonlijke cv-waarden staan uitsluitend in de lokale gebruikersdatabase; repositorytests en documentatie blijven gesaneerd.
|
||||
- VR-208 maakt die ervaringsband uitsluitend informatief en verwijdert ook senioriteitsinvloed uit de AI-component en feedbacklearning. De gebruikersgescopeerde Skillsradar analyseert actuele niet-uitgesloten IT-vacatures van actieve bronnen, onderscheidt skillveldbewijs van tekstinferentie en toont profieldekking en mogelijke leerkansen met categorie-/dekkingsfilters.
|
||||
- VR-209–213 vervangen de volledige browserfrontend door de negen Stitch Intelligence Cockpit-composities. De nieuwe shell, dashboard/vacature-intelligence, pipeline/profiel/bronnen, automation/activiteit/werkgevers en responsive validatie zijn gekoppeld aan echte read models en serveracties. Bewijs staat in `docs/design/STITCH_INTEGRATION_REPORT.md`, route-/scope-/querytests en de elf beelden onder `artifacts/visual-validation/`.
|
||||
|
||||
Reference in New Issue
Block a user