feat(lea): add dashboard competence promotion dry run

This commit is contained in:
Dom
2026-05-29 21:48:00 +02:00
parent bd3aaf7d64
commit 34527b5cc5
8 changed files with 1341 additions and 1 deletions

View File

@@ -2465,10 +2465,56 @@ def knowledge_base_stats():
'sessions': _kb_sessions_stats(),
'patterns': _kb_patterns_stats(),
'workflows': _kb_workflows_stats(),
'competences': _kb_competences_stats(),
}
return jsonify(result)
@app.route('/api/v1/lea/competences/<competence_id>/promote', methods=['POST'])
def dashboard_promote_competence(competence_id):
"""Dry-run or apply a supervised competence promotion from the dashboard."""
try:
from core.competences.promotions import (
CompetencePromotionError,
promote_competence_from_verdicts,
)
payload = request.get_json(silent=True) or {}
promotion = promote_competence_from_verdicts(competence_id, payload)
except KeyError:
return jsonify({
'success': False,
'error': f"Competence '{competence_id}' introuvable",
}), 404
except CompetencePromotionError as exc:
return jsonify({
'success': False,
'error': str(exc),
'write_back_enabled': False,
'yaml_write': False,
}), 400
except Exception as exc:
return jsonify({
'success': False,
'error': str(exc),
'write_back_enabled': False,
'yaml_write': False,
}), 500
status = 200 if promotion.get('dry_run') or promotion.get('duplicate') else 201
return jsonify({
'success': True,
'competence_id': competence_id,
'promotion': {
key: value for key, value in promotion.items()
if not str(key).startswith('_')
},
'dry_run': promotion.get('dry_run', False),
'write_back_enabled': not promotion.get('dry_run', False),
'yaml_write': bool(promotion.get('write_applied', False)),
}), status
def _kb_faiss_stats() -> dict:
"""Statistiques de l'index FAISS."""
faiss_index_path = DATA_PATH / "faiss_index" / "main.index"
@@ -2597,6 +2643,29 @@ def _kb_workflows_stats() -> dict:
return {'total': total}
def _kb_competences_stats() -> dict:
"""Statistiques des compétences Lea YAML et verdicts supervisés."""
try:
from core.competences.promotions import summarize_competence_promotions
competences = summarize_competence_promotions()
by_state = {}
for item in competences:
state = item.get('learning_state', 'unknown')
by_state[state] = by_state.get(state, 0) + 1
return {
'total': len(competences),
'by_state': by_state,
'items': competences,
}
except Exception as exc:
return {
'total': 0,
'by_state': {},
'items': [],
'error': str(exc),
}
def _dir_size(path: Path) -> int:
"""Calcule la taille totale d'un dossier (non récursif profond pour la perf)."""
total = 0