feat(style-acq T14): שער-יו"ר לאישור הצעות-curator → הטמעה לפרופיל

סוגר את הלולאה מקצה-לקצה (INV-G10/LRN1): ה-curator מציע (status=analyzed),
היו"ר מאשרת, והלקחים נכתבים לערוצים שהכותב צורך (T15) — אין auto-commit.

- db.get_draft_final_pair(id) — שורת-פנקס מלאה כולל analysis.
- app.py: GET /api/learning/pairs/{id} (חושף רק changes מסוג style_method —
  INV-LRN5) + POST .../promote (לקחים→discussion_rules['universal'],
  ביטויים→transition_phrases['universal'] דרך merge ל-appeal_type_rules;
  status→lessons_folded). _append_methodology_override משותף.
- web-ui: usePairDetail/usePromoteLearning + ProposalReview (בחירת לקחים/
  ביטויים לאימוץ) בטאב "למידה" עבור pairs במצב analyzed.

INV-G10 (שער-יו"ר) · INV-LRN1 (אין auto-commit) · INV-LRN5 (טוהר).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 19:17:56 +00:00
parent ee76455a9a
commit f20a3a09fd
4 changed files with 244 additions and 5 deletions

View File

@@ -2352,6 +2352,21 @@ async def list_draft_final_pairs(status: str | None = None, limit: int = 200) ->
return [dict(r) for r in rows]
async def get_draft_final_pair(pair_id: UUID) -> dict | None:
"""Full pairing row incl. analysis (curator proposal) — for the T14 approval gate."""
pool = await get_pool()
async with pool.acquire() as conn:
row = await conn.fetchrow(
"""SELECT p.id, p.case_id, c.case_number, c.title, p.status,
p.draft_text, p.final_text, p.diff_stats, p.analysis,
p.created_at, p.updated_at
FROM draft_final_pairs p LEFT JOIN cases c ON c.id = p.case_id
WHERE p.id = $1""",
pair_id,
)
return dict(row) if row else None
async def insert_style_exemplar(
decision_number: str, source: str, practice_area: str, outcome: str,
section: str, paragraph_text: str, word_count: int, embedding: list[float],