Found in PR #79 (fix/70-project-access-email-case)
Severity: Major
PR #79 fixes GET /projects/:projectId to be case-insensitive, but the GET /projects (list) query still uses a case-sensitive Supabase JSONB contains filter:
// backend/src/routes/projects.ts ~line 43
.filter("shared_with", "cs", JSON.stringify([userEmail]))
The cs operator (@> in PostgreSQL) is case-sensitive. If a user authenticates as alice@company.com but their email was stored in shared_with before the normalization fix (e.g., as Alice@Company.Com), shared projects will not appear in the list even though single-project access now works.
Fix: Either:
- Normalize
userEmail to lowercase before the filter: .filter("shared_with", "cs", JSON.stringify([userEmail?.toLowerCase()]))
- Or normalize all existing
shared_with entries via a DB migration so the stored values are already lowercase, making the cs filter reliable.
Option 1 is a one-line fix; option 2 is a longer migration but ensures consistency.
Found in PR #79 (fix/70-project-access-email-case)
Severity: Major
PR #79 fixes
GET /projects/:projectIdto be case-insensitive, but theGET /projects(list) query still uses a case-sensitive Supabase JSONB contains filter:The
csoperator (@>in PostgreSQL) is case-sensitive. If a user authenticates asalice@company.combut their email was stored inshared_withbefore the normalization fix (e.g., asAlice@Company.Com), shared projects will not appear in the list even though single-project access now works.Fix: Either:
userEmailto lowercase before the filter:.filter("shared_with", "cs", JSON.stringify([userEmail?.toLowerCase()]))shared_withentries via a DB migration so the stored values are already lowercase, making thecsfilter reliable.Option 1 is a one-line fix; option 2 is a longer migration but ensures consistency.