Files
PoleDanceApp/dancechamp-claude-code/SPEC-CLAUDE.md
Dianaka123 4c1870ebb4 Add root CLAUDE.md and rename spec CLAUDE.md
Created project-level CLAUDE.md with current architecture, quick start,
gotchas, and conventions. Renamed dancechamp-claude-code/CLAUDE.md to
SPEC-CLAUDE.md to distinguish target spec from current project context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:22:08 +03:00

6.9 KiB

CLAUDE.md — DanceChamp

What is this project?

DanceChamp is a mobile platform for pole dance championships. Three apps, one database:

  • Member App (React Native / Expo) — Dancers discover championships, register, track their 10-step progress
  • Org App (React Native / Expo) — Championship organizers create events, manage members, review videos, confirm payments
  • Admin Panel (React + Vite, web) — Platform admin approves orgs, reviews championships from unverified orgs, manages users

Project Structure

/
├── CLAUDE.md                    ← You are here
├── apps/
│   ├── mobile/                  ← Expo app (Member + Org views, switched by role)
│   │   ├── src/
│   │   │   ├── screens/
│   │   │   │   ├── member/      ← Home, MyChamps, Search, Profile, ChampDetail, Progress
│   │   │   │   ├── org/         ← Dashboard, ChampDetail (tabbed), MemberDetail, Settings
│   │   │   │   └── auth/        ← SignIn, SignUp, Onboarding
│   │   │   ├── components/      ← Shared UI components
│   │   │   ├── navigation/      ← Tab + Stack navigators
│   │   │   ├── store/           ← Zustand stores
│   │   │   ├── lib/             ← Supabase client, helpers
│   │   │   └── theme/           ← Colors, fonts, spacing
│   │   └── app.json
│   └── admin/                   ← Vite React app
│       └── src/
│           ├── pages/           ← Dashboard, Orgs, Champs, Users
│           ├── components/
│           └── lib/
├── packages/
│   └── shared/                  ← Shared types, constants, validation
│       ├── types.ts             ← TypeScript interfaces (User, Championship, etc.)
│       └── constants.ts         ← Status enums, role enums
├── supabase/
│   ├── migrations/              ← SQL migration files
│   └── seed.sql                 ← Demo data
└── docs/
    ├── SPEC.md                  ← Full technical specification
    ├── PLAN.md                  ← Phase-by-phase dev plan with checkboxes
    ├── DATABASE.md              ← Complete database schema + RLS policies
    ├── DESIGN-SYSTEM.md         ← Colors, fonts, components, patterns
    └── SCREENS.md               ← Screen-by-screen reference for all 3 apps

Tech Stack

Layer Choice Notes
Mobile React Native (Expo) npx create-expo-app with TypeScript
Admin React + Vite Separate web app
Language TypeScript Everywhere
Navigation React Navigation Bottom tabs + stack
State Zustand Lightweight stores
Backend Supabase Auth, Postgres DB, Storage, Realtime, Edge Functions
Push Expo Notifications Via Supabase Edge Function triggers

Key Architecture Decisions

1. One mobile app, two views

Member and Org use the same Expo app. After login, the app checks user.role and shows the appropriate navigation:

  • role === "member" → Member tabs (Home, My Champs, Search, Profile)
  • role === "organization" → Org tabs (Dashboard, Settings)

2. Everything is scoped per-championship

Members, results, categories, rules, fees, judges — all belong to a specific championship. There is no "global members list" for an org. Each championship is self-contained.

3. Configurable tabs (Org)

Orgs don't fill a giant wizard. They quick-create a championship (name + date + location), then configure each section (Categories, Fees, Rules, Judges) at their own pace. Each section has a "✓ Mark as Done" button. Championship can only go live when all sections are done.

4. Approval flow

  • Verified orgs → "Go Live" sets status to live immediately (auto-approved)
  • Unverified orgs → "Go Live" sets status to pending_approval → admin must approve

5. Registration dates (not deadline)

Championships have: event_date, reg_start, reg_end. Registration close date must be before event date. No single "deadline" field.

6. Judges = People, Scoring = Rules

The "Judges" tab shows judge profiles (name, instagram, bio). Scoring criteria and penalties live in the "Rules" tab.

Conventions

Code Style

  • Functional components only, no class components
  • Use hooks: useState, useEffect, custom hooks for data fetching
  • Zustand for global state (auth, current user, championships cache)
  • Local state for UI-only state (modals, form inputs, filters)
  • TypeScript strict mode

Naming

  • Files: kebab-case.ts / kebab-case.tsx
  • Components: PascalCase
  • Hooks: useCamelCase
  • Zustand stores: use[Name]Store
  • DB tables: snake_case
  • DB columns: snake_case

Supabase Patterns

// Client init
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)

// Fetching
const { data, error } = await supabase
  .from('championships')
  .select('*, disciplines(*), fees(*)')
  .eq('status', 'live')

// Realtime subscription
supabase.channel('registrations')
  .on('postgres_changes', { event: '*', schema: 'public', table: 'registrations' }, handler)
  .subscribe()

Navigation Pattern

// Member
const MemberTabs = () => (
  <Tab.Navigator>
    <Tab.Screen name="Home" component={HomeStack} />
    <Tab.Screen name="MyChamps" component={MyChampsStack} />
    <Tab.Screen name="Search" component={SearchStack} />
    <Tab.Screen name="Profile" component={ProfileStack} />
  </Tab.Navigator>
)

// Org
const OrgTabs = () => (
  <Tab.Navigator>
    <Tab.Screen name="Dashboard" component={DashboardStack} />
    <Tab.Screen name="Settings" component={SettingsStack} />
  </Tab.Navigator>
)

Important Docs

Before coding any feature, read the relevant doc:

Doc When to read
docs/SPEC.md Full feature spec — read first for any new feature
docs/PLAN.md Dev plan with phases — check what's next
docs/DATABASE.md Schema — read before any DB work
docs/DESIGN-SYSTEM.md UI — read before any screen work
docs/SCREENS.md Screen details — read before building specific screens

Quick Commands

# Start mobile app
cd apps/mobile && npx expo start

# Start admin panel
cd apps/admin && npm run dev

# Supabase local dev
npx supabase start
npx supabase db reset  # Reset + re-seed

# Generate types from Supabase
npx supabase gen types typescript --local > packages/shared/database.types.ts

Current Status

Prototypes completed (JSX files in /prototypes):

  • dance-champ-mvp.jsx — Member app prototype
  • dance-champ-org.jsx — Org app prototype
  • dance-champ-admin.jsx — Admin panel prototype

These are reference implementations showing the exact UI, data structure, and flows. Use them as visual guides — don't copy the code directly (they're single-file React prototypes, not production React Native).