diff --git a/l4d2web/alembic/versions/0012_command_history.py b/l4d2web/alembic/versions/0012_command_history.py new file mode 100644 index 0000000..fee821e --- /dev/null +++ b/l4d2web/alembic/versions/0012_command_history.py @@ -0,0 +1,48 @@ +"""add command_history table + +Revision ID: 0012_command_history +Revises: 0011_server_hostname +Create Date: 2026-05-14 +""" +from __future__ import annotations + +from typing import Sequence, Union + +import sqlalchemy as sa +from alembic import op + + +revision: str = "0012_command_history" +down_revision: Union[str, Sequence[str], None] = "0011_server_hostname" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + op.create_table( + "command_history", + sa.Column("id", sa.Integer(), primary_key=True), + sa.Column("user_id", sa.Integer(), sa.ForeignKey("users.id"), nullable=False), + sa.Column( + "server_id", + sa.Integer(), + sa.ForeignKey("servers.id", ondelete="CASCADE"), + nullable=False, + ), + sa.Column("command", sa.Text(), nullable=False), + sa.Column("reply", sa.Text(), nullable=False, server_default=""), + sa.Column( + "is_error", sa.Boolean(), nullable=False, server_default=sa.text("0") + ), + sa.Column("created_at", sa.DateTime(), nullable=False), + ) + op.create_index( + "ix_cmdhist_user_server_id", + "command_history", + ["user_id", "server_id", "id"], + ) + + +def downgrade() -> None: + op.drop_index("ix_cmdhist_user_server_id", table_name="command_history") + op.drop_table("command_history") diff --git a/l4d2web/models.py b/l4d2web/models.py index 029c90d..f43fd32 100644 --- a/l4d2web/models.py +++ b/l4d2web/models.py @@ -227,3 +227,26 @@ class SteamUserProfile(Base): persona_name: Mapped[str] = mapped_column(String(64), nullable=False) avatar_url: Mapped[str] = mapped_column(Text, nullable=False) fetched_at: Mapped[datetime] = mapped_column(DateTime, nullable=False) + + +class CommandHistory(Base): + __tablename__ = "command_history" + __table_args__ = ( + Index("ix_cmdhist_user_server_id", "user_id", "server_id", "id"), + ) + + id: Mapped[int] = mapped_column(Integer, primary_key=True) + user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) + server_id: Mapped[int] = mapped_column( + ForeignKey("servers.id", ondelete="CASCADE"), nullable=False + ) + command: Mapped[str] = mapped_column(Text, nullable=False) + reply: Mapped[str] = mapped_column( + Text, nullable=False, default="", server_default="" + ) + is_error: Mapped[bool] = mapped_column( + Boolean, nullable=False, default=False, server_default=text("0") + ) + created_at: Mapped[datetime] = mapped_column( + DateTime, default=now_utc, nullable=False + )