# Patroon: Float sort_order (drag-and-drop volgorde) ## Berekening bij tussenvoeging ```ts function getSortOrder(before: number | null, after: number | null): number { if (before === null && after === null) return 1.0 if (before === null) return after! / 2 if (after === null) return before + 1.0 return (before + after) / 2 } ``` ## Herindexeer als precisie opraakt Trigger wanneer het kleinste verschil tussen twee opeenvolgende items < 0.001 is. ```ts async function reindexIfNeeded(items: { id: string; sort_order: number }[]) { const minGap = Math.min(...items.slice(1).map((item, i) => item.sort_order - items[i].sort_order )) if (minGap < 0.001) { await Promise.all(items.map((item, i) => prisma.pbi.update({ where: { id: item.id }, data: { sort_order: i + 1.0 } }) )) } } ``` ## Reorder Server Actions Een drag-and-drop reorder stuurt altijd client-controlled ID-lijsten naar de server. Behandel die lijst als onbetrouwbaar. - Weiger dubbele IDs. - Haal alle IDs op met de parent-scope, bijvoorbeeld `product_id`, `pbi_id`, `sprint_id` of `story_id`. - Weiger de operatie als het aantal gevonden records niet exact gelijk is aan het aantal aangeleverde IDs. - Update pas daarna `sort_order` in een transactie. - Gebruik bij priority changes dezelfde parent uit de database, niet een los meegegeven `productId`.