left4me/l4d2web/alembic/versions/0006_server_name_per_user.py
mwiegand 1166e13e44
feat(l4d2-web): server identity by id, name as display label
Host-side identifier (systemd unit name and /var/lib/left4me dirs) is now
str(server.id), centralized in services/server_identity.server_unit_name.
Server.name becomes a free-form display label, required and unique per
user (was [a-z0-9_-]{1,64} and globally unique).

Migration 0006 swaps the old global UNIQUE(name) for UNIQUE(user_id, name).
Web routes already keyed on id; templates only used name for display.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 19:22:09 +02:00

44 lines
1.4 KiB
Python

"""server name unique per user
Revision ID: 0006_server_name_per_user
Revises: 0005_script_overlays
Create Date: 2026-05-08
"""
from typing import Sequence, Union
from alembic import op
revision: str = "0006_server_name_per_user"
down_revision: Union[str, Sequence[str], None] = "0005_script_overlays"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
# 0001_initial defined `name` with column-level `unique=True`, which SQLite
# stored as an unnamed UNIQUE constraint. The naming_convention here lets
# batch_alter_table refer to it as "uq_servers_name" so we can drop it before
# recreating the table with the new (user_id, name) composite.
_NAMING_CONVENTION = {"uq": "uq_%(table_name)s_%(column_0_name)s"}
def upgrade() -> None:
with op.batch_alter_table(
"servers",
naming_convention=_NAMING_CONVENTION,
recreate="always",
) as batch_op:
batch_op.drop_constraint("uq_servers_name", type_="unique")
batch_op.create_unique_constraint(
"uq_servers_user_name", ["user_id", "name"]
)
def downgrade() -> None:
with op.batch_alter_table(
"servers",
naming_convention=_NAMING_CONVENTION,
recreate="always",
) as batch_op:
batch_op.drop_constraint("uq_servers_user_name", type_="unique")
batch_op.create_unique_constraint("uq_servers_name", ["name"])