From 419af386845aef3d6ce29f26c951b0f9fef1bb21 Mon Sep 17 00:00:00 2001 From: Zayden Jung Date: Tue, 19 May 2026 02:03:35 +0800 Subject: [PATCH] fix missing type annotations for graphql query field arguments --- .cliprepo.yaml | 4 ++++ app/graphql/context.py | 3 ++- app/graphql/queries.py | 7 +++++-- app/graphql/types.py | 25 +++++++++++++------------ 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/.cliprepo.yaml b/.cliprepo.yaml index dbc0908..8a7c4b4 100644 --- a/.cliprepo.yaml +++ b/.cliprepo.yaml @@ -19,4 +19,8 @@ preset: - "app/models/*" - "app/db.py" - "app/auth.py" + - "app/main.py" + + graphql: + - "app/graphql/*" - "app/main.py" \ No newline at end of file diff --git a/app/graphql/context.py b/app/graphql/context.py index 45c37b9..e79b1d5 100644 --- a/app/graphql/context.py +++ b/app/graphql/context.py @@ -7,7 +7,6 @@ from typing import List from collections import defaultdict from app.db import SessionLocal from app.models import WorkspaceMember -from app.graphql.types import WorkspaceMemberType from typing import AsyncGenerator # 定义批量查询函数:接收一组 workspace ID 列表,返回相同长度的结果列表 @@ -32,6 +31,8 @@ class CustomContext(BaseContext): super().__init__(request) self.db = SessionLocal() self.request = request + + self.members_loader = DataLoader(load_fn=load_members_by_workspace_ids) async def get_current_user(self) -> User | None: # 复用现有的 auth 逻辑 diff --git a/app/graphql/queries.py b/app/graphql/queries.py index cbd0445..0b1e08b 100644 --- a/app/graphql/queries.py +++ b/app/graphql/queries.py @@ -1,18 +1,21 @@ import strawberry from typing import Optional +from strawberry.types import Info + from app.graphql.types import UserType from app.models import User +from app.graphql.context import CustomContext @strawberry.type class Query: @strawberry.field - async def me(self, info) -> Optional[UserType]: + async def me(self, info: Info[CustomContext, None]) -> Optional[UserType]: # 从 context 获取当前登录用户 user = await info.context.get_current_user() # Strawberry 会自动将 SQLAlchemy 实例映射为 UserType return user @strawberry.field - def get_user_by_handle(self, info, handle: str) -> Optional[UserType]: + def get_user_by_handle(self, info: Info[CustomContext, None], handle: str) -> Optional[UserType]: db = info.context.db return db.query(User).filter(User.handle == handle).first() \ No newline at end of file diff --git a/app/graphql/types.py b/app/graphql/types.py index cbdbc6b..c83bcab 100644 --- a/app/graphql/types.py +++ b/app/graphql/types.py @@ -1,7 +1,10 @@ import strawberry from typing import List, Optional from datetime import datetime +from strawberry.types import Info + from app.utils.format import get_image_url +from app.graphql.context import CustomContext @strawberry.type class UserType: @@ -19,6 +22,14 @@ class UserType: def avatar_url(self) -> Optional[str]: return get_image_url(self.avatar) if self.avatar else None +@strawberry.type +class WorkspaceMemberType: + id: strawberry.ID + workspace_id: str + user_id: Optional[str] + role: str + status: str + @strawberry.type class WorkspaceType: id: strawberry.ID @@ -30,15 +41,5 @@ class WorkspaceType: # 支持前端按需加载关联的成员 @strawberry.field - def members(self, info) -> List["WorkspaceMemberType"]: - from app.models import WorkspaceMember - db = info.context.db - return db.query(WorkspaceMember).filter(WorkspaceMember.workspace_id == self.id).all() - -@strawberry.type -class WorkspaceMemberType: - id: strawberry.ID - workspace_id: str - user_id: Optional[str] - role: str - status: str \ No newline at end of file + def members(self, info: Info) -> List[WorkspaceMemberType]: + return info.context.members_loader.load(self.id) \ No newline at end of file