feat(feedback): סימון "יושם" מפעיל CEO לקיפול הלקח לקובץ הנכון

סוגר את לולאת פידבק-יו"ר→ידע-סוכנים. עד כה resolve רק עדכן את ה-DB; עכשיו
לחיצה ב-/feedback מעירה את ה-CEO שמקפל את הלקח לקובץ לפי הקטגוריה.

- paperclip_client.py: wake_ceo_for_feedback_fold() — יוצר issue ב-Paperclip
  עם הלקח + rubric ניתוב (style→SKILL.md, wrong_structure→block-schema,
  אחר→lessons.md), מעיר CEO. משכפל את דפוס wake_for_precedent_extraction
- db.py: get_chair_feedback(id) — שליפת הערה בודדת עם case_number/appeal_type
- app.py: resolve endpoint מקבל fold (ברירת מחדל true); BackgroundTask
  fire-and-forget; guard — רק עם lesson_extracted. מחזיר fold_queued
- legal-ceo.md: dispatch ל-feedback_fold_ + סעיף "קיפול הערת יו"ר" עם rubric
- frontend: useResolveFeedback מקבל fold; /feedback שולח fold=true עם toast;
  drafts-panel שולח fold=false (bookkeeping per-case, בלי קיפול כפול)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 13:08:41 +00:00
parent dd0e754dad
commit 4174217179
7 changed files with 212 additions and 9 deletions

View File

@@ -2455,6 +2455,20 @@ async def list_chair_feedback(
return [dict(r) for r in rows]
async def get_chair_feedback(feedback_id: UUID) -> dict | None:
"""Return a single chair_feedback row by id (with case_number), or None."""
pool = await get_pool()
async with pool.acquire() as conn:
row = await conn.fetchrow(
"""SELECT cf.*, c.case_number, c.appeal_type AS case_appeal_type
FROM chair_feedback cf
LEFT JOIN cases c ON c.id = cf.case_id
WHERE cf.id = $1""",
feedback_id,
)
return dict(row) if row else None
async def resolve_chair_feedback(
feedback_id: UUID,
applied_to: list[str],