fix: replace .single() with .maybeSingle() in reviews, saved-gigs, work-history, api-keys, wallet-addresses#476
Conversation
…rk-history, api-keys, wallet-addresses
Greptile SummaryThis PR continues the codebase-wide migration from
Confidence Score: 3/5Not safe to merge as-is — the reviews INSERT path will throw a TypeError and the saved-gigs and work-history INSERT paths will return misleading null payloads under RLS conditions. Two of the five files correctly handle the null result from src/app/api/reviews/route.ts (TypeError on null review), src/app/api/saved-gigs/route.ts and src/app/api/work-history/route.ts (null body on 201 response) Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[INSERT / SELECT query] --> B{.maybeSingle}
B --> C["data: row, error: null ✅"]
B --> D["data: null, error: DBError ✅"]
B --> E["data: null, error: null ⚠️\n(RLS blocks SELECT after INSERT)"]
C --> F[Happy path — row returned]
D --> G[Error guard catches it]
E --> H{null check present?}
H -- "Yes (api-keys)" --> I["if error or !apiKey → 400 ✅"]
H -- "No (reviews)" --> J["review.id → TypeError → 500 ❌"]
H -- "No (saved-gigs / work-history)" --> K["201 with null body ❌"]
|
| @@ -254,7 +254,7 @@ export async function POST(request: NextRequest) { | |||
| .from("profiles") | |||
| .select("did") | |||
| .eq("id", reviewee_id) | |||
| .single(); | |||
| .maybeSingle(); | |||
| if (userDid) { | |||
| onReviewCreated(userDid, review.id, revieweeProfile?.did || undefined); | |||
| } | |||
There was a problem hiding this comment.
Missing null check after
.maybeSingle() on INSERT
The code only checks createError but not !review after the insert. With .maybeSingle(), a successful insert where RLS prevents the SELECT from returning the row yields { data: null, error: null }. With .single() that scenario produced a PGRST116 error caught in createError. Now review is silently null, and the first access at review.id on line 259 (and review.reviewer/review.reviewee on lines 263–264) throws a TypeError, collapsing the entire handler into the generic 500 catch block instead of returning a meaningful response.
Continues the .single() to .maybeSingle() migration. Fixed routes:\n- GET/POST /api/reviews\n- GET/POST /api/saved-gigs\n- GET/POST /api/work-history\n- GET/DELETE /api/api-keys\n- GET/POST/DELETE /api/profile/wallet-addresses