Severity: Low — a bundle of small, independent fixes.
- Unhandled JSON.parse on malformed body —
feedback/route.ts:5 and error/route.ts:5 call await request.json() outside try/catch → unhandled 500 instead of 400 on a non-JSON body. (The arrest-calculator route does this correctly and is a good model.)
- Discord field overflow drops large error reports —
error/route.ts:22-27: a big error/componentStack exceeds Discords 1024-char field limit → 400 → the client error is lost. Truncate to ~1000 chars.
[slug] route weak validation — paperwork-generators/[slug]/route.ts: formType cast without an allowlist; formId/groupId may contain /; the slug path segment is parsed but unused. Restrict to [A-Za-z0-9_-]+.
setFormData merges instead of replaces — paperwork-store.ts:48-53: stale top-level keys from an earlier submit can survive into a later render. onSubmit already assembles the full payload, so replace.
- Analytics opt-out needs a reload —
matomo.tsx:14-32: toggling the Privacy switch does not stop the already-initialized tracker until a full reload. Subscribe to the store and call Matomo optUserOut/forgetUserOptOut reactively.
- Typo classname —
log-parser-page.tsx:147: "... cursor pointer" should be cursor-pointer (the pointer cursor never applies).
Filed from a code audit of the current master. Line numbers are approximate.
Severity: Low — a bundle of small, independent fixes.
feedback/route.ts:5anderror/route.ts:5callawait request.json()outside try/catch → unhandled 500 instead of 400 on a non-JSON body. (Thearrest-calculatorroute does this correctly and is a good model.)error/route.ts:22-27: a bigerror/componentStackexceeds Discords 1024-char field limit → 400 → the client error is lost. Truncate to ~1000 chars.[slug]route weak validation —paperwork-generators/[slug]/route.ts:formTypecast without an allowlist;formId/groupIdmay contain/; theslugpath segment is parsed but unused. Restrict to[A-Za-z0-9_-]+.setFormDatamerges instead of replaces —paperwork-store.ts:48-53: stale top-level keys from an earlier submit can survive into a later render.onSubmitalready assembles the full payload, so replace.matomo.tsx:14-32: toggling the Privacy switch does not stop the already-initialized tracker until a full reload. Subscribe to the store and call MatomooptUserOut/forgetUserOptOutreactively.log-parser-page.tsx:147:"... cursor pointer"should becursor-pointer(the pointer cursor never applies).Filed from a code audit of the current
master. Line numbers are approximate.