fix: affiliate click fallback redirects to localhost in production - #119
fix: affiliate click fallback redirects to localhost in production#119pxivory-max wants to merge 1 commit into
Conversation
Behind Railway's reverse proxy, request.url resolves to localhost:8080 instead of the public URL. This causes all fallback redirects (missing ref, invalid tracking code, errors) to strand users on an unreachable localhost URL. Fixes profullstack#94 Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Greptile SummaryThis PR fixes a production bug where the
Confidence Score: 4/5The fix correctly addresses the localhost redirect issue for all three fallback paths and is safe to merge. The core bug fix is correct — moving No files require special attention beyond the minor Important Files Changed
Sequence DiagramsequenceDiagram
participant Client
participant Railway Proxy
participant NextJS as Next.js /api/affiliates/click
participant Supabase
Client->>Railway Proxy: GET /api/affiliates/click?ugig_ref=CODE
Railway Proxy->>NextJS: forwards request (request.url = localhost:8080/...)
alt No ref param
NextJS-->>Client: 307 redirect → appUrl + /affiliates (FIXED)
else ref param present
NextJS->>Supabase: lookup affiliate_application by tracking_code
alt Not found / not approved
NextJS-->>Client: 307 redirect → appUrl + /affiliates (FIXED)
else Found
NextJS->>Supabase: recordClick(...)
NextJS-->>Client: 307 redirect → offer destination URL
end
else Unhandled error
NextJS-->>Client: 307 redirect → appUrl + /affiliates (FIXED)
end
Reviews (1): Last reviewed commit: "fix: use NEXT_PUBLIC_APP_URL for affilia..." | Re-trigger Greptile |
| } catch (err) { | ||
| console.error("Affiliate click error:", err); | ||
| return NextResponse.redirect(new URL("/affiliates", request.url)); | ||
| const appFallback = process.env.NEXT_PUBLIC_APP_URL || "https://ugig.net"; | ||
| return NextResponse.redirect(new URL("/affiliates", appFallback)); | ||
| } |
There was a problem hiding this comment.
The
appFallback variable in the catch block is redundant — appUrl (declared on line 11, outside the try block) is already in scope here and holds the same value. Re-reading the env var creates a second source of truth for the same constant, which could cause a silent mismatch if the fallback string is ever changed in one place but not the other.
| } catch (err) { | |
| console.error("Affiliate click error:", err); | |
| return NextResponse.redirect(new URL("/affiliates", request.url)); | |
| const appFallback = process.env.NEXT_PUBLIC_APP_URL || "https://ugig.net"; | |
| return NextResponse.redirect(new URL("/affiliates", appFallback)); | |
| } | |
| } catch (err) { | |
| console.error("Affiliate click error:", err); | |
| return NextResponse.redirect(new URL("/affiliates", appUrl)); | |
| } |
Summary
GET /api/affiliates/clickthat resolve tolocalhost:8080behind Railway's reverse proxyNEXT_PUBLIC_APP_URL(already available in the same file) as the base URL for all redirect fallbacksFixes #94
Context
This is part of testing the affiliate/invite-friends flow for the gig:
https://ugig.net/gigs/4741218f-a723-46bb-82cb-6516120331ae
Test plan
curl -si "https://ugig.net/api/affiliates/click"returns307tohttps://ugig.net/affiliates(not localhost)curl -si "https://ugig.net/api/affiliates/click?ugig_ref=invalid"also redirects to public URL🤖 Generated with Claude Code