Add naming scheme selection to run configuration
Add a nullable naming_scheme column to NuzlockeRun so users can pick a themed word category for nickname suggestions. Includes Alembic migration, updated Pydantic schemas, a GET /runs/naming-categories endpoint backed by a cached dictionary loader, and frontend dropdowns in both the NewRun creation flow and the RunDashboard for mid-run changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
"""add naming_scheme to nuzlocke_runs
|
||||
|
||||
Revision ID: e5f6a7b8c9d1
|
||||
Revises: d4e5f6a7b9c0
|
||||
Create Date: 2026-02-11 12:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "e5f6a7b8c9d1"
|
||||
down_revision: str | Sequence[str] | None = "d4e5f6a7b9c0"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column(
|
||||
"nuzlocke_runs",
|
||||
sa.Column("naming_scheme", sa.String(50), nullable=True),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column("nuzlocke_runs", "naming_scheme")
|
||||
@@ -19,10 +19,16 @@ from app.schemas.run import (
|
||||
RunResponse,
|
||||
RunUpdate,
|
||||
)
|
||||
from app.services.naming import get_naming_categories
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/naming-categories", response_model=list[str])
|
||||
async def list_naming_categories():
|
||||
return get_naming_categories()
|
||||
|
||||
|
||||
@router.post("", response_model=RunResponse, status_code=201)
|
||||
async def create_run(data: RunCreate, session: AsyncSession = Depends(get_session)):
|
||||
# Validate game exists
|
||||
@@ -35,6 +41,7 @@ async def create_run(data: RunCreate, session: AsyncSession = Depends(get_sessio
|
||||
name=data.name,
|
||||
status="active",
|
||||
rules=data.rules,
|
||||
naming_scheme=data.naming_scheme,
|
||||
)
|
||||
session.add(run)
|
||||
await session.commit()
|
||||
|
||||
@@ -22,6 +22,7 @@ class NuzlockeRun(Base):
|
||||
)
|
||||
completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
hof_encounter_ids: Mapped[list[int] | None] = mapped_column(JSONB, default=None)
|
||||
naming_scheme: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
||||
|
||||
game: Mapped["Game"] = relationship(back_populates="runs")
|
||||
encounters: Mapped[list["Encounter"]] = relationship(back_populates="run")
|
||||
|
||||
@@ -9,6 +9,7 @@ class RunCreate(CamelModel):
|
||||
game_id: int
|
||||
name: str
|
||||
rules: dict = {}
|
||||
naming_scheme: str | None = None
|
||||
|
||||
|
||||
class RunUpdate(CamelModel):
|
||||
@@ -16,6 +17,7 @@ class RunUpdate(CamelModel):
|
||||
status: str | None = None
|
||||
rules: dict | None = None
|
||||
hof_encounter_ids: list[int] | None = None
|
||||
naming_scheme: str | None = None
|
||||
|
||||
|
||||
class RunResponse(CamelModel):
|
||||
@@ -25,6 +27,7 @@ class RunResponse(CamelModel):
|
||||
status: str
|
||||
rules: dict
|
||||
hof_encounter_ids: list[int] | None = None
|
||||
naming_scheme: str | None = None
|
||||
started_at: datetime
|
||||
completed_at: datetime | None
|
||||
|
||||
|
||||
18
backend/src/app/services/naming.py
Normal file
18
backend/src/app/services/naming.py
Normal file
@@ -0,0 +1,18 @@
|
||||
import json
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
|
||||
DICTIONARY_PATH = Path(__file__).resolve().parents[1] / "seeds" / "data" / "name_dictionary.json"
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def _load_dictionary() -> dict[str, list[str]]:
|
||||
if not DICTIONARY_PATH.exists():
|
||||
return {}
|
||||
with open(DICTIONARY_PATH) as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def get_naming_categories() -> list[str]:
|
||||
"""Return sorted list of available naming category names."""
|
||||
return sorted(_load_dictionary().keys())
|
||||
Reference in New Issue
Block a user