diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 42c417a..dcb6ba1 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -75,7 +75,25 @@ ### 实用工作流(提示模式) - **添加 v2 端点(正确方式):** 在 `app/router/v2/` 下添加文件,导出路由,实现基于数据库与缓存依赖的异步处理函数。**不得**在 v1/v2 添加非官方端点。 -- **添加内部端点:** 放在 `app/router/private/`,保持处理器精简,将业务逻辑放入 `app/service/`。 +- **添加自定义端点:** 放在 `app/router/private/`,保持处理器精简,将业务逻辑放入 `app/service/`。 +- **鉴权:** 使用 [`app.dependencies.user`](../app/dependencies/user.py) 提供的依赖注入,如 `ClientUser` 和 `get_current_user`,参考下方。 + + ```python + from typing import Annotated + from fastapi import Security + from app.dependencies.user import ClientUser, get_current_user + + + @router.get("/some-api") + async def _(current_user: Annotated[User, Security(get_current_user, scopes=["public"])]): + ... + + + @router.get("/some-client-api") + async def _(current_user: ClientUser): + ... + ``` + - **添加后台任务:** 将任务逻辑写在 `app/service/_job.py`(幂等、可重试)。调度器入口放在 `app/scheduler/_scheduler.py`,并在应用生命周期注册。 - **数据库 schema 变更:** 修改 `app/models/` 中的 SQLModel 模型,运行 `alembic revision --autogenerate`,检查迁移并本地测试 `alembic upgrade head` 后再提交。 - **缓存写入与响应:** 使用现有的 `UserResp` 模式和 `UserCacheService`;异步缓存写入应使用后台任务。 diff --git a/AGENTS.md b/AGENTS.md index ef8a10e..bc79c7d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -73,7 +73,25 @@ ### 实用工作流(提示模式) - **添加 v2 端点(正确方式):** 在 `app/router/v2/` 下添加文件,导出路由,实现基于数据库与缓存依赖的异步处理函数。**不得**在 v1/v2 添加非官方端点。 -- **添加内部端点:** 放在 `app/router/private/`,保持处理器精简,将业务逻辑放入 `app/service/`。 +- **添加自定义端点:** 放在 `app/router/private/`,保持处理器精简,将业务逻辑放入 `app/service/`。 +- **鉴权:** 使用 [`app.dependencies.user`](./app/dependencies/user.py) 提供的依赖注入,如 `ClientUser` 和 `get_current_user`,参考下方。 + + ```python + from typing import Annotated + from fastapi import Security + from app.dependencies.user import ClientUser, get_current_user + + + @router.get("/some-api") + async def _(current_user: Annotated[User, Security(get_current_user, scopes=["public"])]): + ... + + + @router.get("/some-client-api") + async def _(current_user: ClientUser): + ... + ``` + - **添加后台任务:** 将任务逻辑写在 `app/service/_job.py`(幂等、可重试)。调度器入口放在 `app/scheduler/_scheduler.py`,并在应用生命周期注册。 - **数据库 schema 变更:** 修改 `app/models/` 中的 SQLModel 模型,运行 `alembic revision --autogenerate`,检查迁移并本地测试 `alembic upgrade head` 后再提交。 - **缓存写入与响应:** 使用现有的 `UserResp` 模式和 `UserCacheService`;异步缓存写入应使用后台任务。 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d6ee47d..f660909 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -148,6 +148,36 @@ async with with_db() as session: - 如果返回需要资源代理,使用 `app.helpers.asset_proxy_helper` 的 `asset_proxy_response` 装饰器。 - 如果需要记录日志,请使用 `app.log` 提供的 `log` 函数获取一个 logger 实例 +#### 鉴权 + +如果这个 Router 可以为公开使用(客户端、前端、OAuth 程序),考虑使用 `Security(get_current_user, scopes=["some_scope"])`,例如: + +```python +from typing import Annotated +from fastapi import Security +from app.dependencies.user import get_current_user + + +@router.get("/some-api") +async def _(current_user: Annotated[User, Security(get_current_user, scopes=["public"])]): + ... +``` + +其中 scopes 选择请参考 [`app.dependencies.user`](./app/dependencies/user.py) 的 `oauth2_code` 中的 `scopes`。 + +如果这个 Router 仅限客户端和前端使用,请使用 `ClientUser` 依赖注入。 + +```python +from app.dependencies.user import ClientUser + + +@router.get("/some-api") +async def _(current_user: ClientUser): + ... +``` + +此外还存在 `get_current_user_and_token` 和 `get_client_user_and_token` 变种,用来同时获得当前用户的 token。 + ### Service 所有的核心业务逻辑放在 `app.service` 里: @@ -172,7 +202,7 @@ async with with_db() as session: 使用 `pre-commit` 在提交之前执行代码质量标准。这确保所有代码都通过 `ruff`(用于代码检查和格式化)和 `pyright`(用于类型检查)的检查。 -### 设置 +#### 设置 要设置 `pre-commit`,请运行以下命令: