Merge synced main and observability rollout#4
Conversation
cursor rules and mcp servers
Project setup
Includes Next.js app with claim/register flows, Solidity contracts (DroppingAirToken + SybilAirdrop), Prisma schema, deploy scripts, Playwright tests, Vercel config, and design tokens. Updates root workspace and gitignore to exclude secrets and build artifacts. Made-with: Cursor
Replace template Next.js app with sybil-airdrop application: - Add claim, register, and status pages with World ID integration - Add API routes (challenge, claim, rp-context, status) - Add Solidity contracts (DroppingAirToken, SybilAirdrop) - Add Prisma schema and Supabase database layer - Add deploy scripts for Base mainnet Adapt to existing CI pipeline: - Use pnpm with proper lockfile - Configure Tailwind v3, PostCSS, and prettier - Update eslint config (remove boundaries plugin) - Add project-specific words to cspell - Add vitest test, pin vite v6 for compatibility - Update tsconfig for ES2020 BigInt support - Fix vercel.json for root-level Next.js build Made-with: Cursor
The prisma/seed.ts imports PrismaClient which requires prisma generate to have been run. Exclude prisma/ from tsc to fix CI typecheck. Made-with: Cursor
Defer Supabase client creation to runtime to avoid build-time errors when environment variables are not available. Made-with: Cursor
The vercel.json was still pointing install/build/output to the old sybil-airdrop/ subdirectory. Now that the app is at the root, use default Next.js build behavior. Made-with: Cursor
Add sybil-airdrop mini app with World ID integration
## Vercel Web Analytics Implementation Successfully installed and configured Vercel Web Analytics for the Next.js App Router project. ### Changes Made **1. Package Installation** - Installed `@vercel/analytics@1.6.1` using pnpm - Updated `package.json` to include the new dependency - Updated `pnpm-lock.yaml` with the resolved package and its dependencies **2. Modified Files** - `app/layout.tsx` - Root layout file for the App Router **3. Code Changes** Added the Analytics component to the root layout: - Imported `Analytics` from `@vercel/analytics/next` - Added `<Analytics />` component inside the `<body>` tag, placed after the main content - Followed Next.js App Router best practices for component placement ### Implementation Details The implementation follows the standard Vercel Analytics setup for Next.js App Router projects: - The Analytics component is imported from `@vercel/analytics/next` - Placed at the root layout level to track analytics across all pages - Positioned after the main content within the body tag for optimal loading ### Verification Steps Completed ✅ **Build Verification**: Successfully built the project with no errors ✅ **Linting**: Passed ESLint checks with no issues ✅ **Testing**: All existing tests (1 test suite) passed ✅ **Type Checking**: TypeScript compilation successful ### Technical Notes - This is an App Router project (uses `app` directory structure) - The Analytics component will automatically track page views and web vitals - No additional configuration is required; the component works out of the box - Analytics data will be available in the Vercel dashboard when deployed ### Files Staged for Commit - `app/layout.tsx` - Added Analytics import and component - `package.json` - Added @vercel/analytics dependency - `pnpm-lock.yaml` - Updated with new package resolution - `.vade-report` - This report file All changes have been tested and verified to work correctly with no breaking changes to existing functionality. Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
…-nextjs-bi6lem Add Vercel Web Analytics to Next.js
Codify mandatory Playwright validation, living QA test-plan maintenance, and pass-before-commit/PR gates so future tasks follow a consistent quality workflow. Made-with: Cursor
Add QA workflow skills and living test plan
Consolidate onboarding, verification, and claiming into one terminal-like homepage, gate claims behind agent verification plus an inverted typing CAPTCHA, and remove obsolete multi-page routes while updating QA coverage. Made-with: Cursor
- Add instrumentation and observability utilities. - Update challenge API to use observability context. - Center the prompt box on the claim page. - Remove header and light mode toggle for a cleaner UI. Made-with: Cursor
Introduce structured request logging with request IDs, standardized error codes, and span wrappers across critical API flows, plus client telemetry hooks and an observability runbook so failures can be traced end-to-end quickly. Made-with: Cursor
Merge histories using allow-unrelated-histories and resolve top-level config conflicts in favor of the sybil-airdrop-feature project structure. Made-with: Cursor
Merge remote main into local main and resolve root conflicts to preserve the Dropping Air app configuration while incorporating upstream additions. Made-with: Cursor
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 348449c156
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return false | ||
| } | ||
|
|
||
| await db.from('Challenge').update({ used: true }).eq('nonce', nonce) |
There was a problem hiding this comment.
Guard nonce consumption with an atomic update
The nonce is marked as used with an unconditional update after a separate read, so two concurrent requests carrying the same signed payload can both observe used=false and both pass validation. In that race, both requests proceed to executeAirdrop, which can submit duplicate claim transactions and burn signer gas on reverts; consume the nonce with a single conditional write (e.g., ...eq('nonce', nonce).eq('used', false)) and verify that exactly one row was updated.
Useful? React with 👍 / 👎.
| const txHash = await withSpan( | ||
| 'claim.execute_airdrop', | ||
| { | ||
| route: ctx.route, | ||
| }, |
There was a problem hiding this comment.
Persist claim state before broadcasting transaction
The handler sends the on-chain claim transaction before recording the claim in the database, so if the DB insert fails after the transaction is accepted/mined, the API returns an error even though tokens were claimed. Because retries only consult the DB, the user can get stuck in repeated failures while the contract already considers the nullifier claimed; this should be made idempotent by persisting/locking claim intent before broadcasting or reconciling chain state on failure.
Useful? React with 👍 / 👎.
| const ACTIVE_CHALLENGES = new Map<string, ChallengeRecord>() | ||
| const CHALLENGE_TTL_MS = 5 * 60 * 1000 |
There was a problem hiding this comment.
Store agent challenges in shared persistence
Challenge state is kept only in an in-memory Map, which breaks verification in multi-instance or serverless deployments where GET /api/agent-challenge and POST /api/agent-challenge can land on different processes (or after a cold restart). In that case valid proofs are rejected as CHALLENGE_NOT_FOUND; challenge records need durable/shared storage (DB/Redis) to make this flow reliable in production.
Useful? React with 👍 / 👎.
Exclude non-app workspaces from root typecheck and switch sybil-airdrop to deployable package dependencies so Vercel builds complete successfully. Made-with: Cursor
Track the new local dev startup and Vercel preview deployment validations in the living QA plan so recent release workflow fixes remain covered. Made-with: Cursor
Summary
mainhistory (includingsybil-airdrop-featureand observability work) into a PR-safe branch to satisfy protected-branch rules.Test plan
pnpm lint(root)npx tsc --noEmitinsybil-airdrop/load, robot gate interaction)GET /api/challengereturnsx-request-idheader andrequestIdin bodyMade with Cursor