From d4dc58fe5a16dee0aa5ccd4546cd90abdeab86e5 Mon Sep 17 00:00:00 2001 From: Chaim Date: Fri, 12 Jun 2026 04:39:16 +0000 Subject: [PATCH] =?UTF-8?q?fix(archive):=20=D7=9E=D7=99=D7=95=D7=9F=20?= =?UTF-8?q?=D7=AA=D7=99=D7=A7=D7=99-=D7=90=D7=A8=D7=9B=D7=99=D7=91=20?= =?UTF-8?q?=D7=9C=D7=A4=D7=99=20=D7=AA=D7=90=D7=A8=D7=99=D7=9A-=D7=90?= =?UTF-8?q?=D7=A8=D7=9B=D7=95=D7=91=20(server-authoritative)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit דף /archive הציג תיקים בסדר updated_at במקום לפי תאריך-הארכוב, למרות שעמודת "תאריך ארכוב" סומנה כממוינת. השורש: list_cases() החזיר תמיד ORDER BY updated_at DESC, וההסתמכות על מיון-בדפדפן (TanStack) לא הבטיחה את הסדר בטעינה הראשונית. התיקון: כש-archived_only=True → ORDER BY archived_at DESC NULLS LAST. הסדר הופך server-authoritative; לא נוגע ברשימה הפעילה ולא ב-MCP tool (שאינו מעביר archived_only). Invariants: G1 (נרמול-במקור — סדר נקבע בשאילתה, לא תיקון-בקריאה), G2 (לא מסלול-מקביל — אותו list_cases), INV-IA* (מקור-אמת יחיד לרשימה). Co-Authored-By: Claude Opus 4.8 (1M context) --- mcp-server/src/legal_mcp/services/db.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mcp-server/src/legal_mcp/services/db.py b/mcp-server/src/legal_mcp/services/db.py index 1f3bdb2..8f52561 100644 --- a/mcp-server/src/legal_mcp/services/db.py +++ b/mcp-server/src/legal_mcp/services/db.py @@ -1713,7 +1713,12 @@ async def list_cases( where.append("archived_at IS NULL") where_clause = f"WHERE {' AND '.join(where)}" if where else "" args.append(limit) - sql = f"SELECT * FROM cases {where_clause} ORDER BY updated_at DESC LIMIT ${len(args)}" + # Archived list is ordered by archive date (newest-first) so the order is + # server-authoritative and the /archive page is correct on load, regardless + # of client-side sorting. NULLS LAST is defensive — the archived_only filter + # already excludes NULLs. + order_by = "archived_at DESC NULLS LAST" if archived_only else "updated_at DESC" + sql = f"SELECT * FROM cases {where_clause} ORDER BY {order_by} LIMIT ${len(args)}" async with pool.acquire() as conn: rows = await conn.fetch(sql, *args) return [_row_to_case(r) for r in rows]