Skip to content

feat(api-client): add global 401/403/5xx interceptor + AuthExpiredListener#681

Open
jun261930-tech wants to merge 1 commit into
builderz-labs:mainfrom
jun261930-tech:feat/api-client-401-interceptor
Open

feat(api-client): add global 401/403/5xx interceptor + AuthExpiredListener#681
jun261930-tech wants to merge 1 commit into
builderz-labs:mainfrom
jun261930-tech:feat/api-client-401-interceptor

Conversation

@jun261930-tech
Copy link
Copy Markdown

Summary

Fixes the UX bug where expired sessions silently fail — API calls return 401 but users see no feedback and stay on the current page.

Changes

New files

  • src/lib/api-client.ts — typed fetch wrapper with global 401/403/5xx interception
  • src/lib/__tests__/api-client.test.ts — 8 vitest test cases covering all interception branches
  • src/components/auth-expired-listener.tsx — Client Component that listens for mc:auth-expired and redirects to /login?from=<current-path>

Modified files

  • src/app/layout.tsx — mounts <AuthExpiredListener /> at root layout
  • eslint.config.mjs — adds no-restricted-syntax warn rule for bare fetch('/api/...) calls (3 quote variants)

Verification

vitest: 8/8 PASS (2.5s)
typecheck: 0 errors
lint: 0 errors, 343 warnings (334 existing bare-fetch baselines)

Migration path

See PR-api-client.md in workspace for 3-phase incremental migration strategy.

Related

  • PLAN.md Phase 1 deliverable
  • Closes the auth-expired silent failure issue documented in SENIOR-CODE-REVIEW.md

P1 of MC code-quality plan (see PLAN.md / PR-api-client.md):

- src/lib/api-client.ts          (+120) ApiError + apiFetch<T> wrapper
- src/lib/__tests__/api-client.test.ts (+108) 8 vitest cases (200/401/403/500/network/loop/204/no-redirect)
- src/components/auth-expired-listener.tsx (+30) global mc:auth-expired -> /login redirect
- src/app/layout.tsx             (+2) register listener
- eslint.config.mjs              (+31) no-restricted-syntax warn for bare fetch('/api/...')

Quality gates passed:
- pnpm vitest run src/lib/__tests__/api-client.test.ts: 8/8 (2.5s)
- pnpm typecheck: 0 error
- pnpm lint: 0 error, 343 warn (~baseline 334 bare fetch + 9 pre-existing)

Out of scope: migrating existing 334 bare fetch sites (P2, separate PR).

P0 verification: playwright captured 19/19 /api/* returning 200 after login,
ruling out backend issue (cookie expired) — see p0-network-evidence.txt.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant