本项目是 Telegram 自动消息服务端(FastAPI + Telethon + MySQL + APScheduler)。详细业务/架构/排障以仓库内 README.md 与 docs/*.zh-CN.md 为准;本文件只记录 Agent 容易踩坑的硬约束与速查信息。
入口:python main.py(main.py:1),由环境变量 MODE 决定:
MODE=api:启动 FastAPI,提供/api/v1/*业务接口、/web/*控制台(根路径/重定向到/web/dashboard,见app/web/__init__.py:44)、以及/static。MODE=pool:进入PoolRunner.run_forever()后台循环,不暴露业务 HTTP(app/startup.py:132)。
- 安装依赖:
pip install -r requirements.txt - 启动:
python main.py(依赖.env) - 测试:
python -m pytest -q(根目录无conftest.py,tests/e2e/conftest.py仅在跑 e2e 时用) - 数据库迁移:
alembic upgrade head(必须人工执行,禁止应用启动时自动迁移;alembic/README.md、README.md:330-336)
- 不要自动建表/自动迁移。应用启动不会建表,也不会跑 alembic。表结构变更必须:手动编辑模型 → 手动
alembic revision --autogenerate→ 人工审阅 → 手动alembic upgrade head。 MODE=pool启动即校验 Telegram 凭据:telegram_api_id > 0且telegram_api_hash非空,否则Settings直接抛ValueError(app/config.py:82-87)。jwt_secret_key禁止使用示例值。非测试环境下仍为change-this-in-production会启动失败(app/config.py:89-90)。测试里通过Settings(..., jwt_secret_key="unit-test-secret")构造,且PYTEST_CURRENT_TEST环境变量存在时才放行。- 多实例分片必须一致:
POOL_TOTAL_SHARDS在所有实例相同,POOL_SHARD_INDEX唯一且< POOL_TOTAL_SHARDS(app/config.py:78-79)。POOL_SHARD_GUARD_ENABLED=true时,启动后若检测到分片漂移会RuntimeError退出(app/worker/pool_runner.py:69-81)。 LOCAL_TEMP_DIR相对路径按项目根目录解析,不是 cwd(app/config.py:92-96)。Docker 部署建议映射到容器内固定目录,模板见README.md:351-359。- 错误分类是单一来源:
app/common/error_classifier.py返回ErrorClass+retryable+is_timeout。pool_runner与task_service必须调用该模块,不要在调用方再写一份error_text关键字判断(README.md:46-50)。 - 删除语义统一为软删除(账号/任务/规则/文件),保留审计。
- 层次:
app/api(协议)→app/service(业务)→app/repository(数据)→app/adapter(Telethon/S3/MySQL 外部封装)。 - 仓库方法命名遵循 JPA 风格:
FindBy*/ExistsBy*/CountBy*/DeleteBy*/UpdateBy*(docs/ARCHITECTURE.zh-CN.md:35)。 - Service / Worker / Scheduler 内部方法使用 PascalCase(如
ReloadActiveTasksToScheduler、AddOrReplaceIntervalJob、CleanupExpiredFiles),与 Python 习惯不同但项目内统一。 web子模块是 Jinja2 控制台(templates/、static/),与 JSON API 解耦;/web/*走 Cookie 会话,/api/v1/*走 Bearer JWT(README.md:235-239)。- 业务代码注释默认使用中文,标识符保持英文。
结构化 JSON 字段,键名固定:
scan_started/scan_completed/account_login_failed/account_login_retry_scheduled/pool_round_health/task_executedpool_round_health关键字段:success_rate、degraded、consecutive_degraded_rounds- 故障处理矩阵(
error_class→ 是否重试)见README.md:73-87;先看pool_round_health→scan_completed→account_login_failed(README.md:213)。
完整参数与档位见 README.md:21-66 和 .env.example。最常用:
MODE、APP_HOST、APP_PORT、LOG_LEVELPOOL_INSTANCE_ID、POOL_MAX_CONCURRENT_LOGINS、POOL_TOTAL_SHARDS、POOL_SHARD_INDEX、POOL_LOGIN_SCAN_INTERVAL_SECONDSMYSQL_DSN(MySQL DSN,无默认值以外的兜底。注:必须配置同步链接格式如mysql+pymysql://,因为 Alembic 迁移是同步的。应用在异步运行时会自动将其转换为异步驱动连接,如aiomysql或aiosqlite)TELEGRAM_API_ID、TELEGRAM_API_HASH(pool 模式必填)S3_*(endpoint、ak/sk、bucket、region)LOCAL_TEMP_DIR、LOCAL_TEMP_MAX_BYTES(默认 5GB)、LOCAL_TEMP_RETENTION_HOURS(默认 168h/7d)、LOCAL_CLEANUP_INTERVAL_MINUTES(默认 60)JWT_SECRET_KEY(必须改)
- 跑全量
pytest时get_settings()会被lru_cache缓存,跨测试可能共享状态;如改MODE、DSN 等需要清缓存或重开进程。 tests/e2e/conftest.py自带 SQLite 适配(BigInteger编译为INTEGER)并独立起127.0.0.1:8099的 uvicorn。生产 MySQL 不会用到这个 conftest。- 现有测试是单元/集成为主,e2e 仅覆盖
/api/v1/users鉴权流程(tests/e2e/test_auth.py)。
- AI 交互语言:所有 AI 回复、原理解释、TODO 项、确认问题均必须使用简体中文。
- 语言切换约束:除非用户在当前对话中明确要求,否则不得自动切换为英文或其他语言。
- 标识符与注释:代码标识符保持英文,代码注释必须使用中文。
- Git 提交规范:Git 的提交信息(Commit Message)必须使用简体中文进行描述。
- 架构与分层:
docs/ARCHITECTURE.zh-CN.md - 值班排障手册:
docs/OPERATIONS.zh-CN.md - 值班速查 / 夜班极简速查:
docs/ONCALL-CHEATSHEET.zh-CN.md、docs/ONCALL-NIGHT-SHORT.zh-CN.md - 接口请求/响应示例:
docs/API-EXAMPLES.zh-CN.md