Skip to content

Convert Wheelgen to Farcaster mini-app#2

Open
mxjxn wants to merge 1 commit intomainfrom
claude/wheelgen-farcaster-miniapp-01QUb61NWqvJA6gozjiuHAvW
Open

Convert Wheelgen to Farcaster mini-app#2
mxjxn wants to merge 1 commit intomainfrom
claude/wheelgen-farcaster-miniapp-01QUb61NWqvJA6gozjiuHAvW

Conversation

@mxjxn
Copy link
Owner

@mxjxn mxjxn commented Nov 20, 2025

Major architectural changes:

  • Add Farcaster SDK integration with auto-auth
  • Create backend API with Vercel Serverless Functions
  • Implement PostgreSQL database schema for artworks
  • Build gallery view for browsing community creations
  • Add publish functionality with shareable embeds
  • Implement client-side routing (/create, /gallery, /art/:id)
  • Create Farcaster manifest and embed meta tags

New features:

  • Users can save artworks to their account
  • Publish artworks to public gallery
  • Share artwork URLs on Farcaster with rich embeds
  • Browse community artworks with user attribution
  • View counts and artwork metadata

Technical stack:

  • Frontend: Vite + SolidJS + p5.js + @farcaster/frame-sdk
  • Backend: Vercel Serverless Functions + PostgreSQL
  • API endpoints: save, list, get, publish, delete artworks
  • Embed strategy: Server-rendered meta tags for Farcaster crawlers

See FARCASTER_MINIAPP_SETUP.md for deployment instructions


Note

Transforms WheelGen into a Farcaster mini-app with auth, gallery, publishing, Postgres-backed serverless API, embeds, and client-side routing.

  • Frontend:
    • Farcaster Integration: Add FarcasterProvider and auth via @farcaster/frame-sdk; inject in main.tsx.
    • Routing/UI: Introduce custom Router and RootApp with routes '/create', '/gallery', '/art/:id'; new pages Gallery and ArtworkView with styles.
    • Publishing: Add PublishTab to save/publish artworks; API client in services/apiClient.ts; embed meta utilities.
  • Backend (Vercel Functions):
    • Artworks API: Add endpoints POST /api/artworks/save, GET /api/artworks/list, GET /api/artworks/:id (increments views), POST /api/artworks/publish, DELETE /api/artworks/:id.
    • Embeds/Manifest: Add GET /api/artworks/embed/:id for shareable meta tags and GET /.well-known/farcaster.json manifest.
    • Database: Add Postgres client (@vercel/postgres) and schema (users, artworks, indexes, update triggers).
  • Infra/Config:
    • Add vercel.json routing (SPA routes and API), .env.example, and setup guide FARCASTER_MINIAPP_SETUP.md.
  • Dependencies:
    • Add @farcaster/frame-sdk, @vercel/node, @vercel/postgres, and related types; update lockfile.

Written by Cursor Bugbot for commit f32c9c2. This will update automatically on new commits. Configure here.

Major architectural changes:
- Add Farcaster SDK integration with auto-auth
- Create backend API with Vercel Serverless Functions
- Implement PostgreSQL database schema for artworks
- Build gallery view for browsing community creations
- Add publish functionality with shareable embeds
- Implement client-side routing (/create, /gallery, /art/:id)
- Create Farcaster manifest and embed meta tags

New features:
- Users can save artworks to their account
- Publish artworks to public gallery
- Share artwork URLs on Farcaster with rich embeds
- Browse community artworks with user attribution
- View counts and artwork metadata

Technical stack:
- Frontend: Vite + SolidJS + p5.js + @farcaster/frame-sdk
- Backend: Vercel Serverless Functions + PostgreSQL
- API endpoints: save, list, get, publish, delete artworks
- Embed strategy: Server-rendered meta tags for Farcaster crawlers

See FARCASTER_MINIAPP_SETUP.md for deployment instructions
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

createdAt: row.createdAt,
updatedAt: row.updatedAt,
user: {
fid: row.userFid,
Copy link

Choose a reason for hiding this comment

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

Bug: Database column name mismatch with TypeScript properties

The code accesses database row properties using camelCase (like row.userFid, row.thumbnailDataUrl, row.publishedAt, row.createdAt, row.updatedAt) but the PostgreSQL schema defines columns in snake_case (user_fid, thumbnail_data_url, published_at, created_at, updated_at). PostgreSQL returns column names as defined in the schema, so these properties will be undefined, causing the artwork object to have null/undefined values for these fields. The same issue affects api/artworks/list.ts, api/artworks/publish.ts, and api/artworks/save.ts.

Fix in Cursor Fix in Web

const { title, data, thumbnailDataUrl } = req.body as SaveArtworkRequest;

// Get user FID from header (set by Farcaster SDK via Quick Auth)
const userFid = req.headers['x-farcaster-fid'];
Copy link

Choose a reason for hiding this comment

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

Bug: Authentication header mismatch between client and server

The API endpoints expect the user FID in the x-farcaster-fid header, but the client sends an Authorization: Bearer <token> header via fetchWithAuth. There's no middleware to decode the JWT token and extract the FID, so req.headers['x-farcaster-fid'] will always be undefined, causing all authenticated requests to fail with 401 Unauthorized. This affects api/artworks/save.ts, api/artworks/publish.ts, and api/artworks/delete.ts.

Fix in Cursor Fix in Web

`INSERT INTO artworks (user_fid, title, data, thumbnail_data_url)
VALUES ($1, $2, $3, $4)
RETURNING *`,
[userFid, title || null, JSON.stringify(data), thumbnailDataUrl]
Copy link

Choose a reason for hiding this comment

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

Bug: Double JSON stringification of artwork data

The artwork data is being double-stringified. The client already sends data as a JavaScript object in the request body (which gets stringified by JSON.stringify(data) in apiClient.ts), but the server calls JSON.stringify(data) again before inserting into the JSONB column. This results in storing a string containing escaped JSON (like "{\"version\":\"1.0\"...}") instead of a proper JSONB object, breaking deserialization when the artwork is retrieved.

Fix in Cursor Fix in Web

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