Backend (FastAPI + SQLAlchemy + SQLite): - JWT auth with access/refresh tokens, bcrypt password hashing - User model with member/organizer/admin roles, auto-approve members - Championship, Registration, ParticipantList, Notification models - Alembic async migrations, seed data with test users - Registration endpoint returns tokens for members, pending for organizers - /registrations/my returns championship title/date/location via eager loading - Admin endpoints: list users, approve/reject organizers Mobile (React Native + Expo + TypeScript): - Zustand auth store, Axios client with token refresh interceptor - Role-based registration (Member vs Organizer) with contextual form labels - Tab navigation with Ionicons, safe area headers, admin tab for admin role - Championships list with status badges, detail screen with registration progress - My Registrations with championship title, progress bar, and tap-to-navigate - Admin panel with pending/all filter, approve/reject with confirmation - Profile screen with role badge, Ionicons info rows, sign out - Password visibility toggle (Ionicons), keyboard flow hints (returnKeyType) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
9.2 KiB
DanceChamp — Technical Specification
1. Overview
A mobile platform for pole dance championships. Dancers discover events and track registration. Organizers create and manage championships. Platform admin oversees everything.
The Problem
Championship info is scattered across Instagram posts, Telegram chats, and Google Docs. Dancers miss deadlines, lose track of multi-step registration, and can't verify submissions went through. Organizers manually manage everything via spreadsheets and DMs.
The Solution
One app with three roles:
- Members browse championships, register, track 10-step progress
- Organizations create championships, configure rules/fees/categories, review videos, confirm payments
- Admin approves organizations, reviews championships from unverified orgs, manages users
Real-World Reference: "Zero Gravity"
International Pole Exotic Championship, Minsk, Belarus. Two disciplines (Exotic Pole Dance + Pole Art), 6+ levels per discipline, two-stage payment (video selection fee + championship fee), video selection with pass/fail, detailed judging criteria (6 categories, 0–10), strict costume/equipment rules, insurance required.
2. Roles & Permissions
Member (Dancer)
Access: Mobile app (member view)
- Browse & search championships
- View full details (rules, fees, categories, judges)
- Register for championships
- Track 10-step progress per championship
- Upload receipts & documents
- Receive notifications (results, deadline reminders, announcements)
- View past participation history
Cannot: Create/edit championships, see other members' data, access org/admin features
Organization
Access: Mobile app (org view)
- Create championships (quick create → configure tabs)
- Manage disciplines, levels, styles, fees, rules, scoring, judges
- View & manage registered members per championship
- Review videos (pass/fail)
- Confirm receipt payments
- Edit member's level/style (triggers notification)
- Publish results
- Send announcements
Cannot: See other orgs' data, access admin features
Admin
Access: Web admin panel
- View all orgs, championships, users
- Approve/reject pending organizations
- Approve/reject championships from unverified orgs
- Block/unblock orgs and users
- Warn users
- Verify organizations (changes approval policy)
- Delete any entity
- View platform stats and activity logs
3. Championship Lifecycle
[Org: Quick Create]
name + date + location → status: DRAFT
│
▼
[Org: Configure Tabs]
Categories ✓ → Fees ✓ → Rules ✓ → Judges ✓
(any order, mark each as done)
│
▼
[Org: "Go Live"]
│
├── Org is VERIFIED (🛡️)
│ → status: LIVE (auto-approved)
│ → visible to members immediately
│
└── Org is UNVERIFIED
→ status: PENDING_APPROVAL
→ admin sees in "Needs Attention"
→ admin approves → LIVE
→ admin rejects → BLOCKED
│
▼
[LIVE — Registration Open]
reg_start ≤ today ≤ reg_end
Members can register
│
▼
[Registration Closed]
today > reg_end
No new registrations
│
▼
[Event Day]
event_date
│
▼
[COMPLETED]
4. Championship Data Structure
Each championship contains:
Event Info
- Name, subtitle
- Event date (when it happens)
- Registration period: start date → end date (must be before event date)
- Location (city, country)
- Venue name
- Accent color (for branding)
Categories (configurable tab)
- Disciplines: e.g. "Exotic Pole Dance", "Pole Art"
- Levels per discipline: e.g. "Beginners", "Amateur", "Semi-Pro", "Profi", "Elite", "Duets & Groups"
- Styles: e.g. "Classic", "Flow", "Theater"
Fees (configurable tab)
- Video selection fee (e.g. "50 BYN / 1,500 RUB")
- Championship fees by type:
- Solo (e.g. "280 BYN / 7,500 RUB")
- Duet per person (e.g. "210 BYN / 5,800 RUB pp")
- Group per person (e.g. "190 BYN / 4,500 RUB pp")
- Refund note (typically non-refundable)
Rules (configurable tab)
- General rules (list of text items)
- Costume rules (list of text items)
- Scoring criteria: name + max score (e.g. "Artistry: 0–10", "Technique: 0–10")
- Penalties: name + value (e.g. "Fall: -2", "Exposure: DQ")
Judges (configurable tab)
- Judge profiles: name, Instagram handle, bio/description
- These are people, not scoring criteria
Members (only when LIVE)
- Registered members scoped to this championship
- Each with: discipline, level, style, type (solo/duet/group), progress steps, video URL, payment status, pass/fail result
5. Member Registration Flow (10 Steps)
Step 1: 📋 Review Rules → Auto (tracked when user opens Rules tab)
Step 2: 🎯 Select Category → Auto (saved from registration picker)
Step 3: 🎬 Record Video → Manual toggle ("I've recorded my video")
Step 4: 📝 Submit Video Form → Manual / link to Google Form
Step 5: 💳 Pay Video Fee → Upload receipt screenshot → Org confirms
Step 6: ⏳ Wait for Results → Pending until org decides
Step 7: 🏆 Results → Auto-updates on pass/fail
├── FAIL → Flow ends
└── PASS → Continue ▼
Step 8: 💰 Pay Championship Fee → Upload receipt → Org confirms
Step 9: 📄 Submit "About Me" → Manual / link to form
Step 10: 🛡️ Confirm Insurance → Upload document → Org confirms
└── ✅ REGISTERED!
Detection Methods
| Step | Method |
|---|---|
| Review rules | Auto — tracked on tab open |
| Select category | Auto — saved from picker |
| Record video | Manual toggle |
| Submit video form | Manual or Gmail auto-detect (future) |
| Pay video fee | Receipt upload → org confirms |
| Results | Auto — org pass/fail updates member |
| Pay championship fee | Receipt upload → org confirms |
| About Me form | Manual or Gmail auto-detect (future) |
| Insurance | Document upload → org confirms |
6. Notifications
Types
| Type | Trigger | Direction |
|---|---|---|
| 🔄 Category Changed | Org changes member's level/style | Org → Member |
| ✅ Payment Confirmed | Org confirms uploaded receipt | Org → Member |
| 🏆 Results | Org passes/fails video selection | Org → Member |
| ⏰ Deadline Reminder | Auto (7d, 3d, 1d before reg_end) | System → Member |
| 📋 Registration Confirmed | All 10 steps complete | System → Member |
| 📢 Announcement | Org sends broadcast | Org → All Members |
Delivery
- In-app: Bell icon with unread count, notification feed
- Push: Expo Notifications for critical updates
- Email: Future enhancement
7. Org App — Configurable Tabs
When org creates a championship, it starts as DRAFT with 5 configurable sections:
| Section | Tab | What to configure | Mark as Done when |
|---|---|---|---|
| Info | Overview | Name, dates, location, venue, reg period | Has date + location |
| Categories | Categories | Levels + styles | At least 1 level + 1 style |
| Fees | Fees | Video fee + championship fees | Video fee filled |
| Rules | Rules | General rules, costume rules, scoring criteria, penalties | At least 1 rule |
| Judges | Judges | Judge profiles (name, instagram, bio) | At least 1 judge |
Setup progress shown on Overview tab as checklist. Each section shows green dot (done) or yellow dot (pending) in tab bar. "Go Live" button appears when all 5 sections are ✓.
8. Admin — Approval Flow
Organization Approval
- New org registers → status:
pending - Admin reviews → Approve (status:
active) or Reject (status:blocked) - Admin can also verify an active org (🛡️ badge)
Championship Approval
- Depends on org's verification status:
- Verified org → Go Live = instant
live - Unverified org → Go Live =
pending_approval→ admin reviews
- Verified org → Go Live = instant
Admin Actions
| Entity | Actions |
|---|---|
| Organization | Approve, Reject, Block, Unblock, Verify, Delete |
| Championship | Approve, Reject, Suspend, Reinstate, Delete |
| User | Warn, Block, Unblock, Delete |
9. Org Settings
- Edit Organization Profile: name, instagram (inline edit form)
- Notification Preferences: toggles for push, email, registration alerts, payment alerts, deadline reminders
- Connected Accounts: Instagram (connected/not), Gmail, Telegram
- Help & Support
- Log Out
10. Search & Discovery (Member)
Members can find championships by:
- Text search (name, org name)
- Filters: discipline, location, status (Registration Open / Upcoming / Past)
- Sort: by date, by popularity
Championship cards show: name, org, dates, location, status badge, member count.
11. Future Features (Out of MVP Scope)
- Instagram parsing: auto-import championship data from org's posts
- Gmail integration: auto-detect Google Forms confirmations
- OCR results detection: parse results from Instagram photo posts
- In-app payments: replace receipt uploads
- In-app forms: replace Google Forms links
- Telegram monitoring: detect results from Telegram chats
- Category recommendation engine
- Calendar sync (export to phone calendar)
- Social features (see which friends are registered)
- Multi-language (Russian + English)