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>
This commit is contained in:
Dianaka123
2026-03-01 22:09:10 +03:00
parent 96e02bf64a
commit d4f0a05707
44 changed files with 450 additions and 183 deletions

View File

@@ -1,7 +1,7 @@
import uuid
from datetime import datetime
from sqlalchemy import DateTime, Float, Integer, String, Text, Uuid, func
from sqlalchemy import DateTime, Float, ForeignKey, Integer, String, Text, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
@@ -11,6 +11,7 @@ class Championship(Base):
__tablename__ = "championships"
id: Mapped[uuid.UUID] = mapped_column(Uuid(as_uuid=True), primary_key=True, default=uuid.uuid4)
org_id: Mapped[uuid.UUID | None] = mapped_column(Uuid(as_uuid=True), ForeignKey("organizations.id", ondelete="SET NULL"))
title: Mapped[str] = mapped_column(String(255), nullable=False)
description: Mapped[str | None] = mapped_column(Text)
location: Mapped[str | None] = mapped_column(String(500))
@@ -37,5 +38,6 @@ class Championship(Base):
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
)
organization: Mapped["Organization | None"] = relationship(back_populates="championships") # type: ignore[name-defined]
registrations: Mapped[list["Registration"]] = relationship(back_populates="championship", cascade="all, delete-orphan") # type: ignore[name-defined]
participant_list: Mapped["ParticipantList | None"] = relationship(back_populates="championship", uselist=False, cascade="all, delete-orphan") # type: ignore[name-defined]