diff --git a/docs/logboek.md b/docs/logboek.md index fc98d85..e6d274c 100644 --- a/docs/logboek.md +++ b/docs/logboek.md @@ -77,14 +77,14 @@ Wat ik deed: - Domeinbasis: titel/artiest-matching (normalisatie, met tolerantie voor Spotify's versie-suffixen zoals "- Remaster 2023"), compressie van het - Spotify-smaakprofiel naar prompttekst plus een set bekende track-ids, + Spotify taste profile naar prompttekst plus een set bekende track-ids, prompts als data in een eigen module, en alle instelbare waarden gesectioneerd in de config met per waarde het waarom. - Twee LLM-calls achter een eigen interface: call 1 interpreteert de - vraag (stemming, activiteit, taal, bekendheid) en stelt 30-40 echte + vraag (mood, activity, language, familiarity) en stelt 30-40 echte nummers voor als gestructureerde output; call 2 herordent uitsluitend - geverifieerde nummers en streamt per nummer een eerlijke onderbouwing. - Elke output wordt gevalideerd, met hooguit 1 herstelpoging. + geverifieerde nummers en streamt per nummer een eerlijke justification. + Elke output wordt gevalideerd, met hooguit 1 correctie-retry. - Grounding: begrensde parallelle search fan-out met early stop, een deadline, een naam-naar-id cache en twee aparte metrieken: niet gevonden versus wel gevonden maar afgekeurd door de match-check. Een track-id dat niet in @@ -96,7 +96,7 @@ Wat ik deed: Waarom: -- De LLM is hier de aanbeveler, maar mag alleen creatief zijn tussen twee +- De LLM is hier de recommender, maar mag alleen creatief zijn tussen twee deterministische muren: alles wat hij ziet is echte data, alles wat de gebruiker ziet is geverifieerd op Spotify. Een verzonnen nummer valt stilletjes af en verschijnt nooit. @@ -165,7 +165,7 @@ Wat ik deed: - Per unresolved kandidaat wordt titel, artiest en status gelogd, zodat zichtbaar is WAT het model verzon in plaats van alleen hoeveel. -### Eerlijke gedeeltelijke resultaten +### Eerlijke partial results Wat ik deed: @@ -201,3 +201,41 @@ Waarom: - De frontend is de tweede consument van het bevroren contract: elke event wordt tegen de TypeScript-union gevalideerd in plaats van los geparst; wat niet valideert is een transport failure, geen gok. + +### Frontend: componenten en app shell + +Dit deel is grotendeels geautomatiseerde omzetting: het UI bouwpakket uit +Open Design heb ik door een cli agent laten converteren naar Vue single file components +tegen het bevroren contract. De transportlaag eronder (stream client, +validatie) komt uit de vorige stap. Review- en hardeningpassen op dit +resultaat volgen hierna als eigen stappen; wat hier staat is de ruwe +conversie. + +Wat ik deed: + +- Alle componenten uit het bouwpakket laten omzetten: chat view, + composer met suggestion chips, streamende track cards met album covers + en een justification per nummer, warning banners, error states, login-status, + mode banner en een dev panel. +- App shell met keyboard-navigatie, focus management en reduced-motion + support. + +Waarom: + +- Het bouwpakket was hierop ontworpen; de componenten volgen de tokens en + states daaruit, en elke regel gaat alsnog door review voordat die op + main landt. +- Styling is scoped CSS per component bovenop globale design tokens + (custom properties). Scoped omdat machine-geconverteerde componenten + om style leakage te voorkomen, en omdat het bouwpakket al gewone CSS + per component leverde: een utility + framework had een rewrite plus een extra dependency gekost. De + tokens houden het thema op 1 plek, dus het bekende scoped-CSS risico + (waarden die per component uiteenlopen) is afgedekt. + +Wat ik heb laten vallen of uitgesteld: + +- Een lijst met eerdere chats. Gesprekken leven bewust alleen client-side + en de server bewaart niets; een history-lijst kan later contract-schoon + via localStorage, zonder server-state. Potentiele extra als er tijd + over is, geen onderdeel van de kern. diff --git a/frontend/index.html b/frontend/index.html index 0ec46d0..624cf41 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,6 +4,7 @@ + discovery-by-llm diff --git a/frontend/public/favicon.svg b/frontend/public/favicon.svg index 6893eb1..3ec7371 100644 --- a/frontend/public/favicon.svg +++ b/frontend/public/favicon.svg @@ -1 +1,5 @@ - \ No newline at end of file + + + + d + diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 982c73d..c38c1d3 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,8 +1,7 @@ - + diff --git a/frontend/src/components/AppHeader.vue b/frontend/src/components/AppHeader.vue new file mode 100644 index 0000000..58444a4 --- /dev/null +++ b/frontend/src/components/AppHeader.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/frontend/src/components/AssistantMessage.vue b/frontend/src/components/AssistantMessage.vue new file mode 100644 index 0000000..1120133 --- /dev/null +++ b/frontend/src/components/AssistantMessage.vue @@ -0,0 +1,132 @@ + + + + + diff --git a/frontend/src/components/AuthStatus.vue b/frontend/src/components/AuthStatus.vue new file mode 100644 index 0000000..70d2bbc --- /dev/null +++ b/frontend/src/components/AuthStatus.vue @@ -0,0 +1,128 @@ + + + + + diff --git a/frontend/src/components/ChatView.vue b/frontend/src/components/ChatView.vue new file mode 100644 index 0000000..28eac2e --- /dev/null +++ b/frontend/src/components/ChatView.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/frontend/src/components/DevPanel.vue b/frontend/src/components/DevPanel.vue new file mode 100644 index 0000000..a15afd0 --- /dev/null +++ b/frontend/src/components/DevPanel.vue @@ -0,0 +1,285 @@ + + + + + diff --git a/frontend/src/components/EmptyResults.vue b/frontend/src/components/EmptyResults.vue new file mode 100644 index 0000000..a46ef54 --- /dev/null +++ b/frontend/src/components/EmptyResults.vue @@ -0,0 +1,28 @@ + + + diff --git a/frontend/src/components/EmptyState.vue b/frontend/src/components/EmptyState.vue new file mode 100644 index 0000000..a16e32a --- /dev/null +++ b/frontend/src/components/EmptyState.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/frontend/src/components/MessageInput.vue b/frontend/src/components/MessageInput.vue new file mode 100644 index 0000000..f44c61b --- /dev/null +++ b/frontend/src/components/MessageInput.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/frontend/src/components/MessageList.vue b/frontend/src/components/MessageList.vue new file mode 100644 index 0000000..e52a7cf --- /dev/null +++ b/frontend/src/components/MessageList.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/frontend/src/components/ModeBanner.vue b/frontend/src/components/ModeBanner.vue new file mode 100644 index 0000000..4b79150 --- /dev/null +++ b/frontend/src/components/ModeBanner.vue @@ -0,0 +1,36 @@ + + + diff --git a/frontend/src/components/PlaylistError.vue b/frontend/src/components/PlaylistError.vue new file mode 100644 index 0000000..ea5829a --- /dev/null +++ b/frontend/src/components/PlaylistError.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/frontend/src/components/PlaylistSaved.vue b/frontend/src/components/PlaylistSaved.vue new file mode 100644 index 0000000..cfe49ec --- /dev/null +++ b/frontend/src/components/PlaylistSaved.vue @@ -0,0 +1,64 @@ + + + + + diff --git a/frontend/src/components/RequestMetadata.vue b/frontend/src/components/RequestMetadata.vue new file mode 100644 index 0000000..1ea7397 --- /dev/null +++ b/frontend/src/components/RequestMetadata.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/frontend/src/components/ResultActions.vue b/frontend/src/components/ResultActions.vue new file mode 100644 index 0000000..f8e5209 --- /dev/null +++ b/frontend/src/components/ResultActions.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/frontend/src/components/ResultSet.vue b/frontend/src/components/ResultSet.vue new file mode 100644 index 0000000..42f7c31 --- /dev/null +++ b/frontend/src/components/ResultSet.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/frontend/src/components/StreamError.vue b/frontend/src/components/StreamError.vue new file mode 100644 index 0000000..fa27e79 --- /dev/null +++ b/frontend/src/components/StreamError.vue @@ -0,0 +1,37 @@ + + + + + diff --git a/frontend/src/components/StreamWarning.vue b/frontend/src/components/StreamWarning.vue new file mode 100644 index 0000000..4fec607 --- /dev/null +++ b/frontend/src/components/StreamWarning.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/frontend/src/components/SuggestionChips.vue b/frontend/src/components/SuggestionChips.vue new file mode 100644 index 0000000..3252a6b --- /dev/null +++ b/frontend/src/components/SuggestionChips.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/frontend/src/components/ThinkingIndicator.vue b/frontend/src/components/ThinkingIndicator.vue new file mode 100644 index 0000000..fd4c87c --- /dev/null +++ b/frontend/src/components/ThinkingIndicator.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/frontend/src/components/TrackCard.vue b/frontend/src/components/TrackCard.vue new file mode 100644 index 0000000..52287b6 --- /dev/null +++ b/frontend/src/components/TrackCard.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/frontend/src/components/UserMessage.vue b/frontend/src/components/UserMessage.vue new file mode 100644 index 0000000..c04cc0a --- /dev/null +++ b/frontend/src/components/UserMessage.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/frontend/src/lib/suggestions.ts b/frontend/src/lib/suggestions.ts new file mode 100644 index 0000000..2a5ef6d --- /dev/null +++ b/frontend/src/lib/suggestions.ts @@ -0,0 +1,9 @@ +export const DISCOVERY_SUGGESTIONS = [ + 'Focus while coding', + 'Energy for the gym', + 'Dutch-language and relaxed', + '90s nostalgia', + 'Surprise me with something new', + 'Rainy Sunday', + 'Background for dinner', +] as const diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index bbcf80c..d5ef513 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,7 +1,12 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' -// https://vite.dev/config/ export default defineConfig({ plugins: [vue()], + server: { + proxy: { + '/api': 'http://127.0.0.1:8888', + '/callback': 'http://127.0.0.1:8888', + }, + }, })