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>
177 lines
6.9 KiB
Markdown
177 lines
6.9 KiB
Markdown
# 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
|
|
```typescript
|
|
// 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
|
|
```typescript
|
|
// 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
|
|
|
|
```bash
|
|
# 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).
|