# Discord Bot v2.0 SBA fantasy league Discord bot. discord.py with async Python, Pydantic models, FastAPI backend. ## Commands - Run: `python bot.py` - Test: `python -m pytest --tb=short -q` - Test specific: `python -m pytest tests/test_services.py -v` ## IMPORTANT: Patterns That Prevent Real Bugs ### Docker Hub Repository Name ``` manticorum67/major-domo-discordapp ``` There is NO DASH between "discord" and "app". Not `discord-app`, not `discordapp-v2`. ### Git Workflow NEVER commit directly to `main`. Always use feature branches: ```bash git checkout -b feature/name # or fix/name ``` ### Double Emoji in Embeds `EmbedTemplate.success/error/warning/info/loading()` auto-add emoji prefixes. - Do NOT put emoji in the `title` parameter of these methods (causes double emoji) - Use `EmbedTemplate.create_base_embed()` when you want custom emoji in titles ### Autocomplete Functions Define autocomplete as standalone functions OUTSIDE the class, not as methods. - See `commands/players/info.py:20-67` for canonical example ### Model Requirements - Database entities require `id` fields: `Player(id=123, ...)`, `Team(id=456, ...)` - Use explicit None checks (`if obj is None:`) not `if not obj:` - Use "Raise or Return" pattern - don't return Optional unless specifically required ### New Commands Must Use ```python from utils.decorators import logged_command from utils.logging import get_contextual_logger class MyCog(commands.Cog): def __init__(self, bot): self.bot = bot self.logger = get_contextual_logger(f'{__name__}.MyCog') # Required @discord.app_commands.command(name="example") @logged_command("/example") async def example(self, interaction, param: str): # Business logic only - decorator handles logging, timing, errors ``` ## Deployment & Troubleshooting ### Production - **Host**: `ssh akamai` → `cd container-data/major-domo` - **Container**: `major-domo-discord-app-1` - **Image**: `manticorum67/major-domo-discordapp` (no dash between discord and app) - **Health**: Process liveness only (no HTTP endpoint) - **CI/CD**: Gitea Actions on PR to `main` — builds Docker image, auto-generates CalVer version (`YYYY.MM.BUILD`) on merge - **Other services on same host**: `sba_db_api`, `sba_postgres`, `sba_redis`, `sba-website-sba-web-1`, `pd_api` ### Logs - **Container logs**: `ssh akamai "docker logs --since 1h major-domo-discord-app-1"` - **Log file (in container)**: `/app/logs/discord_bot_v2.json` (JSON structured, rotating, 10MB max) - **Host mount**: `./logs/discord_bot_v2.json` ### Key Env Vars `BOT_TOKEN`, `API_TOKEN`, `DB_URL`, `GUILD_ID`, `LOG_LEVEL`, `ENVIRONMENT`, `REDIS_URL` (optional) ### Common Issues - Bot not responding → check `docker logs`, verify `BOT_TOKEN` and `GUILD_ID` - API errors → verify `DB_URL` points to correct database API and `API_TOKEN` matches - Redis errors are non-fatal (graceful fallback when `REDIS_URL` is empty) ## API Reference - OpenAPI spec: https://sba.manticorum.com/api/openapi.json (use WebFetch for current endpoints) ## Sub-directory Documentation Each package has its own CLAUDE.md with detailed patterns: `commands/`, `services/`, `models/`, `views/`, `tasks/`, `tests/`, `utils/`