Scrum4Me/components/backlog/url-task-sync.tsx
Madhura68 9c769523cf feat(PBI-74): race-safe loaders + restore-hints + URL-prioriteit (Story 4)
- T-856: activeRequestId-guard zat al in store.ts uit Story 1; bevestigd door
  de race-safety test (in-flight ensurePbiLoaded mag niet overschrijven).
- T-857: restore-hint flow toegevoegd in setActiveProduct/setActivePbi/
  setActiveStory. Async chain: await ensureXxxLoaded → guard check →
  readHints → valideer hint via entities.byId → setActiveYyy(hint).
  Geen setTimeout-trick — chain is alleen await-based.
- T-858: writeProductHint/writePbiHint/writeStoryHint/writeTaskHint
  aangeroepen direct na set(...) zodat de hint-persistentie altijd
  consistent is met de in-store selectie.
- T-859: nieuwe components/backlog/url-task-sync.tsx — leest
  ?editTask=<id> uit useSearchParams, schrijft de hint en roept
  setActiveTask aan zodat de URL wint boven een eerder gepersisteerde
  task-hint. Gemount in beide product-pages (desktop + mobile) binnen
  BacklogHydrationWrapper.
- T-860: 6 nieuwe vitest-cases — 4 voor hint-persist per setter, 2 voor de
  restore-flow chain (hint die niet in entities zit wordt genegeerd; hint
  die wel in entities zit wordt toegepast). Bestaande race-safety test
  blijft groen.

Verify: lint+typecheck clean, 642/642 tests groen.

Refs: PBI-74, ST-1321, T-856..T-860

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 01:17:22 +02:00

32 lines
1.1 KiB
TypeScript

'use client'
// PBI-74 / T-859: URL-prioriteit boven restore-hint.
//
// Als de route `?editTask=<id>` draagt, wint dat boven de localStorage-hint
// die de restore-flow normaal zou toepassen. We schrijven de URL-id direct
// naar de task-hint en roepen setActiveTask aan; de restore-flow leest de
// task-hint pas na drie ensure*Loaded-awaits, dus onze schrijfactie wint
// in de praktijk altijd.
import { useEffect } from 'react'
import { useSearchParams } from 'next/navigation'
import { useProductWorkspaceStore } from '@/stores/product-workspace/store'
import { writeTaskHint } from '@/stores/product-workspace/restore'
export function UrlTaskSync() {
const searchParams = useSearchParams()
const editTask = searchParams.get('editTask')
useEffect(() => {
if (!editTask) return
const productId = useProductWorkspaceStore.getState().context.activeProduct?.id
if (productId) {
// Hint overschrijven zodat restore-flow's setActiveTask op deze id eindigt
// (mocht hij na onze directe call komen).
writeTaskHint(productId, editTask)
}
useProductWorkspaceStore.getState().setActiveTask(editTask)
}, [editTask])
return null
}