Fix: supabase-js JSONB containment bug breaks shared-project queries
Passing a JS array to supabase-js `.contains()` on a JSONB column sends Postgres array-literal syntax (`cs.{x,y}`), which Postgres rejects. The fix is one line: wrap the array in `JSON.stringify()` so supabase-js emits `cs.<jsonarray>` instead.
shared_with is a JSONB column. supabase-js's .contains([userEmail]) generates a PostgREST cs.{email@example.com} filter, which PostgREST passes to Postgres as-is. Postgres reads it as an array literal, not a JSON array, and returns "invalid input syntax for type json". The result: every query that checks whether a project is shared with the current user silently 500'd.
The fix appears in three places: lib/access.ts:listAccessibleProjectIds, routes/projects.ts (list and getById lookups), and routes/tabular.ts (direct-share review lookup). In each case .contains("shared_with", [userEmail]) becomes .contains("shared_with", JSON.stringify([userEmail])).
Altien pairs the fix with two behavioral changes. Structured error logging replaces the previous pattern where the raw Postgres error message hit the response body with no backend trace. More significantly, the failure mode for the shared-projects query is downgraded from "fail the request" to "log and return an empty shared set." If the query fails for any reason - misconfiguration, transient error, anything - the user's own projects still come through. The owned-projects query remains fatal.
The bug exists in the upstream willchen96/mike codebase. The fix is self-contained and has no provider-boundary dependencies.
Spotted something wrong? Or know the PR text has fresher detail than the writeup above?