quick commit
Some checks failed
CI/CD Pipeline / Code Quality Checks (push) Failing after 6m9s
CI/CD Pipeline / Security Scanning (push) Successful in 26s
CI/CD Pipeline / Tests (3.11) (push) Failing after 5m24s
CI/CD Pipeline / Tests (3.12) (push) Failing after 5m23s
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Deploy to Staging (push) Has been skipped
CI/CD Pipeline / Deploy to Production (push) Has been skipped
CI/CD Pipeline / Notification (push) Successful in 1s

This commit is contained in:
2026-01-17 20:24:43 +01:00
parent 95cc3cdb8f
commit 831eed8dbc
82 changed files with 8860 additions and 167 deletions

View File

@@ -0,0 +1,125 @@
"""Add database indexes for performance and security.
Revision ID: 20260117_add_database_indexes
Revises: 20260117_add_automod_thresholds
Create Date: 2026-01-17 12:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "20260117_add_database_indexes"
down_revision = "20260117_add_automod_thresholds"
branch_labels = None
depends_on = None
def upgrade() -> None:
"""Add indexes for common query patterns and performance optimization."""
# Indexes for moderation_logs table
# Primary lookup patterns: by guild, by target user, by moderator, by timestamp
op.create_index("idx_moderation_logs_guild_id", "moderation_logs", ["guild_id"])
op.create_index("idx_moderation_logs_target_id", "moderation_logs", ["target_id"])
op.create_index("idx_moderation_logs_moderator_id", "moderation_logs", ["moderator_id"])
op.create_index("idx_moderation_logs_created_at", "moderation_logs", ["created_at"])
op.create_index("idx_moderation_logs_action", "moderation_logs", ["action"])
op.create_index("idx_moderation_logs_is_automatic", "moderation_logs", ["is_automatic"])
# Compound indexes for common filtering patterns
op.create_index("idx_moderation_logs_guild_target", "moderation_logs", ["guild_id", "target_id"])
op.create_index("idx_moderation_logs_guild_created", "moderation_logs", ["guild_id", "created_at"])
op.create_index("idx_moderation_logs_target_created", "moderation_logs", ["target_id", "created_at"])
# Indexes for strikes table
# Primary lookup patterns: by guild, by user, active strikes, expiration
op.create_index("idx_strikes_guild_id", "strikes", ["guild_id"])
op.create_index("idx_strikes_user_id", "strikes", ["user_id"])
op.create_index("idx_strikes_moderator_id", "strikes", ["moderator_id"])
op.create_index("idx_strikes_is_active", "strikes", ["is_active"])
op.create_index("idx_strikes_expires_at", "strikes", ["expires_at"])
op.create_index("idx_strikes_created_at", "strikes", ["created_at"])
# Compound indexes for active strike counting and user history
op.create_index("idx_strikes_guild_user_active", "strikes", ["guild_id", "user_id", "is_active"])
op.create_index("idx_strikes_user_active", "strikes", ["user_id", "is_active"])
op.create_index("idx_strikes_guild_active", "strikes", ["guild_id", "is_active"])
# Indexes for banned_words table
# Primary lookup patterns: by guild, by pattern (for admin management)
op.create_index("idx_banned_words_guild_id", "banned_words", ["guild_id"])
op.create_index("idx_banned_words_is_regex", "banned_words", ["is_regex"])
op.create_index("idx_banned_words_action", "banned_words", ["action"])
op.create_index("idx_banned_words_added_by", "banned_words", ["added_by"])
# Compound index for guild-specific lookups
op.create_index("idx_banned_words_guild_regex", "banned_words", ["guild_id", "is_regex"])
# Indexes for user_notes table (if it exists)
# Primary lookup patterns: by guild, by user, by moderator
op.create_index("idx_user_notes_guild_id", "user_notes", ["guild_id"])
op.create_index("idx_user_notes_user_id", "user_notes", ["user_id"])
op.create_index("idx_user_notes_moderator_id", "user_notes", ["moderator_id"])
op.create_index("idx_user_notes_created_at", "user_notes", ["created_at"])
# Compound indexes for user note history
op.create_index("idx_user_notes_guild_user", "user_notes", ["guild_id", "user_id"])
op.create_index("idx_user_notes_user_created", "user_notes", ["user_id", "created_at"])
# Indexes for guild_settings table
# These are mostly for admin dashboard filtering
op.create_index("idx_guild_settings_automod_enabled", "guild_settings", ["automod_enabled"])
op.create_index("idx_guild_settings_ai_enabled", "guild_settings", ["ai_moderation_enabled"])
op.create_index("idx_guild_settings_verification_enabled", "guild_settings", ["verification_enabled"])
# Indexes for guilds table
op.create_index("idx_guilds_owner_id", "guilds", ["owner_id"])
op.create_index("idx_guilds_premium", "guilds", ["premium"])
op.create_index("idx_guilds_created_at", "guilds", ["created_at"])
def downgrade() -> None:
"""Remove the indexes."""
# Remove all indexes in reverse order
op.drop_index("idx_guilds_created_at")
op.drop_index("idx_guilds_premium")
op.drop_index("idx_guilds_owner_id")
op.drop_index("idx_guild_settings_verification_enabled")
op.drop_index("idx_guild_settings_ai_enabled")
op.drop_index("idx_guild_settings_automod_enabled")
op.drop_index("idx_user_notes_user_created")
op.drop_index("idx_user_notes_guild_user")
op.drop_index("idx_user_notes_created_at")
op.drop_index("idx_user_notes_moderator_id")
op.drop_index("idx_user_notes_user_id")
op.drop_index("idx_user_notes_guild_id")
op.drop_index("idx_banned_words_guild_regex")
op.drop_index("idx_banned_words_added_by")
op.drop_index("idx_banned_words_action")
op.drop_index("idx_banned_words_is_regex")
op.drop_index("idx_banned_words_guild_id")
op.drop_index("idx_strikes_guild_active")
op.drop_index("idx_strikes_user_active")
op.drop_index("idx_strikes_guild_user_active")
op.drop_index("idx_strikes_created_at")
op.drop_index("idx_strikes_expires_at")
op.drop_index("idx_strikes_is_active")
op.drop_index("idx_strikes_moderator_id")
op.drop_index("idx_strikes_user_id")
op.drop_index("idx_strikes_guild_id")
op.drop_index("idx_moderation_logs_target_created")
op.drop_index("idx_moderation_logs_guild_created")
op.drop_index("idx_moderation_logs_guild_target")
op.drop_index("idx_moderation_logs_is_automatic")
op.drop_index("idx_moderation_logs_action")
op.drop_index("idx_moderation_logs_created_at")
op.drop_index("idx_moderation_logs_moderator_id")
op.drop_index("idx_moderation_logs_target_id")
op.drop_index("idx_moderation_logs_guild_id")