Sprint: Chat is klaar #52

Merged
janpeter merged 15 commits from feat/sprint-x5bootxw into main 2026-05-28 22:59:25 +02:00
Owner

Sprint 'Chat is klaar' (PBI-113) volledig geïmplementeerd in 17 taken over 4 stories.

ST-1434 (DB-laag): IdeaNotification model + back-relaties in canonical shared schema; migration met CREATE TABLE, UNIQUE/composite indexes, CASCADE FKs; NOTIFY-trigger (entity='idea_ready' op scrum4me_changes); claude_jobs DONE-trigger die kaarten auto-insert bij IDEA_GRILL/IDEA_MAKE_PLAN.

ST-1435 (Realtime): 'ready'-variant toegevoegd aan NotificationQuestion union; fetchUnreadIdeaReadyCards server-helper; SSE-route forwardet idea_ready payloads user-scoped; bridge laadt kaarten in initial state; client-hook reconnect/remove-logica bij INSERT/UPDATE; solo-route filtert idea_ready.

ST-1436 (UI): dismissIdeaNotificationAction (auth+demo+atomic updateMany+revalidatePath); ReadyCard sub-component in notifications-sheet met job_kind-label, Q&A-preview, Gelezen-knop (optimistic dismiss via useTransition), DemoTooltip, Link naar /ideas/${idea_id}; answer-modal guard voor kind==='ready'; bell forYouCount telt ready-kaarten.

ST-1437 (Tests+verificatie): unit-tests notifications-store ready-variant (5 tests); unit-tests dismissIdeaNotificationAction (6 tests); typecheck + npm run verify + npm run build allemaal groen.


Draft PR voor sprint-batch cmpps80380019vp7rx5bootxw (single-session). Wordt ready-for-review zodra alle tasks DONE zijn.

Sprint 'Chat is klaar' (PBI-113) volledig geïmplementeerd in 17 taken over 4 stories. ST-1434 (DB-laag): IdeaNotification model + back-relaties in canonical shared schema; migration met CREATE TABLE, UNIQUE/composite indexes, CASCADE FKs; NOTIFY-trigger (entity='idea_ready' op scrum4me_changes); claude_jobs DONE-trigger die kaarten auto-insert bij IDEA_GRILL/IDEA_MAKE_PLAN. ST-1435 (Realtime): 'ready'-variant toegevoegd aan NotificationQuestion union; fetchUnreadIdeaReadyCards server-helper; SSE-route forwardet idea_ready payloads user-scoped; bridge laadt kaarten in initial state; client-hook reconnect/remove-logica bij INSERT/UPDATE; solo-route filtert idea_ready. ST-1436 (UI): dismissIdeaNotificationAction (auth+demo+atomic updateMany+revalidatePath); ReadyCard sub-component in notifications-sheet met job_kind-label, Q&A-preview, Gelezen-knop (optimistic dismiss via useTransition), DemoTooltip, Link naar /ideas/${idea_id}; answer-modal guard voor kind==='ready'; bell forYouCount telt ready-kaarten. ST-1437 (Tests+verificatie): unit-tests notifications-store ready-variant (5 tests); unit-tests dismissIdeaNotificationAction (6 tests); typecheck + npm run verify + npm run build allemaal groen. --- *Draft PR voor sprint-batch `cmpps80380019vp7rx5bootxw` (single-session). Wordt ready-for-review zodra alle tasks DONE zijn.*
Voeg IdeaNotification toe aan prisma/schema.prisma met velden id, idea_id,
user_id, product_id, job_id (unique), kind (ClaudeJobKind), read_at en
created_at. Relaties naar Idea, User en ClaudeJob met onDelete: Cascade.
Index op [user_id, read_at]. Back-relaties toegevoegd op Idea.notifications,
User.idea_notifications en ClaudeJob.idea_notification.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CreateTable idea_notifications with all columns; UNIQUE INDEX on job_id;
composite INDEX on (user_id, read_at); CASCADE FKs for idea_id, user_id, job_id.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CREATE OR REPLACE FUNCTION notify_idea_notification_change() emits
jsonb payload on scrum4me_changes channel with entity='idea_ready',
op, id, idea_id, user_id, product_id, kind, read fields.
Trigger fires AFTER INSERT OR UPDATE on idea_notifications.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Appends insert_idea_ready_card() function and claude_jobs_idea_ready
trigger to the add_idea_notifications migration. On status transition to
DONE for IDEA_GRILL/IDEA_MAKE_PLAN jobs with an idea_id, a card is
auto-inserted into idea_notifications (ON CONFLICT DO NOTHING for
idempotency).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the 'ready' kind to the store's NotificationQuestion union type for
completed idea-job notifications (IDEA_GRILL/IDEA_MAKE_PLAN). Updates
forYouCount selector to include 'ready' items, and fixes type narrowing
in bell/sheet/modal components so TypeScript compilation stays clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Exports async fetchUnreadIdeaReadyCards(userId) that queries IdeaNotification
(unread, desc) and enriches each card with answered Q&A from ClaudeQuestion,
capping at 3 pairs while exposing qa_total for "+N meer" UI rendering.
Maps to the ReadyCard shape from notifications-store.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add IdeaReadyPayload interface + isIdeaReadyPayload type-guard
- Handle idea_ready notifications user-scoped (like idea-jobs: user_id check)
- Fetch fetchUnreadIdeaReadyCards(userId) in parallel with initial-state queries
- Spread ideaReadyCards into stateQuestions (sorted by created_at desc)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Import fetchUnreadIdeaReadyCards and concat its results into the initial
array alongside story- and idea-questions, sorted on created_at desc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- use-notifications-realtime: IdeaReadyPayload interface + isIdeaReadyPayload
  type-guard; op=I/!read → reconnect, read=true → remove from bell
- solo/route: extend EntityPayload entity union + shouldEmit filter for idea_ready

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Atomic updateMany scoped to user_id + read_at IS NULL; revalidatePath layout for SSR badge update. Returns 404 when not found or already read, 401/403 for auth/demo guards.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Renders 'ready' notifications (IDEA_GRILL / IDEA_MAKE_PLAN) as a dedicated
card with label badge, idea code+title, description, up to 3 Q&A pairs with
overflow count, a link to /ideas/:id, and an optimistic "Gelezen" dismiss
button (disabled + DemoTooltip in demo mode). Ready cards do not open
AnswerModal. Uses MD3 secondary-container tokens; data-debug-id attributes
added throughout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Voegt __tests__/stores/notifications-store.test.ts toe met fixture voor
de 'ready'-NotificationQuestion en assertions op openCount, forYouCount
en remove.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers: 401 unauthenticated, 403 demo block, user_id scope in updateMany where,
404 on count !== 1 (not found / already read), and happy-path sets read_at + revalidatePath.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Added IdeaNotification model + back-relations (User, Idea, ClaudeJob)
to vendor/scrum4me-shared/prisma/schema.prisma so prebuild regenerates
prisma/schema.prisma correctly with the new model.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
refactor(ideas): simplify fetchUnreadIdeaReadyCards
Some checks failed
CI / Detect deploy-relevant changes (pull_request) Has been cancelled
CI / Deploy Preview (PR) (pull_request) Has been cancelled
CI / Deploy Production (main) (pull_request) Has been cancelled
CI / Deploy Manual (workflow_dispatch) (pull_request) Has been cancelled
CI / Lint, Typecheck, Test & Build (pull_request) Has been cancelled
e5304b95d3
More concise form: inline select options, use satisfies for type safety.
Logic identical to original implementation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
janpeter changed title from WIP: Sprint: Chat is klaar to Sprint: Chat is klaar 2026-05-28 21:13:52 +02:00
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!52
No description provided.