From b289aa2650d97ca8c06aedfafc151f6f869d92d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Tue, 25 Aug 2026 15:57:59 +0800 Subject: [PATCH] =?UTF-8?q?fix(api):=20sessions=20is=5Fdel=20=E8=B6=8A?= =?UTF-8?q?=E7=95=8C422=E6=A0=A1=E9=AA=8C+=E7=9C=81=E7=95=A5=E4=B8=8D?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E6=98=BE=E5=BC=8F=E5=A5=91=E7=BA=A6=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit is_del 加 Query(ge=0, le=1)——越界值(如2)422 拒绝而非静默空列表; test_sessions_is_del_filter 追加第三个请求:不带 is_del 时全部 4 个 talker 都返回(f1/f2/filehelper/gh0st),补上省略=完全不过滤的显式契约。 Co-Authored-By: Claude --- yunke-server/app/api/routers/sessions.py | 7 ++++--- yunke-server/tests/test_api_sessions.py | 12 +++++++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/yunke-server/app/api/routers/sessions.py b/yunke-server/app/api/routers/sessions.py index 7954dce..ab1d6ef 100644 --- a/yunke-server/app/api/routers/sessions.py +++ b/yunke-server/app/api/routers/sessions.py @@ -94,13 +94,14 @@ async def list_sessions( session: SessionDep, owner_account_id: Annotated[str, Query(min_length=1)], channel: Annotated[str, Query()] = "wechat", - is_del: Annotated[int | None, Query()] = None, + is_del: Annotated[int | None, Query(ge=0, le=1)] = None, ) -> SessionListOut: """账号会话列表:好友(talker_id,room_id 空)+ 群(room_id),按 last_chat_time desc。 ``is_del`` 可选过滤(对齐云客员工聊天窗口「删除好友」开关):按 customer.delete_flag - 在 Python 侧过滤——0=未删(NULL 视为 0),1=已删;无 customer 行的 talker(如 - filehelper 等系统账号)视作未删保留;群会话不受该过滤影响。不传时行为不变。 + 在 Python 侧过滤——0=未删(NULL 视为 0),1=已删;越界值(非 0/1)422 拒绝而非 + 静默空列表;无 customer 行的 talker(如 filehelper 等系统账号)视作未删保留; + 群会话不受该过滤影响。不传时行为不变。 ``pinned``:filehelper 会话置顶标记(对齐云客置顶区),其余好友/群恒 False。 """ today_start = _today_start_ms() diff --git a/yunke-server/tests/test_api_sessions.py b/yunke-server/tests/test_api_sessions.py index 5f3183b..451ef34 100644 --- a/yunke-server/tests/test_api_sessions.py +++ b/yunke-server/tests/test_api_sessions.py @@ -95,10 +95,20 @@ async def test_sessions_is_del_filter(make_client): client = await make_client(seed) live = await client.get("/api/sessions", params={"owner_account_id": OWNER, "channel": CH, "is_del": 0}) deleted = await client.get("/api/sessions", params={"owner_account_id": OWNER, "channel": CH, "is_del": 1}) - assert live.status_code == 200 and deleted.status_code == 200 + omitted = await client.get("/api/sessions", params={"owner_account_id": OWNER, "channel": CH}) + assert live.status_code == 200 and deleted.status_code == 200 and omitted.status_code == 200 # NULL 视为未删;无 customer 行的 talker 保留 assert sorted(s["talker_id"] for s in live.json()["sessions"]) == ["f1", "filehelper", "gh0st"] assert [s["talker_id"] for s in deleted.json()["sessions"]] == ["f2"] + # 省略 is_del = 完全不过滤(显式契约:4 个 talker 全返回) + assert sorted(s["talker_id"] for s in omitted.json()["sessions"]) == ["f1", "f2", "filehelper", "gh0st"] + + +async def test_sessions_is_del_out_of_range(make_client): + """``is_del`` 越界(如 2)→ 422,而非静默空列表。""" + client = await make_client(_seed) + r = await client.get("/api/sessions", params={"owner_account_id": OWNER, "channel": CH, "is_del": 2}) + assert r.status_code == 422 async def test_sessions_pinned_filehelper(make_client):