docs(contributing): add guides & AI agent instructions
This commit is contained in:
48
.github/copilot-instructions.md
vendored
Normal file
48
.github/copilot-instructions.md
vendored
Normal file
@@ -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/<name>_job.py` (idempotent / retry‑safe), add small scheduler starter in `app/scheduler/<name>_scheduler.py` exposing `start_<name>_scheduler()` & `stop_<name>_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 <table>"` → 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.<name>` (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 —
|
||||||
97
CONTRIBUTING.md
Normal file
97
CONTRIBUTING.md
Normal file
@@ -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) 来编写提交信息。这使得在查看项目历史记录时,信息更加可读且易于理解。
|
||||||
|
|
||||||
|
每条提交信息由 **标题**、**主体**和 **页脚** 三部分组成。
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>(<scope>): <subject>
|
||||||
|
<BLANK LINE>
|
||||||
|
<body>
|
||||||
|
<BLANK LINE>
|
||||||
|
<footer>
|
||||||
|
```
|
||||||
|
|
||||||
|
**类型** 必须是以下之一:
|
||||||
|
|
||||||
|
* **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,供其他服务使用
|
||||||
|
|
||||||
|
感谢您的贡献!
|
||||||
Reference in New Issue
Block a user