fix(qa): enforce critical-QA gate on export + fix neutral_background critical-but-passed (GAP-15/16, INV-QA3/EX3)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1509,6 +1509,37 @@ async def get_decision_by_case(case_id: UUID) -> dict | None:
|
||||
return d
|
||||
|
||||
|
||||
async def get_critical_qa_failures(case_id: UUID) -> list[dict]:
|
||||
"""Return critical-severity failures from the case's latest QA run.
|
||||
|
||||
``qa_results`` is cleared+rewritten per ``validate_decision`` run, so the
|
||||
current rows for a ``case_id`` ARE the latest run. Returns rows where
|
||||
``severity='critical' AND passed=false``. Callers distinguish "no QA run
|
||||
yet" (no rows at all) via ``qa_run_exists`` below.
|
||||
"""
|
||||
pool = await get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
rows = await conn.fetch(
|
||||
"""SELECT check_name, severity, passed, errors
|
||||
FROM qa_results
|
||||
WHERE case_id = $1 AND severity = 'critical' AND passed = false
|
||||
ORDER BY check_name""",
|
||||
case_id,
|
||||
)
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
async def qa_run_exists(case_id: UUID) -> bool:
|
||||
"""True if a QA run has ever been recorded for this case (any rows)."""
|
||||
pool = await get_pool()
|
||||
async with pool.acquire() as conn:
|
||||
n = await conn.fetchval(
|
||||
"SELECT count(*) FROM qa_results WHERE case_id = $1",
|
||||
case_id,
|
||||
)
|
||||
return bool(n)
|
||||
|
||||
|
||||
async def update_decision(decision_id: UUID, **fields) -> None:
|
||||
if not fields:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user