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:
@@ -1,4 +1,4 @@
|
||||
"""Seed script — creates test users and one championship.
|
||||
"""Seed script — creates test users, organization, and championships.
|
||||
Run from backend/: .venv/Scripts/python seed.py
|
||||
"""
|
||||
import asyncio
|
||||
@@ -7,6 +7,7 @@ from datetime import UTC, datetime, timedelta
|
||||
|
||||
from app.database import AsyncSessionLocal
|
||||
from app.models.championship import Championship
|
||||
from app.models.organization import Organization
|
||||
from app.models.user import User
|
||||
from app.services.auth_service import hash_password
|
||||
from sqlalchemy import select
|
||||
@@ -29,6 +30,7 @@ async def seed():
|
||||
"password": "Org1234",
|
||||
"role": "organizer",
|
||||
"status": "approved",
|
||||
"instagram_handle": "@ekaterina_pole",
|
||||
},
|
||||
{
|
||||
"email": "member@pole.dev",
|
||||
@@ -36,6 +38,7 @@ async def seed():
|
||||
"password": "Member1234",
|
||||
"role": "member",
|
||||
"status": "approved",
|
||||
"instagram_handle": "@anna_petrova",
|
||||
},
|
||||
{
|
||||
"email": "pending@pole.dev",
|
||||
@@ -57,11 +60,11 @@ async def seed():
|
||||
full_name=ud["full_name"],
|
||||
role=ud["role"],
|
||||
status=ud["status"],
|
||||
instagram_handle=ud.get("instagram_handle"),
|
||||
)
|
||||
db.add(user)
|
||||
print(f" Created user: {ud['email']}")
|
||||
else:
|
||||
# Update role/status if needed
|
||||
user.role = ud["role"]
|
||||
user.status = ud["status"]
|
||||
user.hashed_password = hash_password(ud["password"])
|
||||
@@ -70,6 +73,27 @@ async def seed():
|
||||
|
||||
await db.flush()
|
||||
|
||||
# ── Organization ──────────────────────────────────────────────────────
|
||||
organizer = created_users["organizer@pole.dev"]
|
||||
result = await db.execute(select(Organization).where(Organization.user_id == organizer.id))
|
||||
org = result.scalar_one_or_none()
|
||||
if org is None:
|
||||
org = Organization(
|
||||
user_id=organizer.id,
|
||||
name="Pole Studio Minsk",
|
||||
instagram="@polestudio_minsk",
|
||||
email="organizer@pole.dev",
|
||||
city="Minsk",
|
||||
verified=True,
|
||||
status="active",
|
||||
)
|
||||
db.add(org)
|
||||
print(f" Created organization: {org.name}")
|
||||
else:
|
||||
print(f" Organization already exists: {org.name}")
|
||||
|
||||
await db.flush()
|
||||
|
||||
# ── Championships ──────────────────────────────────────────────────────
|
||||
championships_data = [
|
||||
{
|
||||
@@ -115,11 +139,12 @@ async def seed():
|
||||
)
|
||||
champ = result.scalar_one_or_none()
|
||||
if champ is None:
|
||||
champ = Championship(**cd)
|
||||
champ = Championship(org_id=org.id, **cd)
|
||||
db.add(champ)
|
||||
print(f" Created championship: {cd['title']}")
|
||||
else:
|
||||
print(f" Championship already exists: {cd['title']}")
|
||||
champ.org_id = org.id
|
||||
print(f" Updated championship: {cd['title']}")
|
||||
|
||||
await db.commit()
|
||||
print("\nSeed complete!")
|
||||
|
||||
Reference in New Issue
Block a user