'use client' import { useEffect, useRef } from 'react' import { useBacklogStore, type BacklogPbi, type BacklogStory, type BacklogTask } from '@/stores/backlog-store' import { useBacklogRealtime } from '@/lib/realtime/use-backlog-realtime' import { useProductWorkspaceStore } from '@/stores/product-workspace/store' import type { BacklogPbi as WorkspacePbi, BacklogStory as WorkspaceStory, BacklogTask as WorkspaceTask, ProductBacklogSnapshot, } from '@/stores/product-workspace/types' import { logWorkspaceFingerprint } from '@/lib/realtime/dev-workspace-fingerprint' interface InitialData { pbis: BacklogPbi[] storiesByPbi: Record tasksByStory: Record } interface BacklogHydrationWrapperProps { initialData: InitialData productId: string productName?: string children: React.ReactNode } function fingerprint(data: InitialData): string { const pbiPart = data.pbis.map((p) => `${p.id}:${p.status}:${p.priority}`).join(',') const storyPart = Object.entries(data.storiesByPbi) .flatMap(([, list]) => list.map((s) => `${s.id}:${s.status}:${s.sprint_id ?? 'null'}`)) .join(',') const taskPart = Object.entries(data.tasksByStory) .flatMap(([, list]) => list.map((t) => `${t.id}:${t.status}`)) .join(',') return `${pbiPart}|${storyPart}|${taskPart}` } // PBI-74 / T-844: dual-dispatch — naast de oude useBacklogStore vullen we nu // ook de nieuwe product-workspace-store. De oude store blijft tijdelijk // leidend voor componenten; in Story 3 verschuiven consumers één voor één. // De runtime-payload bevat sort_order op PBI/Story (Prisma schema), ook al // staat het niet op het oude InitialData type — daarom de cast hieronder. function toWorkspaceSnapshot( data: InitialData, productId: string, productName: string | undefined, ): ProductBacklogSnapshot { return { product: { id: productId, name: productName ?? '' }, pbis: data.pbis as unknown as WorkspacePbi[], storiesByPbi: data.storiesByPbi as unknown as Record, tasksByStory: data.tasksByStory as unknown as Record, } } export function BacklogHydrationWrapper({ initialData, productId, productName, children, }: BacklogHydrationWrapperProps) { const setInitialData = useBacklogStore((s) => s.setInitialData) const lastFingerprint = useRef('') useEffect(() => { const fp = fingerprint(initialData) if (fp !== lastFingerprint.current) { lastFingerprint.current = fp setInitialData(initialData) // Dual-dispatch: nieuwe workspace-store schaduwt mee. useProductWorkspaceStore .getState() .hydrateSnapshot(toWorkspaceSnapshot(initialData, productId, productName)) logWorkspaceFingerprint('hydrate') } }, [initialData, productId, productName, setInitialData]) useBacklogRealtime(productId) return <>{children} }