Files
PoleDanceApp/backend/app/crud/crud_user.py
Dianaka123 d4f0a05707 POL-127: Add organizations table and championship ownership
- Create organizations table with Alembic migration (3-phase: create table, migrate data, drop old column)
- Add org_id FK on championships linking to organizations
- Refactor all schemas into one-class-per-file packages (auth, championship, organization, participant, registration, user)
- Update CRUD layer with selectinload for organization relationships
- Update frontend types and components to use nested organization object
- Remove phantom Championship fields (subtitle, venue, accent_color) from frontend

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:09:10 +03:00

83 lines
2.7 KiB
Python

import uuid
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from app.models.organization import Organization
from app.models.user import User
from app.schemas.user import UserRegister, UserUpdate
from app.services.auth_service import hash_password
async def get_by_id(db: AsyncSession, user_id: str | uuid.UUID) -> User | None:
uid = user_id if isinstance(user_id, uuid.UUID) else uuid.UUID(str(user_id))
result = await db.execute(
select(User).where(User.id == uid).options(selectinload(User.organization))
)
return result.scalar_one_or_none()
async def get_by_email(db: AsyncSession, email: str) -> User | None:
result = await db.execute(
select(User).where(User.email == email.lower()).options(selectinload(User.organization))
)
return result.scalar_one_or_none()
async def create(db: AsyncSession, data: UserRegister) -> User:
user = User(
email=data.email.lower(),
hashed_password=hash_password(data.password),
full_name=data.full_name,
phone=data.phone,
instagram_handle=data.instagram_handle,
role=data.requested_role,
# Members are auto-approved; organizers require admin review
status="approved" if data.requested_role == "member" else "pending",
)
db.add(user)
await db.flush() # get user.id for the FK
# Create Organization row for organizer registrations
if data.requested_role == "organizer" and data.organization_name:
org = Organization(
user_id=user.id,
name=data.organization_name,
status="pending",
verified=False,
)
db.add(org)
await db.commit()
await db.refresh(user, attribute_names=["organization"])
return user
async def update(db: AsyncSession, user: User, data: UserUpdate) -> User:
user_fields = data.model_dump(exclude_none=True, exclude={"organization_name"})
for field, value in user_fields.items():
setattr(user, field, value)
# Route org field updates to Organization table
if data.organization_name is not None and user.organization:
user.organization.name = data.organization_name
await db.commit()
await db.refresh(user, attribute_names=["organization"])
return user
async def set_status(db: AsyncSession, user: User, status: str) -> User:
user.status = status
await db.commit()
await db.refresh(user)
return user
async def list_all(db: AsyncSession, skip: int = 0, limit: int = 100) -> list[User]:
result = await db.execute(
select(User).options(selectinload(User.organization)).offset(skip).limit(limit)
)
return list(result.scalars().all())