feat: explain RTC blockers when no R3 candidates are eligible
This commit is contained in:
@@ -340,6 +340,19 @@ def blocker_filter_summary(session, *, tenant_id=None, agent_id=None, product_co
|
||||
}
|
||||
|
||||
|
||||
def rtc_blocker_summary(session, agent_id: int) -> dict:
|
||||
"""Read-only, installation-scoped RTC blocker aggregates for the cClassTrib page."""
|
||||
query = _blockers_query(session, agent_id=agent_id, field="RTC", status="OPEN", scope="all")
|
||||
blockers = int(session.scalar(query.with_only_columns(func.count(BlockedProduct.id)).order_by(None)) or 0)
|
||||
products = int(session.scalar(query.with_only_columns(func.count(func.distinct(BlockedProduct.product_code))).order_by(None)) or 0)
|
||||
reason = func.coalesce(BlockedProduct.evidence_summary["reason"].as_string(), BlockedProduct.reason_code)
|
||||
reasons = session.execute(
|
||||
query.with_only_columns(reason, func.count(func.distinct(BlockedProduct.product_code)))
|
||||
.group_by(reason).order_by(None)
|
||||
).all()
|
||||
return {"open_blockers": blockers, "products_affected": products, "reason_counts": {str(code or ""): int(count) for code, count in reasons}}
|
||||
|
||||
|
||||
def _blocker_breakdown_query(query):
|
||||
"""Group on the source column itself for PostgreSQL-safe SQL semantics."""
|
||||
return query.with_only_columns(BlockedProduct.field, func.count(BlockedProduct.id)).group_by(BlockedProduct.field).order_by(None)
|
||||
|
||||
Reference in New Issue
Block a user