From c02aa8941eb9c00a42cf658ddfbc76c21c72161a Mon Sep 17 00:00:00 2001 From: MingxuanGame Date: Fri, 22 Aug 2025 09:37:18 +0000 Subject: [PATCH] docs(contributing): add guides & AI agent instructions --- .github/copilot-instructions.md | 48 ++++++++++++++++ CONTRIBUTING.md | 97 +++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 .github/copilot-instructions.md create mode 100644 CONTRIBUTING.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..f496480 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,48 @@ +## g0v0-server – AI Coding Agent Quick Guide + +Focus: High‑performance osu! (v1 / v2 / lazer) API emulator. Python (FastAPI + SQLModel/MySQL + Redis + APScheduler) + Rust (`packages/msgpack_lazer_api` for MessagePack encode/decode). + +### Core Architecture (know these before editing) +1. Entry: `main.py` – FastAPI app + lifespan startup/shutdown orchestration (fetcher init, GeoIP, schedulers, cache/email/download health checks, Redis message system, stats, achievements). Add new long‑running startup logic here only if it is foundational; otherwise prefer a scheduler or on‑demand service. +2. Routers (`app/router/`): + - `v1/` & `v2/`: Must mirror official endpoints only (no custom additions). Keep prefix via parent `router = APIRouter(prefix="/api/v2")` etc. + - `notification/`: Chat & notification subset (also “official only”). + - `auth.py`: Auth / token flows. + - `private/`: Server‑specific or internal endpoints (place all custom APIs here; split by concern with small modules + include via `private/router.py`). +3. Services (`app/service/`): Stateless or stateful domain logic (pp calc, rankings, caching, daily challenge, email, geoip, etc.). If you need background computation, create a service + (optionally) scheduler wrapper. +4. Schedulers (`app/scheduler/`): Start/stop functions named `start_*_scheduler` + matching `stop_*`. Lifespan wires them; stay consistent (see `cache_scheduler`, `database_cleanup_scheduler`). +5. Database layer (`app/database/`): SQLModel models; large models (e.g. `score.py`) embed domain helpers & serialization validators. When adding/altering tables: generate Alembic migration (autogenerate) & review for types / indexes. +6. Caching: Redis accessed via dependency (`app/dependencies/database.get_redis`). High‑traffic objects (users, user scores) use `UserCacheService` with explicit key patterns (`user:{id}...`). Reuse existing service; do not invent new ad‑hoc keys for similar data. +7. Rust module: `packages/msgpack_lazer_api` – performance critical (MessagePack for lazer). After Rust edits: `maturin develop -R` (release) inside dev container; Python interface consumed via import `msgpack_lazer_api` (see usage in encode/decode paths – keep function signatures stable; update `.pyi` if API changes). + +### Common Task Playbooks +Add v2 endpoint: create file under `app/router/v2/`, import router via `from .router import router`, define FastAPI path ops (async) using DB session (`session: Database`) & caching patterns; avoid blocking calls. Do NOT modify existing prefixes; do NOT add non‑official endpoints here (place in `private`). +Add background job: put pure logic in `app/service/_job.py` (idempotent / retry‑safe), add small scheduler starter in `app/scheduler/_scheduler.py` exposing `start__scheduler()` & `stop__scheduler()`, then register in `main.lifespan` near similar tasks. +DB schema change: edit / add SQLModel in relevant module, then: `alembic revision --autogenerate -m "feat(db): add "` → inspect migration (indexes, enums) → `alembic upgrade head`. +pp / ranking recalculation: standalone scriptable path via env `RECALCULATE=true python main.py` (see `app/service/recalculate.py`). Keep heavy loops async + batched (`asyncio.gather`) like `_recalculate_pp` pattern. +User data responses: Use `UserResp.from_db(...)` and cache asynchronously (`background_task.add_task(cache_service.cache_user, user_resp)`). Maintain ≤50 result limits where existing code does (see `v2/user.py`). + +### Configuration & Safety +Central settings: `app/config.py` (pydantic-settings). Secrets default to unsafe placeholders; lifespan logs warnings if not overridden (`secret_key`, `osu_web_client_secret`). When introducing new config flags: add field + defaults, document in README tables, and reference via `settings.` (avoid reading env directly elsewhere). + +### Conventions / Quality +Commit messages: Angular format (type(scope): subject). Types: feat/fix/docs/style/refactor/perf/test/chore/ci. +Async only in request paths (no blocking I/O). Use existing redis/service helpers instead of inline logic. Prefer model methods / helper functions near existing ones for cohesion. +Cache keys: follow established prefixes (`user:` / `v1_user:` / `user:{id}:scores:`). Invalidate via provided service methods. +Error handling: Raise `HTTPException` for client issues; wrap external fetch retries (see `_recalculate_pp` loop with capped retries + sleep). Avoid silent except; log via `logger`. + +### Tooling / Commands +Setup: `uv sync` → `pre-commit install`. +Run dev server: `uvicorn main:app --reload --host 0.0.0.0 --port 8000` (logs managed by custom logger; uvicorn default log config disabled). +Rust rebuild: `maturin develop -R`. +Migrations: `alembic revision --autogenerate -m "feat(db): ..."` → `alembic upgrade head`. + +### When Modifying Large Files (e.g. `score.py`) +Keep validation / serializer patterns (field_validator / field_serializer). Add new enum-like JSON fields with both validator + serializer for forward compatibility. + +### PR Scope Guidance +One concern per change (e.g., add endpoint OR refactor cache logic—not both). Update README config tables if adding env vars. + +Questions / ambiguous patterns: prefer aligning with closest existing service; if still unclear, surface a clarification comment instead of introducing a new pattern. + +— End of instructions — diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..a61baa4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,97 @@ +# 贡献指南 + +## 开发环境 + +为了确保一致的开发环境,我们强烈建议使用提供的 Dev Container。这将设置一个容器化的环境,预先安装所有必要的工具和依赖项。 + +1. 安装 [Docker](https://www.docker.com/products/docker-desktop/)。 +2. 在 Visual Studio Code 中安装 [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)。 +3. 在 VS Code 中打开项目。当被提示时,点击“在容器中重新打开”以启动开发容器。 + +## 依赖管理 + +该项目使用 `uv` 进行快速高效的 Python 包管理。 + +要安装依赖项,请在终端中运行以下命令: + +```bash +uv sync +``` + +## 代码质量和代码检查 + +我们使用 `pre-commit` 在提交之前执行代码质量标准。这确保所有代码都通过 `ruff`(用于代码检查和格式化)和 `pyright`(用于类型检查)的检查。 + +### 设置 + +要设置 `pre-commit`,请运行以下命令: + +```bash +pre-commit install +``` + +这将安装 pre-commit 钩子,每次提交时会自动运行。如果任何检查失败,提交将被中止。您需要修复报告的问题并暂存更改,然后再尝试提交。 + +## 提交信息指南 + +我们遵循 [AngularJS 提交规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commit-message-format) 来编写提交信息。这使得在查看项目历史记录时,信息更加可读且易于理解。 + +每条提交信息由 **标题**、**主体**和 **页脚** 三部分组成。 + +``` +(): + + + +
+``` + +**类型** 必须是以下之一: + +* **feat**:新功能 +* **fix**:错误修复 +* **docs**:仅文档更改 +* **style**:不影响代码含义的更改(空格、格式、缺少分号等) +* **refactor**:代码重构 +* **perf**:改善性能的代码更改 +* **test**:添加缺失的测试或修正现有测试 +* **chore**:对构建过程或辅助工具和库(如文档生成)的更改 +* **ci**:持续集成相关的更改 + +**范围** 可以是任何指定提交更改位置的内容。例如 `api`、`db`、`auth` 等等。 + +**主题** 包含对更改的简洁描述。 + +## 项目结构 + +以下是项目主要目录和文件的结构说明: + +- `main.py`: FastAPI 应用的主入口点,负责初始化和启动服务器。 +- `pyproject.toml`: 项目配置文件,用于管理依赖项 (uv)、代码格式化 (Ruff) 和类型检查 (Pyright)。 +- `alembic.ini`: Alembic 数据库迁移工具的配置文件。 +- `app/`: 存放所有核心应用代码。 + - `router/`: 包含所有 API 端点的定义,根据 API 版本和功能进行组织。 + - `service/`: 存放核心业务逻辑,例如用户排名计算、每日挑战处理等。 + - `database/`: 定义数据库模型 (SQLModel) 和会话管理。 + - `models/`: 定义非数据库模型和其他模型。 + - `scheduler/`: 包含由 APScheduler 调度的后台任务。 + - `dependencies/`: 管理 FastAPI 的依赖项注入。 + - `achievement.py`: 存放与成就相关的逻辑。 + - `storage/`: 存储服务代码。 + - `fetcher/`: 用于从外部服务(如 osu! 官网)获取数据的模块。 + - `config.py`: 应用配置,使用 pydantic-settings 管理。 + - `calculator.py`: 存放所有的计算逻辑,例如 pp 和等级。 +- `migrations/`: 存放 Alembic 生成的数据库迁移脚本。 +- `packages/`: 包含项目相关的独立包。 + - `msgpack_lazer_api/`: 基于 Rust 的高性能支持 lazer APIMod 的 MessagePack 解析模块,用于与 osu!lazer 客户端通信。 +- `static/`: 存放静态文件,如 `mods.json`。 + +## API Router 规范 + +- `app/router/v2` 存放所有 osu! v2 API 实现,不允许添加额外的,原 v2 API 不存在的 Endpoint +- `app/router/notification` 存放所有 osu! v2 API 聊天和通知的实现,不允许添加额外的,原 v2 API 不存在的 Endpoint +- `app/router/v1` 存放所有 osu! v1 API 实现,不允许添加额外的,原 v1 API 不存在的 Endpoint +- `app/router/auth.py` 存放账户鉴权/登录的 API +- `app/router/private` 存放服务器自定义 API,供其他服务使用 + +感谢您的贡献!