Follow-up items surfaced during code review. Not ship-blockers — captured here so they don't get lost.
From the /ship adversarial review of feat/silent-github-token-refresh (PR #176).
All items below are tracked as GitHub issues (#177-#187). Update issue status there; this file remains as the source narrative for context.
- Preserve
?queryand#hashon silent refresh redirect — #177 - Clear refresh attempt counter on
/login?error=token_refresh_failed— #178
- Multi-tab PKCE collision — #179
- 401 interceptor races freshly-set cookie — #180
- Race on rapid combobox open/close — #181
-
x-forwarded-forfirst-IP spoofing on Vercel — #182 - Server-side
attemptcap bypassed whensessionStorageunavailable — #183 - Error message reflection in
/login?error=...— #184
- Dedicated unit tests for
sanitizeNextPath— #185 - Dedicated unit tests for
getForwardedClientIp— #186
- 30-day provider token cookie TTL — risk re-confirm — #187
From the /review of perf/board-read-embed (the /board/[id] single-embed read path).
All items are P3, non-blocking for that PR: the refactor preserves behavior, and the
items below are either pre-existing conditions surfaced by the adversarial review or
explicit risk acceptances. Captured here; the P3 items below remain open. The T5 cleanup
is done as of v0.3.1.3 — the dead getStatusLists / getRepoCards / getBoardData
(board.ts) and getCommentsForCards (project-info.ts) read-path functions are removed
(static analysis proved zero callers post-embed-migration, so the prod-confirmation gate was
obviated). fetchBoardInitialData was already removed by the v0.3.1.0 embed migration.
-
getBoardBundleasync DB-contract tests — cover embed-error ⇒ throw (never a 404),nulldata ⇒null⇒notFound(), zero-column ⇒createDefaultStatusLists, and therepocard.length >= 1000truncation Sentry warning. Out of scope of the pureremapBoardEmbedunit suite (needs Supabase + PostgREST + RLS). v0.3.1.0: the malformed-id ⇒nullpath (404, never reaches Postgres) is now covered bysrc/tests/unit/lib/actions/board-data.test.ts; the Supabase-backed paths above remain. -
logBoardTimingflag tests — assert no-op whenBOARD_TIMING_LOGis unset and one structured line when set (the "1 line = deduped" dedup proof). v0.3.1.1: covered bysrc/tests/unit/lib/utils/board-timing.test.ts— flag off ⇒ no-op, flag on ⇒ exactly oneboard-timingline carrying the board id + every segment, plus a module-tag lock. The per-calltoHaveBeenCalledTimes(1)proves one line per call; the "1 line per request = React.cache dedup" property lives ingetBoardBundle, not this unit. - E2E
/board/[nonexistent-uuid]⇒ 404 — the not-found contract (.maybeSingle()null ⇒notFound()) now has direct E2E cover. v0.3.1.2:e2e/logged-in/board-not-found.spec.tsasserts the segment-local "Board not found" boundary renders for both a malformed board id (rejected byboardIdSchemabefore Postgres) and a well-formed but unseeded board UUID (.maybeSingle()null). Asserts page content, not HTTP status, since the App Router may stream a 200 beforenotFound()throws.
These conditions exist in
maintoday; they were surfaced — not introduced — by this PR's adversarial review. The single-embed refactor preserves the prior read behavior.
- >1000 cards/columns silently truncated at the PostgREST
db-max-rowscap — the oldgetRepoCards/getStatusListshad the same cap with no warning; this PR added a Sentry warning forrepocardonly. A partial board can undercount cards before a destructive column-delete (BoardPageClientcounts only loadedrepoCards). Needs hard-fail / exact count / pagination before mutation-capable UI. Also add astatuslistcap check. v0.3.1.0: the embed now ordersrepocardbyorderascending, so truncation drops the highest-order cards deterministically rather than an arbitrary subset; the silent undercount / hard-fail / pagination work above remains open. -
/board/[id]passes the fullboardrow (incl.user_id) to the client for public boards — pre-existing: the old page also usedselect('*')and passed the raw row. Public-board RLS lets any authenticated user read a public board by UUID, so consider strippinguser_id/owner-onlysettingson this path the waypublic-board.tsalready does.
-
generateMetadatashares the full bundle fetch (and may create default columns) — intentional:React.cachededups it with the page render, which is the whole point of eliminating the duplicate board fetch. Reverting to a name-only metadata query would re-introduce the second round-trip. Revisit only if metadata-only prefetch paths emerge.