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:
@@ -3,7 +3,7 @@
|
||||
* Backs the /training "למידה" tab. Endpoints under /api/learning.
|
||||
*/
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { apiRequest } from "./client";
|
||||
|
||||
export type DraftFinalPair = {
|
||||
@@ -67,3 +67,50 @@ export function useStyleDistance(caseNumber: string | null) {
|
||||
staleTime: 15_000,
|
||||
});
|
||||
}
|
||||
|
||||
// ── T14: curator distillation proposal + chair approval gate ──────
|
||||
|
||||
export type DistillationChange = {
|
||||
type?: string;
|
||||
domain?: string;
|
||||
block?: string;
|
||||
description?: string;
|
||||
draft_text?: string;
|
||||
final_text?: string;
|
||||
lesson?: string;
|
||||
};
|
||||
|
||||
export type PairDetail = {
|
||||
id: string;
|
||||
case_number: string;
|
||||
title: string;
|
||||
status: string;
|
||||
diff_stats: { change_percent?: number } | null;
|
||||
overall_assessment: string;
|
||||
changes: DistillationChange[]; // style_method only (server-filtered)
|
||||
new_expressions: string[];
|
||||
};
|
||||
|
||||
export function usePairDetail(pairId: string | null) {
|
||||
return useQuery({
|
||||
queryKey: [...learningKeys.all, "pair", pairId ?? ""] as const,
|
||||
queryFn: ({ signal }) =>
|
||||
apiRequest<PairDetail>(`/api/learning/pairs/${pairId}`, { signal }),
|
||||
enabled: Boolean(pairId),
|
||||
staleTime: 15_000,
|
||||
});
|
||||
}
|
||||
|
||||
export function usePromoteLearning(pairId: string) {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (body: { lessons: string[]; phrases: string[] }) =>
|
||||
apiRequest<{ id: string; status: string; folded_lessons: number; folded_phrases: number }>(
|
||||
`/api/learning/pairs/${pairId}/promote`,
|
||||
{ method: "POST", body },
|
||||
),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: learningKeys.all });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user