From ac44bab8e60babc32bb04b1f4141b75f3f1bb58a Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 23 Apr 2026 09:52:22 +0200 Subject: [PATCH] Update documentation and refactor useAutoSave hook Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Docs/Tasks.md | 24 ------------------------ frontend/src/hooks/useAutoSave.ts | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/Docs/Tasks.md b/Docs/Tasks.md index dc20845..4e617c8 100644 --- a/Docs/Tasks.md +++ b/Docs/Tasks.md @@ -1,27 +1,3 @@ -### TASK-QUALITY-03 — `useHistory` Object Identity Dependency Footgun - -**Where found** -`frontend/src/hooks/useHistory.ts`. The hook accepts a `query` object as a parameter and lists it directly in the `useCallback` dependency array for the internal `load` function. If a caller passes an inline object literal on every render (e.g. `useHistory({ page: 1, jail: selectedJail })`), `query` is a new reference every render, causing a new `load` callback, which causes `useEffect([load])` to fire, triggering an infinite re-fetch. - -**Goal** -Document this constraint prominently in the hook's JSDoc and in `Docs/Web-Development.md`. Alternatively, change the hook to accept individual primitive parameters instead of an object, eliminating the reference-stability requirement: -```ts -export function useHistory(page: number, pageSize: number, jail?: string, ...): UseHistoryResult -``` -This is the safest fix because it makes incorrect usage a compile-time error. - -**Possible traps and issues** -- Changing the signature is a breaking change for all callers. Audit all call sites before changing the signature. -- The interim documentation fix (a clear JSDoc warning) is a lower-risk option if refactoring callers is out of scope. - -**Docs changes needed** -Add a note to `Docs/Web-Development.md`: "Hooks that accept objects as parameters must either destructure to primitives internally or require the caller to provide a stable reference (e.g. via `useMemo`)." - -**Why this is needed** -This is a silent footgun. The hook works correctly in all current call sites only because callers happen to use `useMemo` or stable state references. A future caller passing an inline literal will introduce an infinite re-fetch with no obvious diagnostic. - ---- - ### TASK-QUALITY-04 — `pendingSaveRef as boolean` Redundant Cast in `useAutoSave` **Where found** diff --git a/frontend/src/hooks/useAutoSave.ts b/frontend/src/hooks/useAutoSave.ts index 8c849f3..5c379bb 100644 --- a/frontend/src/hooks/useAutoSave.ts +++ b/frontend/src/hooks/useAutoSave.ts @@ -74,7 +74,7 @@ export function useAutoSave( isSavingRef.current = false; // If a pending save was queued while we were saving, run it now. - if (pendingSaveRef.current as boolean) { + if (pendingSaveRef.current) { pendingSaveRef.current = false; await performSave(latestValueRef.current); }