From 96e02bf64a2de169832c76ddb91b549e1c558a34 Mon Sep 17 00:00:00 2001 From: Dianaka123 Date: Sat, 28 Feb 2026 22:33:24 +0300 Subject: [PATCH] =?UTF-8?q?POL-126:=20Fix=20critical=20backend=20bugs=20?= =?UTF-8?q?=E2=80=94=20Championship=20model/DB=20mismatch,=20broken=20impo?= =?UTF-8?q?rts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Restore judges/categories TEXT columns to Championship model (were in DB but missing from model) - Remove phantom columns not in DB: org_id, subtitle, venue, accent_color - Remove broken relationships to unmigrated tables (Organization, Discipline, Style, Fee, Rule, Judge) - Remove broken instagram_service import from lifespan (file doesn't exist) - Add http://localhost:3000 to default CORS origins (web frontend) Model files for unmigrated tables kept on disk for future migration. Co-Authored-By: Claude Opus 4.6 --- backend/app/config.py | 2 +- backend/app/main.py | 16 +--------------- backend/app/models/__init__.py | 12 ------------ backend/app/models/championship.py | 15 +++------------ backend/app/models/user.py | 1 - 5 files changed, 5 insertions(+), 41 deletions(-) diff --git a/backend/app/config.py b/backend/app/config.py index 95719b4..58a9507 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -18,7 +18,7 @@ class Settings(BaseSettings): EXPO_ACCESS_TOKEN: str = "" - CORS_ORIGINS: str = "http://localhost:8081,exp://" + CORS_ORIGINS: str = "http://localhost:3000,http://localhost:8081,exp://" @property def cors_origins_list(self) -> list[str]: diff --git a/backend/app/main.py b/backend/app/main.py index 807f1fd..86e4728 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -1,5 +1,3 @@ -from contextlib import asynccontextmanager - from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware @@ -7,19 +5,7 @@ from app.config import settings from app.routers import auth, championships, registrations, participant_lists, users -@asynccontextmanager -async def lifespan(app: FastAPI): - # Start Instagram sync scheduler if configured - if settings.INSTAGRAM_USER_ID and settings.INSTAGRAM_ACCESS_TOKEN: - from app.services.instagram_service import start_scheduler - scheduler = start_scheduler() - yield - scheduler.shutdown() - else: - yield - - -app = FastAPI(title="Pole Dance Championships API", version="1.0.0", lifespan=lifespan) +app = FastAPI(title="Pole Dance Championships API", version="1.0.0") app.add_middleware( CORSMiddleware, diff --git a/backend/app/models/__init__.py b/backend/app/models/__init__.py index e20c15b..0fa623a 100644 --- a/backend/app/models/__init__.py +++ b/backend/app/models/__init__.py @@ -1,26 +1,14 @@ from app.models.user import User, RefreshToken -from app.models.organization import Organization from app.models.championship import Championship from app.models.registration import Registration from app.models.participant import ParticipantList from app.models.notification import NotificationLog -from app.models.discipline import Discipline -from app.models.style import Style -from app.models.fee import Fee -from app.models.rule import Rule -from app.models.judge import Judge __all__ = [ "User", "RefreshToken", - "Organization", "Championship", "Registration", "ParticipantList", "NotificationLog", - "Discipline", - "Style", - "Fee", - "Rule", - "Judge", ] diff --git a/backend/app/models/championship.py b/backend/app/models/championship.py index 13bc139..96f251d 100644 --- a/backend/app/models/championship.py +++ b/backend/app/models/championship.py @@ -1,7 +1,7 @@ import uuid from datetime import datetime -from sqlalchemy import DateTime, Float, ForeignKey, Integer, String, Text, Uuid, func +from sqlalchemy import DateTime, Float, Integer, String, Text, Uuid, func from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database import Base @@ -11,21 +11,18 @@ 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) - subtitle: Mapped[str | None] = mapped_column(String(255)) description: Mapped[str | None] = mapped_column(Text) location: Mapped[str | None] = mapped_column(String(500)) - venue: Mapped[str | None] = mapped_column(String(255)) event_date: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) registration_open_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) registration_close_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) - accent_color: Mapped[str | None] = mapped_column(String(20)) # hex color e.g. #FF5CA8 - # Legacy flat fields (kept for backwards compat, replaced by relational tables in POL-7 to POL-11) form_url: Mapped[str | None] = mapped_column(String(2048)) entry_fee: Mapped[float | None] = mapped_column(Float) video_max_duration: Mapped[int | None] = mapped_column(Integer) # seconds + judges: Mapped[str | None] = mapped_column(Text) # JSON string: [{name, bio, instagram}] + categories: Mapped[str | None] = mapped_column(Text) # JSON string: ["cat1", "cat2"] # Status: 'draft' | 'open' | 'closed' | 'completed' status: Mapped[str] = mapped_column(String(20), nullable=False, default="draft") @@ -40,11 +37,5 @@ 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] - disciplines: Mapped[list["Discipline"]] = relationship(back_populates="championship", cascade="all, delete-orphan") # type: ignore[name-defined] - styles: Mapped[list["Style"]] = relationship(back_populates="championship", cascade="all, delete-orphan") # type: ignore[name-defined] - fees: Mapped["Fee | None"] = relationship(back_populates="championship", uselist=False, cascade="all, delete-orphan") # type: ignore[name-defined] - rules: Mapped[list["Rule"]] = relationship(back_populates="championship", cascade="all, delete-orphan") # type: ignore[name-defined] - judges_list: Mapped[list["Judge"]] = relationship(back_populates="championship", cascade="all, delete-orphan") # type: ignore[name-defined] diff --git a/backend/app/models/user.py b/backend/app/models/user.py index f2a3a3a..15d80c1 100644 --- a/backend/app/models/user.py +++ b/backend/app/models/user.py @@ -30,7 +30,6 @@ class User(Base): refresh_tokens: Mapped[list["RefreshToken"]] = relationship(back_populates="user", cascade="all, delete-orphan") registrations: Mapped[list["Registration"]] = relationship(back_populates="user") # type: ignore[name-defined] notification_logs: Mapped[list["NotificationLog"]] = relationship(back_populates="user") # type: ignore[name-defined] - organization: Mapped["Organization | None"] = relationship(back_populates="user", uselist=False) # type: ignore[name-defined] class RefreshToken(Base):