Skip to content

Latest commit

 

History

History
89 lines (63 loc) · 4.79 KB

File metadata and controls

89 lines (63 loc) · 4.79 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this project is

SWAP is a Next.js 14 social network and marketplace for trading collectible stickers (World Cup 2026 Panini album). Users manage their collections, follow other collectors, chat, join communities, and coordinate trades through a marketplace.

Commands

npm run dev       # start dev server (http://localhost:3000)
npm run build     # production build
npm run start     # start production server
npm run lint      # ESLint (next/core-web-vitals)

No test runner is configured. No API routes — all backend calls go directly to Supabase.

Environment variables

Required in .env.local:

NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=

Architecture

Stack: Next.js 14 App Router · TypeScript · Tailwind CSS · Supabase (Postgres + Auth + Storage + Realtime)

Route groups:

  • app/(auth)/ — public auth pages (login, register, forgot/reset password)
  • app/(protected)/ — authenticated pages with shared sidebar + bottom nav layout
    • colecciones/ — sticker collection viewer
    • marketplace/ — profile-based trade matching (sorted by sticker compatibility)
    • chat/[tradeId]/ — per-trade and direct message chat
    • chats/ — list of all conversations
    • perfil/ — own user profile (Instagram-style)
    • perfil/[userId]/ — public profile of any user
    • perfil/[userId]/album/[albumId]/ — read-only album view of another user
    • amigos/ — user search
    • comunidades/ — community list
    • comunidades/[communityId]/ — group chat for a community

Auth flow: middleware.ts protects all / routes, refreshes the Supabase session on each request, and redirects unauthenticated users to /login. Registration sends a confirmation email — users must verify before logging in.

Supabase helpers:

  • lib/supabase/client.ts — browser client (use in Client Components)
  • lib/supabase/server.ts — server client (use in Server Components / Server Actions)

Data model (key tables): profiles, albums, stickers, user_stickers, listings, listing_offers, listing_wants, trades, messages, follows, communities, community_messages, trade_reads, push_subscriptions. Migrations live in supabase/migrations/.

Trade matching logic: user_stickers.repeated_count > 0 = stickers the user can give. A sticker is "missing" for a user if they have no user_stickers row with owned = true for it. Marketplace (marketplace/page.tsx) fetches all users' repeated and owned stickers server-side, computes match counts per user, and passes pre-computed ProfileMatch[] to the client. Public profile (perfil/[userId]/page.tsx) does the same but also fetches full sticker details for the modal list.

Component pattern: Pages are async Server Components that fetch data from Supabase and pass it to *Client.tsx Client Components that own interactive state (modals, forms, chat). TypeScript interfaces for all entities are in lib/types/.

Key lib files

  • lib/albumCovers.ts — maps album names to local cover images in public/albums/. Add entries here when adding new album covers; no DB change needed.
  • lib/importParser.ts — parses WhatsApp-style sticker list messages from other apps. Exports parseImportText and matchStickers.

TypeScript gotchas

  • Target is not es2015, so never use [...new Set(...)] spread. Always use Array.from(new Set(...)) instead.
  • Supabase Realtime channels: always use a unique channel name per component instance (e.g. useRef(\channel-name-${Date.now()}`).current`) to avoid "cannot add callbacks after subscribe()" errors when effects re-run.

Navigation — always update both

The app has two nav components that must stay in sync:

  • components/layout/Sidebar.tsx — desktop (md+)
  • components/layout/BottomNav.tsx — mobile

Both receive userId from app/(protected)/layout.tsx for the unread badge.

Migrations to apply in Supabase SQL Editor

All files in supabase/migrations/ must be run in order. Apply any that are not yet in production:

File What it adds
009_add_trade_reads.sql trade_reads table + get_unread_count() RPC
010_allow_direct_trades.sql trades.listing_id nullable for DMs
011_add_reply_to_and_unread_per_trade.sql messages.reply_to_id + get_unread_counts_per_trade() RPC
012_delete_policies.sql RLS: delete own messages and trades
013_add_updated_at_to_user_stickers.sql user_stickers.updated_at + index for sorting
014_add_notifications_seen_at.sql profiles.notifications_seen_at for notification badge
015_push_subscriptions.sql push_subscriptions table for web push (VAPID)