Resolve conflict in views/trade_embed.py: keep main's hotfix (emoji-stripped UI, inline validation errors) and apply next-release's import refactor (lazy imports hoisted to top-level). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
112 lines
4.5 KiB
Markdown
112 lines
4.5 KiB
Markdown
# 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` or `next-release`. Always use feature branches.
|
|
|
|
**Branch from `next-release`** for normal work targeting the next release:
|
|
```bash
|
|
git checkout -b feature/name origin/next-release # or fix/name, refactor/name
|
|
```
|
|
**Branch from `main`** only for urgent hotfixes that bypass the release cycle.
|
|
|
|
PRs go to `next-release` (staging), then `next-release → main` when releasing.
|
|
|
|
### 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
|
|
|
|
### Release Workflow
|
|
1. Create feature/fix branches off `next-release` (e.g., `fix/scorebug-bugs`)
|
|
2. When done, merge the branch into `next-release` — this is the staging branch where changes accumulate
|
|
3. When ready to release, open a PR from `next-release` → `main`
|
|
4. CI builds Docker image on PR; CalVer tag is created on merge
|
|
5. Deploy the new image to production (see `/deploy` skill)
|
|
- **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)
|
|
|
|
## Dependencies
|
|
|
|
### Pinning Policy
|
|
All dependencies are pinned to exact versions (`==`). This ensures every Docker build
|
|
produces an identical image — a `git revert` actually rolls back to the previous working state.
|
|
|
|
- **`requirements.txt`** — production runtime deps only (used by Dockerfile)
|
|
- **`requirements-dev.txt`** — includes `-r requirements.txt` plus dev/test tools
|
|
|
|
When installing for local development or running tests:
|
|
```bash
|
|
pip install -r requirements-dev.txt
|
|
```
|
|
|
|
When upgrading a dependency, update BOTH the `==` pin and (if applicable) the comment in
|
|
the file. Test before committing. Never use `>=` or `~=` constraints.
|
|
|
|
## 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/`
|