caterium-app/docs/LOGIN-RECOVERY-20260918.md

2.5 KiB

Recover login when the API proxy returns no data

The API proxy intermittently returned HTTP 200 with an empty HTML response for authentication and workspace membership requests. The same Supabase backend returned a valid session and the existing workspace directly. The former membership loader treated malformed responses like missing workspaces, while an existing login gate kept its loading message. A second authentication client used by the fallback also shared the same session storage key.

The shared transport now validates JSON responses and uses the same backend directly for failed reads and password login. Authorization and the single SDK session are preserved. Only GET/HEAD and explicitly allowlisted read RPCs can be retried, plus password login. Database writes are not replayed. Both channels have bounded waits; permission and credential errors are returned without fallback.

Membership requests for the same account share one in-flight operation. Late responses from a different account are ignored. Missing RPC compatibility is used only for a missing function, not network errors. A failed membership request produces a retry/exit screen and cannot be mistaken for a developer account with no company. Successful login still opens the normal application.

Regression coverage includes empty/invalid proxy responses, identical request bodies and authorization on fallback, non-replayed writes, credential rejection, concurrent membership loads, recovery UI, and a real Supabase SDK login against controlled endpoint responses. The full flow is checked on desktop and mobile without changing production credentials or authentication requirements.

Server retry loop discovered during production verification

Supabase logs showed PostgREST 14.5 repeatedly executing sun_v17_save_client_v1772 with SUN_CLIENT_CONFLICT expected=1 actual=2, SQLSTATE 40001, exhausting the REST connection pool. Both direct and proxied workspace reads then timed out. See the Supabase incident guidance.

Migration 20260918000000_conflict_http_status.sql changes the two application version-conflict handlers to PT409. It preserves function bodies, privileges, revision checks and data. Existing looping backends must be identified in this project's logs and pg_stat_activity, then terminated individually. The SQL smoke test verifies both conflicts return PT409 and stale writes leave data unchanged.