Scrum4Me/docs/specs/dialogs/answer-modal.md
Janpeter Visser 00af559726
Sprint: ideeen aanpassen (#211)
* feat(user-settings): voeg IdeasListPrefs schema toe met filterStatuses

Nieuw IdeasListPrefs-subschema met filterStatuses (array van IdeaStatusApi-waarden),
ingehangen als views.ideasList in ViewsPrefs. Testdekking voor geldig, ongeldig en
leeg filterStatuses.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: extraheer MultiFilterPills naar backlog-filter-popover

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ideas): voeg IdeasFilterPopover component toe

Nieuwe client-component met multi-select statusfilter popover voor het
Ideeënscherm; hergebruikt MultiFilterPills uit backlog-filter-popover.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ideas): vervang inline statuschips door IdeasFilterPopover met user-settings persistentie

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(ideas): voeg componenttests toe voor IdeasFilterPopover en persistentie

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ideas): voeg activeProductId-prop toe aan IdeaList

IdeaListProps uitgebreid met activeProductId: string | null.
Create-form initialiseert en reset naar het actieve product na aanmaken.
Tests en page.tsx bijgewerkt (page.tsx krijgt echte waarde in volgende taak).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ideas): resolve active_product_id en geef door aan IdeaList

Haalt active_product_id op via prisma.user.findUnique en resolveert
het tegen de al opgehaalde toegankelijke productenlijst (AC4). Geeft
het resultaat als prop door aan IdeaList in plaats van hardcoded null.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ideas): stuur activeProductId mee bij snel idee aanmaken

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(ideas): voeg component-tests toe voor activeProductId-voorvulling

AC1: "Nieuw idee"-select voorgevuld met activeProductId
AC2: "Nieuw idee"-select leeg bij activeProductId=null
AC3: "Snel idee" stuurt product_id=activeProductId mee bij createIdeaAction

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(notifications): toon textarea altijd in answer-modal naast opties

Vervang opties-XOR-textarea door twee onafhankelijke blokken: opties
alleen wanneer aanwezig, vrij tekstveld altijd zichtbaar. Bij opties
een visuele scheiding (border-t) en label 'Of typ een eigen antwoord'.
Verstuur-knop nu altijd in footer zichtbaar (was verborgen bij opties).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(notifications): gebruik question.options?.length als conditie

Gebruik de kortere optional chaining variant consistent, conform plan.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(notifications): voeg component-tests toe voor AnswerModal

Dekt: optieknoppen + textarea + Verstuur zichtbaar met opties,
submit via optieknop, submit via vrij tekstveld, disabled Verstuur
bij leeg veld, en demo-modus (textarea + Verstuur disabled).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(notifications): werk answer-modal spec bij voor vrije tekstveld naast opties

Beschrijft dat textarea + Verstuur altijd zichtbaar zijn in multiple-choice
mode. Corrigeert de Cmd/Ctrl+Enter-bullet: shortcut werkt nu ook daar.
Bijgewerkt naar 2026-05-15.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 07:28:36 +02:00

2.9 KiB

title status audience language last_updated
AnswerModal Profiel active
ai-agent
contributor
nl 2026-05-15

AnswerModal Profiel

Volgt docs/patterns/dialog.md. Beschrijft alleen de Q&A-specifieke afwijkingen.

Doel

Een Claude-agent vraagt tijdens een lopende job een verduidelijking aan de gebruiker. De vraag verschijnt als notification (bell + SSE event). Klik op de notification opent deze dialog waarin de gebruiker antwoordt — vrij tekst (max ANSWER_MAX_CHARS) of een keuze uit options als die meegegeven is.

Velden

Veld Type Mode Validatie
answer string both min 1, max ANSWER_MAX_CHARS (4000), trim

questionId komt uit de prop question.id, niet uit het formulier.

Schema

lib/schemas/question-answer.ts:

  • answerQuestionSchema — gedeeld door form + answerQuestion action
  • ANSWER_MAX_CHARS constant — gebruikt door textarea + char-counter

URL- of state-pattern

  • Gekozen: state-basedquestion: NotificationQuestion | null-prop uit notifications-sheet.

Server action

  • answerQuestion(questionId, answer) in actions/questions.ts
  • Result-shape: { ok: true } | { ok: false; error: string }
  • Demo-policy: session.isDemo-check in actie blokkeert demo-writes (laag 2). Laag 3 wordt verzorgd door <DemoTooltip> rond submit-knop en disabled-state op de textarea.
  • Atomic transition met updateMany voorkomt double-submit races.

Layout

Gebruikt entityDialogContentClasses (§4 spec). Body bevat naast de textarea ook de gestelde vraag (read-only block) en een link naar de bijbehorende sprint. Geen klassieke form-tag — de Textarea is een controlled component.

Speciale gedragingen

Multiple-choice mode

Als question.options niet leeg is, worden de opties getoond als een lijst van knoppen. Klikken op een knop submit direct met die waarde. Het vrije tekstveld en de Verstuur-knop blijven altijd zichtbaar — ook in multiple-choice mode. Zo kan de gebruiker naast de vaste opties ook een eigen antwoord typen en versturen.

Optimistic remove

Na succesvolle submit wordt de vraag direct uit useNotificationsStore verwijderd. De SSE-event komt later met dezelfde verwijdering — voorkomt extra render.

Dirty-tracking

Single-field form: dirty = answer.trim().length > 0. Esc/backdrop/Cancel met dirty-state opent de standaard guard.

Foutcodes

Action geeft alleen { ok, error: string } terug — geen 422-fieldErrors omdat het een single-field form is. Errors worden via toast getoond. Validatie (min 1, max 4000) wordt UI-side voorkomen via maxLength + submit-disable.

Bewust NIET in v1

  • Markdown rendering — antwoord wordt als plain text doorgegeven; Claude leest 'm direct als context.
  • Cmd/Ctrl+Enter shortcut — werkt via useDialogSubmitShortcut in zowel textarea-mode als multiple-choice mode (het vrije tekstveld is altijd aanwezig).
  • Bulk-answer — één vraag tegelijk per dialog.