# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview GuardDen is a minimal, cost-conscious Discord moderation bot focused on spam detection and NSFW image filtering. Built with discord.py, PostgreSQL, and optional AI integration (Claude/OpenAI) for image analysis only. Self-hosted with Docker support. ## Commands ```bash # Install dependencies pip install -e ".[dev,ai]" # Run the bot python -m guardden # Run tests pytest # Run single test pytest tests/test_automod.py::TestAutomodService::test_spam_detection # Lint and format ruff check src tests ruff format src tests # Type checking mypy src # Docker deployment docker compose up -d # Database migrations alembic upgrade head ``` ## Architecture - `src/guardden/bot.py` - Main bot class (`GuardDen`) extending `commands.Bot`, manages lifecycle and services - `src/guardden/config.py` - Pydantic settings loaded from environment variables (prefix: `GUARDDEN_`) - `src/guardden/models/guild.py` - SQLAlchemy 2.0 async models for guilds and settings - `src/guardden/services/` - Business logic (database, guild config, automod, AI, rate limiting) - `src/guardden/cogs/` - Discord command groups (automod, ai_moderation, owner) - `config.yml` - Single YAML file for bot configuration ## Key Patterns - All database operations use async SQLAlchemy with `asyncpg` - Guild configurations loaded from single `config.yml` file (not per-guild) - Discord snowflake IDs stored as `BigInteger` in PostgreSQL - No moderation logging or strike system - Environment variables: `GUARDDEN_DISCORD_TOKEN`, `GUARDDEN_DATABASE_URL`, AI keys ## Automod System - `AutomodService` in `services/automod.py` handles spam detection - Checks: message rate limit → duplicate messages → mass mentions - Spam tracking uses per-guild, per-user trackers with automatic cleanup - Results return `AutomodResult` dataclass with actions to take - Everyone gets moderated (no whitelist, no bypass for permissions) ## AI Moderation System - `services/ai/` contains provider abstraction and implementations - `AIProvider` base class defines interface: `analyze_image()` only - `AnthropicProvider` and `OpenAIProvider` implement the interface - `NullProvider` used when AI is disabled (returns empty results) - Factory pattern via `create_ai_provider(provider, api_key)` - `ImageAnalysisResult` includes NSFW categories, severity, confidence - Sensitivity setting (0-100) adjusts thresholds - **NSFW-Only Filtering** (default: `True`): Only sexual content is filtered - **Cost Controls**: Rate limiting, deduplication, file size limits, max images per message - `AIRateLimiter` in `services/ai_rate_limiter.py` tracks usage ## Adding New Cogs 1. Create file in `src/guardden/cogs/` 2. Implement `setup(bot)` async function 3. Add cog path to `_load_cogs()` in `bot.py` ## Adding New AI Provider 1. Create `src/guardden/services/ai/newprovider.py` 2. Implement `AIProvider` abstract class 3. Add to factory in `services/ai/factory.py` 4. Add config option in `config.py`