API client, auth bootstrap and job polling #42

2 Commits
Author SHA1 Message Date
dev_agentandClaude Opus 5.5 690e1056a6 Keep polling a job after a failed poll
Independent review Codex gpt-6-sol high: APPROVED (0 findings)
CI / ci (push) Successful in 1m31s
CI / ci (pull_request) Successful in 1m31s
A failed GET /api/v1/jobs/{id} no longer ends polling. useJob exposes the
request's error, keeps the last known status and result, and schedules the
next poll on the same 500 ms to 2 s backoff. Polling stops only at a
terminal status, a changed job id or unmount.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 08:37:11 -04:00
dev_agentandClaude Opus 5.5 913c1e5337 Add API client, /me bootstrap and useJob polling hook
Independent review Codex gpt-6-sol high: CHANGES_REQUIRED (1 medium)
CI / ci (push) Successful in 1m34s
CI / ci (pull_request) Successful in 1m32s
web/src/api provides createApiClient().apiFetch: same-origin JSON with
the cached /api/v1/me CSRF token on non-GET requests and a typed
ApiError from the server's error body. A 401 navigates to
/auth/login?return={path}; a csrf 403 refreshes /me once and retries
once; any other 403 shows the "not in this household" screen.

App loads /me before the routes, showing the Skeleton meanwhile. The
QueryClient retries only ApiErrors the server marks retryable. useJob
polls GET /api/v1/jobs/{id} backing off 500 ms to 2 s, exposing status,
partial result and error until a terminal status, and stops on unmount.

Maestro task 21051318-15ae-4d0e-a9a1-2143f87de759.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 08:33:34 -04:00