diff --git a/src/app/api/subscriptions/route.ts b/src/app/api/subscriptions/route.ts index 40bf4b12..d9d60e1c 100644 --- a/src/app/api/subscriptions/route.ts +++ b/src/app/api/subscriptions/route.ts @@ -15,7 +15,7 @@ export async function GET(request: NextRequest) { .from("subscriptions") .select("*") .eq("user_id", auth.user.id) - .single(); + .maybeSingle(); if (error && error.code !== "PGRST116") { return NextResponse.json({ error: error.message }, { status: 400 }); @@ -54,7 +54,7 @@ export async function DELETE(request: NextRequest) { .from("subscriptions") .select("stripe_subscription_id, status") .eq("user_id", auth.user.id) - .single(); + .maybeSingle(); if (error || !subscription) { return NextResponse.json( @@ -106,7 +106,7 @@ export async function PUT(request: NextRequest) { .from("subscriptions") .select("stripe_subscription_id, cancel_at_period_end") .eq("user_id", auth.user.id) - .single(); + .maybeSingle(); if (error || !subscription) { return NextResponse.json( diff --git a/src/app/api/testimonials/route.ts b/src/app/api/testimonials/route.ts index 37b76f68..cf5b1ab7 100644 --- a/src/app/api/testimonials/route.ts +++ b/src/app/api/testimonials/route.ts @@ -122,7 +122,7 @@ export async function POST(request: NextRequest) { .from("gigs") .select("poster_id, title") .eq("id", gig_id) - .single(); + .maybeSingle(); if (gigError || !gig) { return NextResponse.json( @@ -148,7 +148,7 @@ export async function POST(request: NextRequest) { ); } } else { - // Someone else leaving a testimonial on this gig — notify the poster + // Someone else leaving a testimonial on this gig �notify the poster notifyUserId = gig.poster_id; targetLabel = `your gig "${gig.title}"`; } @@ -183,7 +183,7 @@ export async function POST(request: NextRequest) { ...(autoApprove ? { status: "approved" } : {}), }) .select() - .single(); + .maybeSingle(); if (error) { if (error.code === "23505") { @@ -202,10 +202,10 @@ export async function POST(request: NextRequest) { .from("profiles") .select("full_name, username") .eq("id", user.id) - .single(); + .maybeSingle(); const authorName = authorProfile?.full_name || authorProfile?.username || "Someone"; - const stars = "★".repeat(rating) + "☆".repeat(5 - rating); + const stars = "�.repeat(rating) + "�.repeat(5 - rating); // In-app notification await serviceClient.from("notifications").insert({ @@ -224,7 +224,7 @@ export async function POST(request: NextRequest) { const baseUrl = process.env.NEXT_PUBLIC_APP_URL || "https://ugig.net"; await sendEmail({ to: ownerEmail, - subject: `${authorName} left a ${rating}-star testimonial on ${targetLabel} — ugig.net`, + subject: `${authorName} left a ${rating}-star testimonial on ${targetLabel} �ugig.net`, html: `

New Testimonial ${stars}

diff --git a/src/app/api/verification/request/route.ts b/src/app/api/verification/request/route.ts index d4475254..5c43861c 100644 --- a/src/app/api/verification/request/route.ts +++ b/src/app/api/verification/request/route.ts @@ -7,7 +7,7 @@ import { } from "@/lib/rate-limit"; import { getUserDid, onVerificationRequested } from "@/lib/reputation-hooks"; -// POST /api/verification/request — submit a verification request with evidence +// POST /api/verification/request �submit a verification request with evidence export async function POST(request: NextRequest) { try { const auth = await getAuthContext(request); @@ -40,7 +40,7 @@ export async function POST(request: NextRequest) { .from("profiles") .select("verified") .eq("id", user.id) - .single(); + .maybeSingle(); if (profile?.verified) { return NextResponse.json( @@ -55,7 +55,7 @@ export async function POST(request: NextRequest) { .select("id, status") .eq("user_id", user.id) .eq("status", "pending") - .single(); + .maybeSingle(); if (existingRequest) { return NextResponse.json( @@ -73,7 +73,7 @@ export async function POST(request: NextRequest) { status: "pending", }) .select() - .single(); + .maybeSingle(); if (error) { return NextResponse.json({ error: error.message }, { status: 400 }); diff --git a/src/app/api/video-calls/route.ts b/src/app/api/video-calls/route.ts index 3aaf45aa..0576dab5 100644 --- a/src/app/api/video-calls/route.ts +++ b/src/app/api/video-calls/route.ts @@ -115,7 +115,7 @@ export async function POST(request: NextRequest) { .from("profiles") .select("id, username, full_name") .eq("id", participant_id) - .single(); + .maybeSingle(); if (!participant) { return NextResponse.json( @@ -147,7 +147,7 @@ export async function POST(request: NextRequest) { scheduled_at, }) .select() - .single(); + .maybeSingle(); if (createError) { return NextResponse.json({ error: createError.message }, { status: 400 }); @@ -180,7 +180,7 @@ export async function POST(request: NextRequest) { .from("profiles") .select("full_name, username") .eq("id", user.id) - .single(); + .maybeSingle(); const initiatorName = initiatorProfile?.full_name || initiatorProfile?.username || "Someone"; const participantName = participant.full_name || participant.username || "there"; @@ -192,7 +192,7 @@ export async function POST(request: NextRequest) { .from("gigs") .select("title") .eq("id", gig_id) - .single(); + .maybeSingle(); gigTitle = gig?.title || null; } diff --git a/src/app/api/wallet/zap/route.ts b/src/app/api/wallet/zap/route.ts index c8f169c6..2d9cac55 100644 --- a/src/app/api/wallet/zap/route.ts +++ b/src/app/api/wallet/zap/route.ts @@ -54,7 +54,7 @@ export async function POST(request: NextRequest) { return NextResponse.json({ error: "No Lightning wallet found" }, { status: 400 }); } - // Pre-check sender's balance (informational only — authoritative check happens at transfer time) + // Pre-check sender's balance (informational only �authoritative check happens at transfer time) const senderBalance = await getLnBalance(senderWallet.invoice_key); if (senderBalance < amount_sats) { return NextResponse.json({ error: "Insufficient balance", balance_sats: senderBalance }, { status: 400 }); @@ -70,7 +70,7 @@ export async function POST(request: NextRequest) { const fee_sats = Math.floor(amount_sats * PLATFORM_FEE_RATE); const recipient_amount = amount_sats - fee_sats; - // Transfer recipient's share: sender → recipient (instant internal transfer) + // Transfer recipient's share: sender �recipient (instant internal transfer) // Handle insufficient-funds errors gracefully (TOCTOU race condition #78) try { await internalTransfer( @@ -117,13 +117,13 @@ export async function POST(request: NextRequest) { }, { status: 502 }); } - // Generic LNbits error — expose the actual message + // Generic LNbits error �expose the actual message return NextResponse.json({ error: err?.message || "Zap transfer failed", }, { status: 502 }); } - // Transfer platform fee: sender → platform wallet (retry up to 3 times) + // Transfer platform fee: sender �platform wallet (retry up to 3 times) if (fee_sats > 0) { let feeTransferred = false; for (let attempt = 1; attempt <= 3; attempt++) { @@ -190,7 +190,7 @@ export async function POST(request: NextRequest) { note: note || null, }) .select() - .single(); + .maybeSingle(); const zapId = (zap as any)?.id; @@ -229,13 +229,13 @@ export async function POST(request: NextRequest) { .from("profiles") .select("*") .eq("id", recipient_id) - .single(); + .maybeSingle(); const { data: senderProfile } = await admin .from("profiles") .select("username") .eq("id", senderId) - .single(); + .maybeSingle(); const senderName = senderProfile?.username || "Someone"; @@ -243,7 +243,7 @@ export async function POST(request: NextRequest) { await (admin.from("notifications") as any).insert({ user_id: recipient_id, type: "zap_received", - title: "You received a zap! ⚡", + title: "You received a zap! �, body: `${senderName} zapped you ${recipient_amount.toLocaleString()} sats`, data: { zap_id: zapId, amount_sats: recipient_amount, target_type, target_id }, }); @@ -251,7 +251,7 @@ export async function POST(request: NextRequest) { await (admin.from("notifications") as any).insert({ user_id: recipient_id, type: "zap_received", - title: "You received a zap! ⚡", + title: "You received a zap! �, body: `${senderName} zapped you ${recipient_amount.toLocaleString()} sats. Add a Lightning Address to your profile to withdraw.`, data: { zap_id: zapId, amount_sats: recipient_amount, target_type, target_id, action_url: "/profile" }, });