feat: delete AI reports, Super Contexte versions, and KB entries

- database.py: add delete_ai_report(), delete_reasoning_state(), delete_kb_entry()
- reasoning.py: DELETE /api/reasoning/reports/{id}
- knowledge.py: DELETE /api/knowledge/history/{id} and /entries/{id}
- useApi.ts: useDeleteAiReport, useDeleteReasoningState, useDeleteKbEntry hooks
- RapportIA.tsx: trash icon on hover in archived reports sidebar
- SuperContexte.tsx: trash icon on hover for history versions and KB entries;
  both propagate onDelete through CategorySection down to KbEntry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-17 00:10:41 +02:00
parent 22687dfd03
commit a3fb486477
6 changed files with 174 additions and 33 deletions

View File

@@ -8,6 +8,7 @@ from services.database import (
get_kb_entries, get_all_kb_entries, save_kb_entry, update_kb_entry_status,
get_latest_reasoning_state, get_reasoning_history, get_reasoning_state_by_id,
save_reasoning_state, list_ai_reports, get_mtm_trades_with_traces, _trade_maturity,
delete_reasoning_state, delete_kb_entry,
)
router = APIRouter(prefix="/api/knowledge", tags=["knowledge"])
@@ -174,6 +175,24 @@ def get_state_version(state_id: int):
return {"state": state}
@router.delete("/history/{state_id}")
def delete_state_version(state_id: int):
"""Delete a reasoning state version by ID."""
deleted = delete_reasoning_state(state_id)
if not deleted:
raise HTTPException(404, "Version introuvable")
return {"deleted": True, "id": state_id}
@router.delete("/entries/{entry_id}")
def delete_entry(entry_id: int):
"""Permanently delete a KB entry."""
deleted = delete_kb_entry(entry_id)
if not deleted:
raise HTTPException(404, "Entrée introuvable")
return {"deleted": True, "id": entry_id}
@router.get("/entries")
def list_entries(status: str = "all"):
if status == "all":

View File

@@ -21,6 +21,7 @@ from services.database import (
get_trade_entry_by_id,
list_ai_reports,
save_ai_report,
delete_ai_report,
_trade_maturity,
)
@@ -369,3 +370,12 @@ def get_report(report_id: int):
if not report:
raise HTTPException(404, f"Report {report_id} not found")
return report
@router.delete("/reports/{report_id}")
def delete_report(report_id: int):
"""Delete an archived AI report by ID."""
deleted = delete_ai_report(report_id)
if not deleted:
raise HTTPException(404, f"Report {report_id} not found")
return {"deleted": True, "id": report_id}

View File

@@ -1451,3 +1451,27 @@ def get_reasoning_state_by_id(state_id: int) -> Optional[Dict[str, Any]]:
except Exception:
d["synthesis"] = {}
return d
def delete_ai_report(report_id: int) -> bool:
conn = get_conn()
cur = conn.execute("DELETE FROM ai_reports WHERE id=?", (report_id,))
conn.commit()
conn.close()
return cur.rowcount > 0
def delete_reasoning_state(state_id: int) -> bool:
conn = get_conn()
cur = conn.execute("DELETE FROM reasoning_state WHERE id=?", (state_id,))
conn.commit()
conn.close()
return cur.rowcount > 0
def delete_kb_entry(entry_id: int) -> bool:
conn = get_conn()
cur = conn.execute("DELETE FROM knowledge_base WHERE id=?", (entry_id,))
conn.commit()
conn.close()
return cur.rowcount > 0