Pole Dance Championships App — Technical Document
1. Project Overview
Problem
Pole dance championships lack dedicated tools for organizers and participants. Organizers rely on Instagram posts to announce events, and registrations are managed via Google Forms — leading to:
- No visibility — Participants can't track their registration status in one place.
- Scattered info — Dates, rules, and results are buried across Instagram posts.
- No access control — Anyone can register; organizers need a way to accept or reject participants.
Solution
A members-only mobile app for pole dance championship participants and organizers.
- New users register and wait for admin approval before accessing the app.
- Championship announcements are auto-imported from Instagram (Graph API).
- Members browse championships, submit registrations, and track their status.
- Organizers accept, reject, or waitlist participants and publish the final participant list.
- Push notifications alert members when results are published.
2. User Roles
| Role |
Access |
| Member |
Browse championships, register, track own registration status |
| Organizer |
All of the above + manage registrations, publish participant lists |
| Admin |
All of the above + approve/reject new member accounts |
New accounts start as pending and must be approved by an admin before they can use the app.
3. Tech Stack
| Layer |
Technology |
| Mobile |
React Native + TypeScript (Expo managed workflow) |
| Navigation |
React Navigation v6 |
| Server state |
TanStack React Query v5 |
| Client state |
Zustand |
| Backend |
FastAPI (Python, async) |
| ORM |
SQLAlchemy 2.0 async |
| Database |
SQLite (local dev) / PostgreSQL (production) |
| Migrations |
Alembic |
| Auth |
JWT — access tokens (15 min) + refresh tokens (7 days, rotation-based) |
| Instagram sync |
Instagram Graph API, polled every 30 min via APScheduler |
| Push notifications |
Expo Push API (routes to FCM + APNs) |
| Token storage |
expo-secure-store (with in-memory cache for reliability) |
4. Architecture
5. Data Model
User
Championship
Registration
ParticipantList
RefreshToken
NotificationLog
6. API Endpoints
Auth
| Method |
Path |
Description |
| POST |
/api/v1/auth/register |
Register new account (status=pending) |
| POST |
/api/v1/auth/login |
Login, get access + refresh tokens |
| POST |
/api/v1/auth/refresh |
Refresh access token |
| POST |
/api/v1/auth/logout |
Revoke refresh token |
| GET |
/api/v1/auth/me |
Get current user |
Championships
| Method |
Path |
Access |
| GET |
/api/v1/championships |
Approved members |
| GET |
/api/v1/championships/{id} |
Approved members |
| POST |
/api/v1/championships |
Organizer+ |
| PATCH |
/api/v1/championships/{id} |
Organizer+ |
| DELETE |
/api/v1/championships/{id} |
Admin |
Registrations
| Method |
Path |
Access |
| POST |
/api/v1/championships/{id}/register |
Approved member |
| GET |
/api/v1/championships/{id}/registrations |
Organizer+ |
| PATCH |
/api/v1/registrations/{id}/status |
Organizer+ |
| GET |
/api/v1/registrations/mine |
Member (own only) |
| DELETE |
/api/v1/registrations/{id} |
Member (own, before decision) |
Participant Lists
| Method |
Path |
Access |
| GET |
/api/v1/championships/{id}/participant-list |
Approved member |
| PUT |
/api/v1/championships/{id}/participant-list |
Organizer+ |
| POST |
/api/v1/championships/{id}/participant-list/publish |
Organizer+ |
| POST |
/api/v1/championships/{id}/participant-list/unpublish |
Organizer+ |
Users (Admin)
| Method |
Path |
Description |
| GET |
/api/v1/users |
List all users |
| PATCH |
/api/v1/users/{id}/status |
Approve/reject member |
| PATCH |
/api/v1/users/me/push-token |
Register push token |
7. Mobile Screens
Auth Flow
- LoginScreen — Email + password login
- RegisterScreen — Full name, phone, email, password
- PendingApprovalScreen — Shown after register until admin approves
App (approved members)
- ChampionshipListScreen — All championships with status badges
- ChampionshipDetailScreen — Full info + registration button
- RegistrationFormScreen — Category, level, notes
- ProfileScreen — User info, logout
Navigation
8. Instagram Integration
How It Works
- Admin configures
INSTAGRAM_USER_ID and INSTAGRAM_ACCESS_TOKEN in .env.
- APScheduler polls the Instagram Graph API every 30 minutes.
- New media posts are parsed: title (first line of caption), location (
Место: / Location: prefix), dates (regex for RU + EN date formats).
- New championships are created with
status=draft for admin review.
- Long-lived tokens are refreshed weekly automatically.
Parsing Logic
- Title — First non-empty line of the caption.
- Location — Line starting with
Место: or Location:.
- Date — Regex matches formats like
15 апреля 2026, April 15, 2026, 15.04.2026.
- Deduplication — Championships are matched by
instagram_media_id.
9. Local Development Setup
Prerequisites
- Python 3.11+
- Node.js 18+
- Expo Go app on phone
Backend
Or use: start-backend.bat
Mobile
Or use: start-mobile.bat
Environment (backend/.env)
Environment (mobile/.env)
Test Accounts
10. Known Limitations (Local Dev)
- SQLite is used instead of PostgreSQL — change
DATABASE_URL for production.
- Push notifications don't work in Expo Go SDK 53 — requires a development build.
- Instagram polling requires a valid Business/Creator account token.
- Windows Firewall must allow inbound TCP on port 8000 for phone to reach the backend.
11. Future Features
- Web admin panel — Browser-based dashboard for organizers to manage registrations and championships.
- In-app notifications feed — History of received push notifications.
- Calendar sync — Export championship dates to phone calendar.
- Production deployment — Docker + PostgreSQL + nginx + SSL.
- OCR / LLM parsing — Better extraction of championship details from Instagram images and captions.
- Multi-organizer — Support multiple Instagram accounts for different championships.