delete agent type (#66)

* delete agent type

* more filters

---------

Co-authored-by: Kartik Sarangmath <kartiksarangmath@Kartiks-MacBook-Air.local>
This commit is contained in:
ksarangmath
2025-08-11 00:25:35 -07:00
committed by GitHub
parent 23b37cc7d3
commit 804d458583
6 changed files with 151 additions and 27 deletions

View File

@@ -0,0 +1,67 @@
"""Add soft delete to user agents
Revision ID: 9f61865b8ba8
Revises: 2e2f1b18e835
Create Date: 2025-08-10 22:22:28.432623
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = "9f61865b8ba8"
down_revision: Union[str, None] = "2e2f1b18e835"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
# Add column as nullable first with server default
op.add_column(
"user_agents",
sa.Column(
"is_deleted", sa.Boolean(), server_default=sa.text("FALSE"), nullable=True
),
)
# Set default value for existing rows (in case any are NULL)
op.execute("UPDATE user_agents SET is_deleted = FALSE WHERE is_deleted IS NULL")
# Now make the column NOT NULL
op.alter_column(
"user_agents", "is_deleted", nullable=False, server_default=sa.text("FALSE")
)
op.drop_constraint(
op.f("uq_user_agents_user_id_name"), "user_agents", type_="unique"
)
op.create_index(
"uq_user_agents_user_id_name",
"user_agents",
["user_id", "name"],
unique=True,
postgresql_where=sa.text("is_deleted = FALSE"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(
"uq_user_agents_user_id_name",
table_name="user_agents",
postgresql_where=sa.text("is_deleted = FALSE"),
)
op.create_unique_constraint(
op.f("uq_user_agents_user_id_name"),
"user_agents",
["user_id", "name"],
postgresql_nulls_not_distinct=False,
)
op.drop_column("user_agents", "is_deleted")
# ### end Alembic commands ###

View File

@@ -2,7 +2,7 @@ from datetime import datetime, timezone
from uuid import UUID, uuid4
from typing import TYPE_CHECKING
from sqlalchemy import ForeignKey, Index, String, Text, UniqueConstraint
from sqlalchemy import ForeignKey, Index, String, Text, text
from sqlalchemy.dialects.postgresql import UUID as PostgresUUID, JSONB
from sqlalchemy.orm import (
DeclarativeBase, # type: ignore[attr-defined]
@@ -77,7 +77,14 @@ class User(Base):
class UserAgent(Base):
__tablename__ = "user_agents"
__table_args__ = (
UniqueConstraint("user_id", "name", name="uq_user_agents_user_id_name"),
# Partial unique index: only enforce uniqueness for non-deleted agents
Index(
"uq_user_agents_user_id_name",
"user_id",
"name",
unique=True,
postgresql_where=text("is_deleted = FALSE"),
),
Index("ix_user_agents_user_id", "user_id"),
)
@@ -91,6 +98,7 @@ class UserAgent(Base):
webhook_url: Mapped[str | None] = mapped_column(Text, default=None)
webhook_api_key: Mapped[str | None] = mapped_column(Text, default=None) # Encrypted
is_active: Mapped[bool] = mapped_column(default=True)
is_deleted: Mapped[bool] = mapped_column(default=False) # Soft delete flag
created_at: Mapped[datetime] = mapped_column(
default=lambda: datetime.now(timezone.utc)
)