Files
ForbiddenStarsApp/backend/alembic/versions/0010_user_favorite_faction.py
NotBigGhostandClaude Opus 5 60b22dd8df Профиль: любимая фракция — выбор игрока, а не вывод из статистики
Раньше «любимая» вычислялась как самая частая среди партий с ручным
выбором фракции. Теперь это поле профиля: users.favorite_faction_id
(FK на factions, ON DELETE SET NULL, миграция 0010) и необязательное
поле в PATCH /api/users/me/profile.

Роутер профиля переведён на model_dump(exclude_unset=True) и обновляет
только пришедшие поля — иначе сохранение одного «о себе» обнуляло бы
выбранную фракцию.

«Основная фракция» логику не меняет (она и так считалась по всем партиям,
включая рандомные раздачи) и переезжает в подпись «Чаще всего играет на»:
FactionStat получает name_ru_prepositional из словаря предложного падежа
в faction_service. Словарь в коде, а не в БД: набор фракций задан игрой;
фракция вне словаря выводится в именительном.

Служебное chosen_games существовало только ради старой «любимой» — убрано
из SQL вместе с ней.

#17

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ps52xzuUXnWrJ5SRnEeaLk
2026-09-07 16:17:43 +03:00

47 lines
1.7 KiB
Python

"""Пользователь: любимая фракция (личный выбор в профиле).
Идемпотентна: на свежей БД столбец создаёт 0001 (create_all из актуальных моделей) -> no-op;
на существующей БД добавляет столбец. render_as_batch включён в env.py (для SQLite).
Revision ID: 0010_user_favorite_faction
Revises: 0009_participant_eliminated
Create Date: 2026-09-07
"""
from typing import Sequence, Union
import sqlalchemy as sa
from sqlalchemy import inspect
from alembic import op
revision: str = "0010_user_favorite_faction"
down_revision: Union[str, None] = "0009_participant_eliminated"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
bind = op.get_bind()
insp = inspect(bind)
cols = {c["name"] for c in insp.get_columns("users")}
if "favorite_faction_id" not in cols:
with op.batch_alter_table("users") as b:
b.add_column(sa.Column("favorite_faction_id", sa.Integer(), nullable=True))
b.create_foreign_key(
"fk_users_favorite_faction_id",
"factions",
["favorite_faction_id"],
["id"],
ondelete="SET NULL",
)
def downgrade() -> None:
bind = op.get_bind()
insp = inspect(bind)
cols = {c["name"] for c in insp.get_columns("users")}
if "favorite_faction_id" in cols:
with op.batch_alter_table("users") as b:
b.drop_constraint("fk_users_favorite_faction_id", type_="foreignkey")
b.drop_column("favorite_faction_id")