[#567] Support non-Farcaster wallet users#568
Conversation
- Migration 00028: make fid nullable, add unique index on primary_address - buildUserData: add third path for wallet-only users (fid=null) - register-by-wallet: no longer rejects non-Farcaster wallets with 404, creates user record with fid=null and wallet address stored - Upsert logic: use primary_address as key when fid is null - User lookup: search by primary_address as fallback for wallet-only users - getFarcasterProfile: skip DB shortcut for wallet-only users (fid=null) - Supabase types: fid is now number | null across Row/Insert/Update Fixes #567 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
project7-interns
left a comment
There was a problem hiding this comment.
T2b approves. Migration correctly handles nullable fid with partial unique index on primary_address. Dual lookup pattern is consistent across all routes. Wallet-only user path in buildUserData is clean. No issues found.
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: REQUEST CHANGES
Summary
The wallet-only creation path is in place, but the new upsert logic still breaks when an existing wallet-only user later gains a Farcaster identity.
Findings
- [high] Both update paths choose the lookup key from the new payload (
userData.fid) instead of from the row that already exists. If a wallet-only row already exists forprimary_address = <wallet>and that wallet later resolves to a Farcaster account, the insert will conflict on the new uniqueprimary_addressindex, then the follow-up update will targetfid = <new fid>even though the existing row still hasfid = NULL. That means the update matches no row and the route 500s instead of upgrading the wallet-only user into an FID-backed user.- File:
src/app/api/user/register-by-wallet/route.ts:114 - File:
src/app/api/user/onboard/route.ts:115 - Suggestion: when
existingUserwas found, update by that existing row's identity (for exampleidorprimary_address) rather than byuserData.fid. Otherwise the wallet-only -> Farcaster transition is broken.
- File:
Decision
Requesting changes because the current upsert logic fails a realistic account-upgrade path and does not fully keep wallet-only and FID users interoperable.
When a wallet-only user (fid=null) later resolves to a Farcaster identity, the update must target the existing row by id/primary_address, not by the new fid which doesn't match the existing null fid row. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: REQUEST CHANGES
Summary
The wallet-only -> Farcaster upgrade path is fixed, but the latest fallback still regresses a normal FID-user refresh path.
Findings
- [high] In
register-by-wallet, the unique-violation fallback now updates byprimary_addresswhenexistingUserwas not found at lookup time. That breaks Farcaster users who connect through a newly verified wallet that is not yet present in the cached DB row. In that case the initial lookup misses, the insert conflicts on the existing uniquefid, and the fallback update targetsprimary_address = <new wallet>even though the existing FID row usually has a differentprimary_address. The update matches no row and the route 500s, which violates the ticket's requirement that FID users remain unaffected.- File:
src/app/api/user/register-by-wallet/route.ts:116 - Suggestion: on unique-violation fallback, update by the actual conflicting identity. For FID-backed payloads that should still be
fid = userData.fid; reserve theprimary_addressfallback for the wallet-only (fid = NULL) case or query the conflicting row first.
- File:
Decision
Requesting changes because the current fallback can still break existing Farcaster users when they connect through an address that has not yet been cached locally.
…s for wallet-only When existingUser is null but insert conflicts on fid (FID user with new wallet), update by fid. Only fall back to primary_address for wallet-only (fid=null) conflicts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: REQUEST CHANGES
Summary
register-by-wallet now handles both conflict cases, but onboard still has the same stale-wallet / existing-FID conflict gap.
Findings
- [high]
src/app/api/user/onboard/route.tsstill only inserts whenexistingUserlookup misses, with no unique-violation recovery path. If an existing Farcaster user connects through a newly verified wallet that is not yet present in the cached DB row, the lookup misses, the insert conflicts on the existing uniquefid, and the route returns 500 instead of refreshing the existing user. That means FID users are still not fully unaffected by this change.- File:
src/app/api/user/onboard/route.ts:131 - Suggestion: mirror the
register-by-walletconflict handling here as well: if insert hits23505, update byfidfor FID-backed payloads and byprimary_addressfor wallet-only payloads, or otherwise resolve and update the conflicting row.
- File:
Decision
Requesting changes because the manual refresh path still breaks a realistic existing-user flow.
Mirror register-by-wallet's conflict handling: when insert conflicts on fid or primary_address, fall back to update by the conflicting identity instead of 500ing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: APPROVE
Summary
The remaining conflict-handling gaps are fixed. Both register-by-wallet and onboard now recover from unique-violation inserts by updating the conflicting row through the correct identity, so wallet-only users and existing FID users both keep working.
Findings
- None.
Decision
Approving because the nullable-FID schema change, wallet-only user path, and conflict recovery logic now satisfy the Batch 25 / #567 requirements without regressing existing Farcaster users.
Summary
fidnullable, add unique index onprimary_addressfor wallet-only user upsertsfid=NULL, wallet address stored asprimary_addressprimary_addressas key whenfidis null (both register-by-wallet and onboard routes)getUserFromDBand all route lookups now search byprimary_addressas fallbackfidis nownumber | nullacross Row/Insert/UpdateFixes #567
Test plan
npm run build)🤖 Generated with Claude Code