From 726acfa4ff04e794d84b80c28b635c314a60baa8 Mon Sep 17 00:00:00 2001 From: mwiegand Date: Sun, 10 May 2026 21:12:27 +0200 Subject: [PATCH] models: add User.active column for soft-delete (deactivation) Default true; server_default '1'. Lets the admin UI deactivate a user without losing the row or the user's content (servers, blueprints, overlays). Reactivation flips it back. Migration 0008 adds the column via op.add_column; downgrade uses batch_alter_table per SQLite ALTER TABLE semantics, matching the 0007 pattern. --- l4d2web/alembic/versions/0008_user_active.py | 33 ++++++++++++++++++++ l4d2web/models.py | 3 ++ 2 files changed, 36 insertions(+) create mode 100644 l4d2web/alembic/versions/0008_user_active.py diff --git a/l4d2web/alembic/versions/0008_user_active.py b/l4d2web/alembic/versions/0008_user_active.py new file mode 100644 index 0000000..dd3b13e --- /dev/null +++ b/l4d2web/alembic/versions/0008_user_active.py @@ -0,0 +1,33 @@ +"""users.active + +Revision ID: 0008_user_active +Revises: 0007_blueprint_overlay_expose_server_cfg +Create Date: 2026-05-10 +""" +from typing import Sequence, Union + +import sqlalchemy as sa +from alembic import op + + +revision: str = "0008_user_active" +down_revision: Union[str, Sequence[str], None] = "0007_blueprint_overlay_expose_server_cfg" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + op.add_column( + "users", + sa.Column( + "active", + sa.Boolean(), + nullable=False, + server_default=sa.text("1"), + ), + ) + + +def downgrade() -> None: + with op.batch_alter_table("users") as batch_op: + batch_op.drop_column("active") diff --git a/l4d2web/models.py b/l4d2web/models.py index 398543e..641dc56 100644 --- a/l4d2web/models.py +++ b/l4d2web/models.py @@ -30,6 +30,9 @@ class User(Base): username: Mapped[str] = mapped_column(String(64), unique=True, nullable=False) password_digest: Mapped[str] = mapped_column(String(255), nullable=False) admin: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False) + active: Mapped[bool] = mapped_column( + Boolean, default=True, nullable=False, server_default=text("1"), + ) created_at: Mapped[datetime] = mapped_column(DateTime, default=now_utc, nullable=False) updated_at: Mapped[datetime] = mapped_column(DateTime, default=now_utc, nullable=False)