Files
PoleDanceApp/backend/app/crud/crud_registration.py
Dianaka123 789d2bf0a6 Full app rebuild: FastAPI backend + React Native mobile with auth, championships, admin
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>
2026-02-25 22:46:50 +03:00

87 lines
2.8 KiB
Python

import uuid
from datetime import UTC, datetime
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from app.models.registration import Registration
from app.schemas.registration import RegistrationCreate, RegistrationUpdate
async def get(db: AsyncSession, reg_id: str | uuid.UUID) -> Registration | None:
rid = reg_id if isinstance(reg_id, uuid.UUID) else uuid.UUID(str(reg_id))
result = await db.execute(
select(Registration).where(Registration.id == rid).options(selectinload(Registration.user))
)
return result.scalar_one_or_none()
async def get_by_user_and_championship(
db: AsyncSession, user_id: uuid.UUID, championship_id: uuid.UUID
) -> Registration | None:
result = await db.execute(
select(Registration).where(
Registration.user_id == user_id,
Registration.championship_id == championship_id,
)
)
return result.scalar_one_or_none()
async def list_for_championship(
db: AsyncSession, championship_id: str | uuid.UUID, skip: int = 0, limit: int = 100
) -> list[Registration]:
cid = championship_id if isinstance(championship_id, uuid.UUID) else uuid.UUID(str(championship_id))
result = await db.execute(
select(Registration)
.where(Registration.championship_id == cid)
.options(selectinload(Registration.user))
.offset(skip)
.limit(limit)
)
return list(result.scalars().all())
async def list_for_user(db: AsyncSession, user_id: uuid.UUID, skip: int = 0, limit: int = 50) -> list[Registration]:
result = await db.execute(
select(Registration)
.where(Registration.user_id == user_id)
.options(selectinload(Registration.championship))
.order_by(Registration.submitted_at.desc())
.offset(skip)
.limit(limit)
)
return list(result.scalars().all())
async def create(db: AsyncSession, user_id: uuid.UUID, data: RegistrationCreate) -> Registration:
reg = Registration(
championship_id=data.championship_id,
user_id=user_id,
category=data.category,
level=data.level,
notes=data.notes,
status="submitted",
)
db.add(reg)
await db.commit()
await db.refresh(reg)
return reg
async def update(db: AsyncSession, reg: Registration, data: RegistrationUpdate) -> Registration:
raw = data.model_dump(exclude_none=True)
for field, value in raw.items():
setattr(reg, field, value)
if "status" in raw and raw["status"] in ("accepted", "rejected", "waitlisted"):
reg.decided_at = datetime.now(UTC)
await db.commit()
await db.refresh(reg)
return reg
async def delete(db: AsyncSession, reg: Registration) -> None:
await db.delete(reg)
await db.commit()