Closes P1 #10 step 2 / launch sequence step 10. PR #17 already
plumbed VERCEL_AUTOMATION_BYPASS_SECRET into both workflows' env;
this brief wires the actual @playwright/test dep, the
playwright.config.js that bridges env -> use.extraHTTPHeaders,
and a single visual spec so the screenshot workflow has something
to discover.
Per architect Decision 1 - tests/smoke/app.smoke.spec.ts stays as
.ts (npx eslint exits 0 against the current config); new visual
spec also .ts.
Per Decision 2 - playwright.config.js fail-loud in CI when
VERCEL_AUTOMATION_BYPASS_SECRET is missing (throw at config load
with actionable message naming the env var, rotation command,
AGENTS.md reference); warn-and-no-op in dev. Mirrors lib/rate-limit.js
fail-closed pattern (AGENTS.md Gotcha #12).
Per Decision 3 - two projects partitioned by testMatch:
- smoke -> tests/smoke/**/*.spec.{ts,js}
- visual -> tests/visual/**/*.spec.{ts,js}
Shared use: block. Matches the workflows' --project=smoke|visual
invocations.
Per Decision 4 - NO baselines committed. The Mac-vs-Linux platform-
suffix issue (architect Boot-the-brief Finding 7: Playwright's custom
snapshotPathTemplate has no {platform} token) means a Mac-generated
baseline would silently overwrite a Linux CI baseline. Queued as
seed-visual-baselines-on-linux follow-up convoy. First CI run of
Screenshot diff will fail at the test step; existing
continue-on-error: true swallows it and the comment-on-PR step
posts the run link.
Per Decision 5 - no eslint.config.mjs change.
Per Decision 6 - three simple scripts (test:smoke, test:visual,
test:visual:update). No auto-boot wrapper.
Verification:
- npm ci --dry-run exits 0 (lockfile in sync)
- npm run lint: 128 problems (baseline match - 81 errors, 47 warnings)
- npm run test:run: 21/21 vitest pass (no regression)
- npm run test:smoke (no BASE_URL): dev-path warn-and-continue
fires "[playwright.config] VERCEL_AUTOMATION_BYPASS_SECRET unset"
warning, enumerates 3 smoke tests, attempts to run (fails on
missing local chromium binary - workflows install browsers via
npx playwright install --with-deps chromium)
- CI=true npm run test:smoke: CI-path throws at config load with
"VERCEL_AUTOMATION_BYPASS_SECRET is required in CI to reach
Vercel-Protection-protected preview deployments. Reseed via:
gh secret set VERCEL_AUTOMATION_BYPASS_SECRET --body \"<value>\".
See AGENTS.md \xc2\xa7 7 for the full plumbing context."
- npx playwright --version: Version 1.60.0
Implementation note: removed the architect's defensive eslint-disable-
next-line no-console directive in the dev-warn branch because the
active eslint config does not enable no-console for repo-root config
files; ESLint reported the directive as unused, which would have
regressed the lint baseline by +1. Behavior unchanged; comment-only
edit per the brief's explicit "comment wording can be tightened"
allowance. Replaced with an explanatory comment noting why the
directive is intentionally absent.
Implementation note 2: alphabetized @playwright/test as the FIRST
entry in devDependencies (before @testing-library/dom) because
"@p" < "@t". The brief's prose said "between @testing-library/react
and autoprefixer" which would have broken alphabetization; followed
the brief's overarching principle ("alphabetical position") instead.
No code paths in pages/** or lib/** touched. No workflow YAML
edited. No AGENTS.md edits (doc-writer pass at convoy close handles
the seed-on-Linux runbook).
Co-authored-by: Cursor <cursoragent@cursor.com>
📤 Avatar Upload API (/api/user/avatar):
- File upload with multipart form data parsing
- Comprehensive validation (file type, size limits)
- Support for JPEG, PNG, GIF, WebP images up to 5MB
- Automatic cleanup of old avatars before new uploads
- Vercel Blob integration with public access
- Database tracking in user_avatars table
- Error handling for upload failures
🎨 Avatar Generation API (/api/user/avatar/generate):
- Custom avatar generation using DiceBear API
- Fire-themed color scheme (matching app branding)
- Personalized based on user initials/username/email
- SVG format for crisp display at any size
- Automatic fallback if generation fails
- Same cleanup and storage workflow as uploads
🗑️ Account Deletion API (/api/user/delete):
- Complete user data cleanup including Vercel Blob files
- Cascading deletion respecting foreign key constraints
- Admin account protection (prevents self-deletion)
- Comprehensive cleanup order:
* User avatars from Vercel Blob storage
* Deck cards, decks, collection cards, collections
* User cards, avatar records, settings
* Finally the user account itself
- Detailed logging for audit trail
- Graceful error handling with specific error messages
🔧 Technical Features:
- Custom multipart form data parser for file uploads
- Vercel Blob put/del operations with error handling
- Unique filename generation with timestamps
- Database transaction-like cleanup for deletions
- File type validation and size limits
- Proper CORS headers for all endpoints
🎯 Integration Ready:
- Works seamlessly with existing profile page UI
- Supports both upload and generate avatar buttons
- Returns avatar URLs for immediate display
- Database consistency with user profile system
- Production-ready error handling and validation
The avatar system is now fully functional with Vercel Blob! 📸✨
- Install @vercel/analytics and @vercel/speed-insights packages
- Integrate Analytics component for user behavior tracking
- Add SpeedInsights component for Core Web Vitals monitoring
- Track page views, user interactions, and performance metrics