Skip to content

[#1243] Add /verify-fc endpoint with partial-failure semantics#1281

Merged
realproject7 merged 2 commits into
mainfrom
task/1243-verify-fc-endpoint
May 26, 2026
Merged

[#1243] Add /verify-fc endpoint with partial-failure semantics#1281
realproject7 merged 2 commits into
mainfrom
task/1243-verify-fc-endpoint

Conversation

@realproject7

Copy link
Copy Markdown
Owner

Summary

  • POST /api/airdrop/verify-fc — SIWE-authenticated Farcaster follow verification
  • Calls verifyFc(username, PLOTLINK_FC_FID) then persists fid + fc_handle + fc_verified_at atomically on success
  • Partial-failure paths (RE1 Critical 3): user_not_found → 404, not_following → 422, neynar_error → 502 — all with zero DB writes
  • FID UNIQUE index conflict → 409
  • 6 tests: SIWE rejection, all 3 error paths verify no DB write, success persists all fields, UNIQUE conflict

Version

1.32.0 → 1.32.1

🤖 Generated with Claude Code

SIWE-authenticated FC verification: calls verifyFc then persists
fid + fc_handle + fc_verified_at on success. Partial-failure paths:
user_not_found → 404, not_following → 422, neynar_error → 502 —
all with zero DB writes. FID UNIQUE conflict → 409. 6 tests cover
all acceptance paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented May 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
plotlink Ignored Ignored May 26, 2026 6:34am

Request Review

@realproject7 realproject7 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@re2 review — APPROVE ✅

Checked against issue #1243 acceptance criteria:

Criterion Status
user_not_found → 404, no DB write ✅ (test verifies mockUpdate not called)
not_following → 422, no DB write
neynar_error → 502, no DB write
Success → persists fid + fc_handle + fc_verified_at atomically ✅ (single update() call)
FID UNIQUE conflict → 409
SIWE rejection → 401
Version 1.32.0 → 1.32.1 (patch)

Code review notes:

  • Correct ordering: SIWE auth → verifyFc → DB write. No DB interaction until both auth and verification succeed (RE1 Critical 3).
  • Uses update (not upsert) — requires existing pl_activations row, consistent with the activation flow (X handle confirmed first).
  • statusMap for error→HTTP mapping is clean and exhaustive for the verifyFc error union.
  • fc_handle lowercased before storage.
  • PLOTLINK_FC_FID read dynamically from config.
  • 6 tests cover all acceptance paths including no-DB-write assertions on every failure path.
  • Lockfile synced to 1.32.1.

No issues found.

@project7-interns project7-interns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The endpoint has the right SIWE and Neynar failure mapping, and the tests cover the explicit partial-failure statuses. The success persistence path can still report success without actually writing the FC fields.

Findings

  • [high] Success uses update(...).eq("address", address) without verifying that a pl_activations row exists or that any row was changed. Supabase updates with no matching row can return error: null, so /verify-fc can return 200 with fid, fc_handle, and fc_verified_at even though none of the three fields were persisted. That violates the #1243 acceptance item that success persists all 3 fields atomically.
    • File: src/app/api/airdrop/verify-fc/route.ts:44
    • Suggestion: Use an upsert on address, or request representation/count and fail if no row was updated. Add a route test for the no-existing-activation-row case so success cannot silently become a no-op.

Decision

Requesting changes until the success path guarantees the FC fields are actually persisted. CI was still pending at review time.

Use .select().single() after update to confirm a row was modified.
Return 400 when no pl_activations row exists (PGRST116 or null).
Added 7th test for no-existing-activation-row path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@project7-interns project7-interns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE

Summary

The requested success-path persistence fix is in place. /verify-fc now verifies the update returned a row, maps the no-activation-row case to 400, and the tests cover SIWE rejection, all partial-failure statuses with no DB write, success persistence, FID conflict, and the no-row update path.

Findings

  • None.

Decision

Approved. Latest visible checks are Vercel status contexts only, so wait for any required branch checks before merge.

@realproject7 realproject7 merged commit 3d8e6f0 into main May 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants