DiscordGuildKeeper
進行中規格驅動開發的私人公會 Discord 管家 Bot,以 milestone 漸進交付動畫/票券訂閱、Gemini 問答與頻道摘要,部署於 Oracle Cloud ARM 免費資源。
專案概述
服務小型朋友群組的多功能 Discord 管家 Bot,以 Python 3.12 async 為核心,在單一專案內收斂 Backend / DB / Cache / Scheduler / Crawler / LLM / Container / CI/CD 的技術廣度。專案以一份權威工程規格書(PROJECT_SPEC.md)驅動,明訂 milestone 順序與每階段的 Definition of Done。目前已完成 M0 骨架與 M1 核心:discord.py 2.x 生命週期管理與 guild-scoped slash command 同步、FastAPI 健康檢查端點(/healthz、/readyz、/version)、SQLAlchemy 2.x async + asyncpg 與首版 Alembic migration、指令呼叫追蹤,以及多階段 linux/arm64 Docker image 與 GitHub Actions CI。M3–M6 的動畫爬蟲、票券監控與 Gemini LLM 功能已完成介面與資料模型設計,實作尚在規劃中。
關鍵亮點
- 規格驅動開發:撰寫一份 v2.0 權威工程規格書,涵蓋系統架構、資料模型、技術選型理由、milestone 順序與每階段 Definition of Done,並明列反模式(如禁止 mock 冒充真實 API 通過、production image 必須 arm64),作為實作的單一真實來源。
- 嚴謹的應用生命週期:main.py 以明確的啟動/關閉順序協調 FastAPI(uvicorn 作為 asyncio task)、Discord client、DB engine 與 Redis,自行接管 SIGINT/SIGTERM,並在 DISCORD_TOKEN 缺席時退化為 API-only 模式讓健康檢查持續運作。
- 為 OCI Always Free ARM 量身的部署管線:多階段 Docker build(uv 安裝、非 root 使用者、curl healthcheck),分離 dev/prod docker-compose,CI 跑 ruff + mypy strict + pytest 與 amd64 build smoke,正式部署則 build linux/arm64。
- 可觀測性與分層設計從第一天落地:結構化 JSON logging(structlog)、command_invocations 追蹤每次指令的延遲與狀態,並以 cogs(Discord adapter)/ services(業務邏輯)/ repositories(資料存取)/ crawlers(外部呼叫)的清楚分層約束可測試性。
技術棧
挑戰與取捨
最大的取捨是「先把工程地基做扎實,再逐步長出功能」:專案刻意以 milestone 推進(M0 骨架 → M1 lifecycle/health → M2 部署 → M3 動畫 → M4 LLM → M5 票券 → M6 observability),目前停在 M1 完成,M3–M6 的 service/crawler 檔案僅有 docstring 與規格引用、尚未實作,因此它呈現的是一個架構與規範完整、但功能仍在建構中的專案。技術層面的難點包含:在單一 async event loop 中協調 Discord gateway、uvicorn、scheduler 與 DB/Redis 的啟動與優雅關閉;為求快速迭代採用 guild-scoped slash command 同步而非全域(避免約一小時的傳播延遲);以及預先把爬蟲/LLM 的 rate limit、timeout、retry 與通知去重(notification_deliveries 唯一約束)納入資料模型設計,避免日後重構。另一個現實取捨是票券/動畫來源網站改版機率高,規格因此強制要求 crawler 必須有 fixture 測試、並尊重 robots.txt 與低頻率抓取,不做侵入式繞過。