Changes: - Strip AI providers to image-only analysis (remove text/phishing methods) - Simplify guild models (remove BannedWord, reduce GuildSettings columns) - Create migration to drop unused tables and columns - Rewrite README for minimal bot focus - Update CLAUDE.md architecture documentation Result: -992 lines, +158 lines (net -834 lines) Cost-conscious bot ready for deployment.
215 lines
8.1 KiB
Python
215 lines
8.1 KiB
Python
"""Minimal bot cleanup - remove unused tables and columns.
|
|
|
|
Revision ID: 20260127_minimal_bot_cleanup
|
|
Revises: 20260125_add_whitelist
|
|
Create Date: 2026-01-27 00:00:00.000000
|
|
"""
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
from sqlalchemy.dialects import postgresql
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision = "20260127_minimal_bot_cleanup"
|
|
down_revision = "20260125_add_whitelist"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
"""Remove tables and columns not needed for minimal bot."""
|
|
# Drop unused tables
|
|
op.drop_table("user_activity")
|
|
op.drop_table("message_activity")
|
|
op.drop_table("ai_checks")
|
|
op.drop_table("banned_words")
|
|
op.drop_table("user_notes")
|
|
op.drop_table("strikes")
|
|
op.drop_table("moderation_logs")
|
|
|
|
# Drop unused columns from guild_settings
|
|
op.drop_column("guild_settings", "verification_enabled")
|
|
op.drop_column("guild_settings", "verification_type")
|
|
op.drop_column("guild_settings", "verified_role_id")
|
|
op.drop_column("guild_settings", "strike_actions")
|
|
op.drop_column("guild_settings", "mute_role_id")
|
|
op.drop_column("guild_settings", "mod_role_ids")
|
|
op.drop_column("guild_settings", "welcome_channel_id")
|
|
op.drop_column("guild_settings", "whitelisted_user_ids")
|
|
op.drop_column("guild_settings", "scam_allowlist")
|
|
op.drop_column("guild_settings", "send_in_channel_warnings")
|
|
op.drop_column("guild_settings", "ai_log_only")
|
|
op.drop_column("guild_settings", "ai_confidence_threshold")
|
|
op.drop_column("guild_settings", "log_channel_id")
|
|
op.drop_column("guild_settings", "mod_log_channel_id")
|
|
op.drop_column("guild_settings", "link_filter_enabled")
|
|
|
|
|
|
def downgrade() -> None:
|
|
"""Restore removed tables and columns (WARNING: Data will be lost!)."""
|
|
# Restore guild_settings columns
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("link_filter_enabled", sa.Boolean, nullable=False, default=False),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("mod_log_channel_id", sa.BigInteger, nullable=True),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("log_channel_id", sa.BigInteger, nullable=True),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("ai_confidence_threshold", sa.Float, nullable=False, default=0.7),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("ai_log_only", sa.Boolean, nullable=False, default=False),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("send_in_channel_warnings", sa.Boolean, nullable=False, default=False),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column(
|
|
"scam_allowlist",
|
|
postgresql.JSONB().with_variant(sa.JSON(), "sqlite"),
|
|
nullable=False,
|
|
default=list,
|
|
),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column(
|
|
"whitelisted_user_ids",
|
|
postgresql.JSONB().with_variant(sa.JSON(), "sqlite"),
|
|
nullable=False,
|
|
default=list,
|
|
),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("welcome_channel_id", sa.BigInteger, nullable=True),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column(
|
|
"mod_role_ids",
|
|
postgresql.JSONB().with_variant(sa.JSON(), "sqlite"),
|
|
nullable=False,
|
|
default=list,
|
|
),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("mute_role_id", sa.BigInteger, nullable=True),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column(
|
|
"strike_actions",
|
|
postgresql.JSONB().with_variant(sa.JSON(), "sqlite"),
|
|
nullable=False,
|
|
),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("verified_role_id", sa.BigInteger, nullable=True),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("verification_type", sa.String(20), nullable=False, default="button"),
|
|
)
|
|
op.add_column(
|
|
"guild_settings",
|
|
sa.Column("verification_enabled", sa.Boolean, nullable=False, default=False),
|
|
)
|
|
|
|
# Restore tables (empty, data lost)
|
|
op.create_table(
|
|
"moderation_logs",
|
|
sa.Column("id", sa.Integer, primary_key=True, autoincrement=True),
|
|
sa.Column("guild_id", sa.BigInteger, nullable=False),
|
|
sa.Column("user_id", sa.BigInteger, nullable=False),
|
|
sa.Column("moderator_id", sa.BigInteger, nullable=False),
|
|
sa.Column("action", sa.String(20), nullable=False),
|
|
sa.Column("reason", sa.Text, nullable=True),
|
|
sa.Column("created_at", sa.DateTime, nullable=False),
|
|
sa.ForeignKeyConstraint(["guild_id"], ["guilds.id"], ondelete="CASCADE"),
|
|
)
|
|
|
|
op.create_table(
|
|
"strikes",
|
|
sa.Column("id", sa.Integer, primary_key=True, autoincrement=True),
|
|
sa.Column("guild_id", sa.BigInteger, nullable=False),
|
|
sa.Column("user_id", sa.BigInteger, nullable=False),
|
|
sa.Column("reason", sa.Text, nullable=True),
|
|
sa.Column("created_at", sa.DateTime, nullable=False),
|
|
sa.ForeignKeyConstraint(["guild_id"], ["guilds.id"], ondelete="CASCADE"),
|
|
)
|
|
|
|
op.create_table(
|
|
"user_notes",
|
|
sa.Column("id", sa.Integer, primary_key=True, autoincrement=True),
|
|
sa.Column("guild_id", sa.BigInteger, nullable=False),
|
|
sa.Column("user_id", sa.BigInteger, nullable=False),
|
|
sa.Column("moderator_id", sa.BigInteger, nullable=False),
|
|
sa.Column("note", sa.Text, nullable=False),
|
|
sa.Column("created_at", sa.DateTime, nullable=False),
|
|
sa.ForeignKeyConstraint(["guild_id"], ["guilds.id"], ondelete="CASCADE"),
|
|
)
|
|
|
|
op.create_table(
|
|
"banned_words",
|
|
sa.Column("id", sa.Integer, primary_key=True, autoincrement=True),
|
|
sa.Column("guild_id", sa.BigInteger, nullable=False),
|
|
sa.Column("pattern", sa.Text, nullable=False),
|
|
sa.Column("is_regex", sa.Boolean, nullable=False, default=False),
|
|
sa.Column("action", sa.String(20), nullable=False, default="delete"),
|
|
sa.Column("reason", sa.Text, nullable=True),
|
|
sa.Column("source", sa.String(100), nullable=True),
|
|
sa.Column("category", sa.String(20), nullable=True),
|
|
sa.Column("managed", sa.Boolean, nullable=False, default=False),
|
|
sa.Column("added_by", sa.BigInteger, nullable=False),
|
|
sa.Column("created_at", sa.DateTime, nullable=False),
|
|
sa.Column("updated_at", sa.DateTime, nullable=False),
|
|
sa.ForeignKeyConstraint(["guild_id"], ["guilds.id"], ondelete="CASCADE"),
|
|
)
|
|
|
|
op.create_table(
|
|
"ai_checks",
|
|
sa.Column("id", sa.Integer, primary_key=True, autoincrement=True),
|
|
sa.Column("guild_id", sa.BigInteger, nullable=False),
|
|
sa.Column("user_id", sa.BigInteger, nullable=False),
|
|
sa.Column("message_id", sa.BigInteger, nullable=False),
|
|
sa.Column("check_type", sa.String(20), nullable=False),
|
|
sa.Column("flagged", sa.Boolean, nullable=False),
|
|
sa.Column("confidence", sa.Float, nullable=False),
|
|
sa.Column("created_at", sa.DateTime, nullable=False),
|
|
sa.ForeignKeyConstraint(["guild_id"], ["guilds.id"], ondelete="CASCADE"),
|
|
)
|
|
|
|
op.create_table(
|
|
"message_activity",
|
|
sa.Column("id", sa.Integer, primary_key=True, autoincrement=True),
|
|
sa.Column("guild_id", sa.BigInteger, nullable=False),
|
|
sa.Column("user_id", sa.BigInteger, nullable=False),
|
|
sa.Column("channel_id", sa.BigInteger, nullable=False),
|
|
sa.Column("message_count", sa.Integer, nullable=False),
|
|
sa.Column("date", sa.Date, nullable=False),
|
|
sa.ForeignKeyConstraint(["guild_id"], ["guilds.id"], ondelete="CASCADE"),
|
|
)
|
|
|
|
op.create_table(
|
|
"user_activity",
|
|
sa.Column("id", sa.Integer, primary_key=True, autoincrement=True),
|
|
sa.Column("guild_id", sa.BigInteger, nullable=False),
|
|
sa.Column("user_id", sa.BigInteger, nullable=False),
|
|
sa.Column("last_seen", sa.DateTime, nullable=False),
|
|
sa.Column("message_count", sa.Integer, nullable=False, default=0),
|
|
sa.ForeignKeyConstraint(["guild_id"], ["guilds.id"], ondelete="CASCADE"),
|
|
)
|