feat: idea-chat-channel — Chat-tab vervangt Timeline (M17, PBI-123) #93

Merged
janpeter merged 22 commits from feat/idea-chat-channel into main 2026-07-04 10:38:26 +02:00
Owner

Fase 2 (web) van het idea-chat-channel — sprint S-2026-07-03-idea-chat, PBI-123, stories ST-1454/1455/1456. Upstream gemerged: scrum4me-shared #23 + #25, scrum4me-mcp #60 (mcp-stable bijgewerkt).

Wat: elk idee krijgt één chat-channel dat de Timeline-tab vervangt (desktop + mobiel): user/agent-berichten, grill-resultaten als volledige markdown, IdeaLog-audit als system-projectie, ClaudeQuestion-kaarten met AnswerForm, legacy PLAN_CHAT read-only.

  • Migrations: enum-add apart (Postgres-regel) + idea_chat_messages/cutoff-kolommen/NOTIFY-trigger/belkaart-trigger/partial-unique-vangrail — al toegepast op de server-Postgres; Neon vereist nog handmatig prisma migrate deploy met NEON_URL
  • sendIdeaChatMessage: per-idea FOR UPDATE-lock, coalescing, P2002→409, product-loos = persist zonder job
  • Status-neutrale cancel + restart-weigering (retry = nieuw bericht)
  • GET /api/ideas/[id]/messages: composiet-cursor, delta + ouder-paginering
  • SSE-matrix: idea_message-entity + IDEA_CHAT-guards (solo-leak gedicht); dirty-teller-store, geen router.refresh voor berichten
  • Belkaart "Claude heeft geantwoord"; PLAN_CHAT-afbouw stap 1; JobKindConfig-seed; ADR-0013

Docs in deze PR: spec (rev4) + plan (rev3, ook als ProductDoc plans/m17-idea-chat-channel) + ADR-0013 — beide codex-akkoord via s4m-queue-reviews.

Verify: 194 files / 1566 tests groen; tsc schoon. Handmatige e2e met een echte worker (bericht→antwoord→doc-update→belkaart, coalescing, cancel, demo, mobiel) = DoD vóór sprint-close.

🤖 Generated with Claude Code

Fase 2 (web) van het idea-chat-channel — sprint S-2026-07-03-idea-chat, PBI-123, stories ST-1454/1455/1456. Upstream gemerged: scrum4me-shared #23 + #25, scrum4me-mcp #60 (mcp-stable bijgewerkt). **Wat:** elk idee krijgt één chat-channel dat de Timeline-tab vervangt (desktop + mobiel): user/agent-berichten, grill-resultaten als volledige markdown, IdeaLog-audit als system-projectie, ClaudeQuestion-kaarten met AnswerForm, legacy PLAN_CHAT read-only. - Migrations: enum-add apart (Postgres-regel) + `idea_chat_messages`/cutoff-kolommen/NOTIFY-trigger/belkaart-trigger/partial-unique-vangrail — **al toegepast op de server-Postgres; Neon vereist nog handmatig `prisma migrate deploy` met NEON_URL** - `sendIdeaChatMessage`: per-idea `FOR UPDATE`-lock, coalescing, P2002→409, product-loos = persist zonder job - Status-neutrale cancel + restart-weigering (retry = nieuw bericht) - `GET /api/ideas/[id]/messages`: composiet-cursor, delta + ouder-paginering - SSE-matrix: `idea_message`-entity + IDEA_CHAT-guards (solo-leak gedicht); dirty-teller-store, geen router.refresh voor berichten - Belkaart "Claude heeft geantwoord"; PLAN_CHAT-afbouw stap 1; JobKindConfig-seed; ADR-0013 **Docs in deze PR:** spec (rev4) + plan (rev3, ook als ProductDoc plans/m17-idea-chat-channel) + ADR-0013 — beide codex-akkoord via s4m-queue-reviews. Verify: 194 files / 1566 tests groen; tsc schoon. Handmatige e2e met een echte worker (bericht→antwoord→doc-update→belkaart, coalescing, cancel, demo, mobiel) = DoD vóór sprint-close. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- coalescing: per-idea lock (FOR UPDATE) in action én MCP + partial unique index als vangrail
- job-events: IdeaLog canoniek, renderer projecteert; JOB_EVENT uit IdeaChatMessageKind
- SSE: expliciete route/client-matrix (incl. solo-leak IDEA_CHAT)
- PLAN_CHAT: cutover in 2 stappen met drain + legacy pending-rendering

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- realtime-eigenaarschap expliciet: globale hook bumpt alleen dirty-teller in
  nieuwe idea-chat-store; chat-component bezit lijst+cursor en delta-fetcht
- IDEA_CHAT-cancel: status-neutrale tak in cancelIdeaJobAction, geen
  coalescing bij CANCELLED; retry buiten scope (nieuw bericht = retry)
- MCP: IDEA_CHAT expliciet in claimbare kinds van wait_for_job-claim-query

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- context-cutoff wordt bij claim gepersisteerd op ClaudeJob
  (chat_cutoff_message_id/chat_cutoff_at); update_job_status leest
  server-side, MCP autoritatief; NULL-vangnet via job.created_at
- restartClaudeJobAction weigert IDEA_CHAT (422) + knop verborgen;
  voorkomt tweede retry-semantiek buiten lock/cutoff om
- cutoff-tests (done/failed, advance) in §10; kolommen in §8 shared-stap

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Task 7: claim-payload-historie hard begrensd op de gepersisteerde cutoff
  (post-claim bericht niet dubbel: niet in payload, wel follow-up)
- Task 12: code-fence gesloten, MergeInput geexporteerd/geimporteerd,
  composiet-cursor als DB-predicaat in alle vier de queries + tsc-check
- Task 13: product_id gelezen onder de per-idea lock (stale-state race)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Twee migrations: enum-add apart van gebruik (Postgres-regel), daarna tabel,
chat_cutoff-kolommen, partial unique index, NOTIFY-trigger (user_id via join
op ideas, geen berichttekst) en claude_jobs_idea_ready-uitbreiding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Plus IDEE-CHAT-labels in de jobs-KIND_LABELS-records (nieuw enum-lid) en
worktree-fixes (@prisma/client-kopie, manual.generated).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- hook: idea_message → alleen dirty-teller; IDEA_CHAT done/failed/cancelled →
  bump i.p.v. router.refresh; grill/plan-refresh ongewijzigd
- notifications-route: kind-guard + user-scoped idea_message-branch
- solo-route: IDEA_CHAT + idea_message expliciet geweerd (leak-fix)
- jobs-route: entity-payloads expliciet geweerd

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- AnswerForm verplaatst naar components/ideas/answer-form.tsx (hergebruik)
- IdeaChatItem: rendering per ChannelItem (bubbels, system-projectie,
  GRILL_RESULT-details, AnswerForm, legacy-markering)
- IdeaChat: lijst+cursor-eigenaarschap, dirty-bump→delta-fetch, ouder-laden,
  status-gating, pending-chip, worker-hint, demo-laag
- idea-detail-layout: chat-tab i.p.v. timeline (count-badge bewust weg)
- page.tsx: ?tab=timeline-redirect + fetchChannelItems i.p.v. 3 losse queries

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
idea-timeline.tsx verwijderd (laatste consumer weg); mobiele page gebruikt
fetchChannelItems; mobile-tests bijgewerkt naar het ChannelItem-contract.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- user-chat-input.tsx en actions/user-questions.ts verwijderd (geen nieuwe
  UserQuestion-writes; tabel + enum-lid blijven read-only legacy)
- seed-row fromKindDefault('IDEA_CHAT', DANGER_FULL_ACCESS) + seed-tests (10 kinds)
- submodule-bump a7c7887: update_idea toegevoegd aan de shared tool-registry
  (bestond als MCP-tool, ontbrak in de master-lijst — shared PR #25)
- rij ge-upsert in job_kind_config (sonnet-4-6/15 turns/11 tools)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
docs(adr): ADR-0013 chat-channel per idee — herbeslissing M12-keuze 10 (M17)
All checks were successful
CI / Lint, Typecheck, Test & Build (pull_request) Successful in 3m39s
CI / Deploy Manual (workflow_dispatch) (pull_request) Has been skipped
CI / Detect deploy-relevant changes (pull_request) Has been skipped
CI / Deploy Preview (PR) (pull_request) Has been skipped
CI / Deploy Production (main) (pull_request) Has been skipped
a723f00aff
Plus opruiming: ongebruikte IdeaLog/IdeaQuestion/IdeaUserQuestionDto-interfaces
uit idea-detail-layout (props-swap-restant).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
janpeter/Scrum4Me!93
No description provided.