Management UI: corpus delete, process panel, activity feed, diagnostics
- DELETE /api/training/corpus/{id} + delete button on training page,
with confirmation dialog and recompute hint
- /api/system/tasks + floating process panel (bottom-left) showing
active background tasks with live 3s polling
- /api/system/recent-activity derives a feed from cases, style_corpus,
and last style_patterns run; sidebar on home page renders with
relative timestamps
- /api/system/diagnostics + /#/diagnostics page showing DB health,
row counts per table, active tasks, stuck documents (>10 min),
failed extractions
- Cosmetic: signature phrase headline now prefers clean phrases over
bracket-heavy templates for display
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -794,6 +794,51 @@ async def add_to_style_corpus(
|
||||
return corpus_id
|
||||
|
||||
|
||||
async def delete_from_style_corpus(corpus_id: UUID) -> dict:
|
||||
"""Remove a decision from style_corpus + related documents (cascades chunks).
|
||||
|
||||
Also tries to delete the [קורפוס] document associated by title match,
|
||||
since the current training pipeline inserts style_corpus with document_id=NULL.
|
||||
"""
|
||||
pool = await get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
async with conn.transaction():
|
||||
row = await conn.fetchrow(
|
||||
"DELETE FROM style_corpus WHERE id = $1 "
|
||||
"RETURNING decision_number, document_id",
|
||||
corpus_id,
|
||||
)
|
||||
if not row:
|
||||
return {"deleted": False, "reason": "not found"}
|
||||
|
||||
docs_deleted = 0
|
||||
if row["document_id"]:
|
||||
await conn.execute(
|
||||
"DELETE FROM documents WHERE id = $1", row["document_id"]
|
||||
)
|
||||
docs_deleted = 1
|
||||
else:
|
||||
# Best-effort: match a [קורפוס] document by the decision_number
|
||||
# in its title. Only for single, unambiguous matches.
|
||||
if row["decision_number"]:
|
||||
docs = await conn.fetch(
|
||||
"SELECT id FROM documents "
|
||||
"WHERE case_id IS NULL AND title LIKE $1",
|
||||
f"%{row['decision_number']}%",
|
||||
)
|
||||
if len(docs) == 1:
|
||||
await conn.execute(
|
||||
"DELETE FROM documents WHERE id = $1", docs[0]["id"]
|
||||
)
|
||||
docs_deleted = 1
|
||||
|
||||
return {
|
||||
"deleted": True,
|
||||
"decision_number": row["decision_number"],
|
||||
"docs_deleted": docs_deleted,
|
||||
}
|
||||
|
||||
|
||||
async def get_style_patterns(pattern_type: str | None = None) -> list[dict]:
|
||||
pool = await get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
|
||||
Reference in New Issue
Block a user