diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index be77ac8..3b9b017 120000 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1 +1,115 @@ -../AGENTS.md \ No newline at end of file +# GitHub Copilot Instructions for g0v0-server + +This is an osu! API simulation server built with FastAPI, supporting osu! API v1/v2 and osu!lazer client functionality. + +## Architecture Overview + +**Entry Point:** `main.py` orchestrates startup/shutdown with complex lifespan management including fetchers, GeoIP, schedulers, cache systems, Redis messaging, and achievement loading. + +**Router Organization:** +- `app/router/v1/` - osu! API v1 endpoints (must match [official v1 spec](https://github.com/ppy/osu-api/wiki)) +- `app/router/v2/` - osu! API v2 endpoints (must match [official v2 OpenAPI spec](https://osu.ppy.sh/docs/openapi.yaml)) +- `app/router/private/` - Custom/internal endpoints not in official APIs +- `app/router/auth.py` - OAuth 2.0 authentication flows +- `app/router/notification/` - Chat and notification systems + +**Data Layer:** +- SQLModel ORM with async MySQL (`app/models/`, `app/database/`) +- Redis for caching, sessions, and messaging (`app/service/*_cache_service.py`) +- Alembic migrations in `migrations/` + +**Background Systems:** +- `app/scheduler/` - Background job schedulers (cache refresh, cleanup, rankings) +- `app/service/` - Business logic services (user ranking, email queue, asset proxy) +- Native Rust module `packages/msgpack_lazer_api/` for fast MessagePack serialization + +## Development Workflows + +**Environment Setup:** +```bash +uv sync # Install dependencies +pre-commit install # Setup git hooks +maturin develop -R # Build native Rust module (when changed) +``` + +**Database Operations:** +```bash +alembic revision --autogenerate -m "feat(db): description" # Create migration +alembic upgrade head # Apply migrations +``` + +**Development Server:** +```bash +uvicorn main:app --reload --host 0.0.0.0 --port 8000 +``` + +**Code Quality:** +```bash +pre-commit run --all-files # Run all checks +pyright # Type checking +ruff . # Linting and formatting +``` + +## Key Patterns & Conventions + +**Route Handlers:** +- Always async with dependency injection for DB/Redis +- Keep handlers thin - business logic goes in `app/service/` +- Use `UserCacheService` for user data caching patterns +- Background tasks for async cache updates: `bg_tasks.add_task()` + +**Database Access:** +```python +# Inject database session +async def endpoint(session: AsyncSession = Depends(get_session)): + # Use select() with specific columns for performance + stmt = select(User.id, User.username).where(User.active == True) + # Use exists() for existence checks + exists_stmt = select(exists().where(User.id == user_id)) +``` + +**Caching Patterns:** +```python +# Redis key naming: "user:{id}:profile", "beatmap:{id}:data" +# Use UserCacheService.get_user_resp() for cached user responses +# MessagePack serialization via native module for compact storage +``` + +**Error Handling:** +- `HTTPException` for client errors with proper status codes +- Structured logging with loguru for server-side issues +- Sentry integration for production error tracking + +**Authentication:** +- OAuth 2.0 with multiple flows (password, authorization_code, client_credentials) +- v1 API uses API key in query parameter `k` +- JWT tokens with configurable expiration + +## Critical Integration Points + +**Asset Proxy System:** Routes osu! asset URLs (avatars, beatmap covers) through custom domain - see `app/service/asset_proxy_*.py` + +**Game Mode Support:** Multi-mode with RX/AP variants - mode handling in `app/models/score.py` + +**Rate Limiting:** FastAPI-limiter with Redis backend - different limits for download vs general APIs + +**Native Module:** Rust MessagePack encoder/decoder in `packages/msgpack_lazer_api/` - rebuild with `maturin develop -R` after changes + +**Background Schedulers:** Multiple concurrent schedulers for rankings, cache warming, database cleanup - managed in lifespan handlers + +## API Compliance Rules + +- **v1/v2 endpoints MUST match official osu! API specifications exactly** +- Custom endpoints go in `app/router/private/` only +- Maintain response schema compatibility - breaking changes require migration plan +- Use existing `*Resp` models for consistent response formats + +## Configuration + +Environment-driven via Pydantic Settings in `app/config.py`: +- Database: MySQL with async aiomysql driver +- Cache: Redis for sessions, rate limiting, messaging +- Storage: Local, S3, or Cloudflare R2 backends +- Optional: Sentry, New Relic, email SMTP + +See project wiki for complete `.env` configuration guide. \ No newline at end of file diff --git a/app/router/v2/user.py b/app/router/v2/user.py index 463a8be..0388719 100644 --- a/app/router/v2/user.py +++ b/app/router/v2/user.py @@ -404,3 +404,25 @@ async def get_user_scores( ) return score_responses + + +@router.get( + "/users/{user_id}/kudosu", + response_model=list, + name="获取用户 kudosu 记录", + description="获取指定用户的 kudosu 记录。TODO: 可能会实现", + tags=["用户"], +) +async def get_user_kudosu( + user_id: int = Path(description="用户 ID"), + offset: int = Query(default=0, description="偏移量"), + limit: int = Query(default=6, description="返回记录数量限制"), +): + """ + 获取用户的 kudosu 记录 + + TODO: 可能会实现 + 目前返回空数组作为占位符 + """ + # TODO: 实现 kudosu 记录获取逻辑 + return []