Jul 10 - Update QR public page

This commit is contained in:
2026-07-10 13:25:38 -04:00
parent 8d4b8b72eb
commit 008dd94962
2 changed files with 148 additions and 48 deletions
+65 -14
View File
@@ -62,12 +62,19 @@ def _rating_label(score):
def _build_summary(facility: Facility) -> dict:
"""Assemble the occupant-facing summary for a facility."""
"""Assemble the occupant-facing summary for a facility.
Occupant-safe (rule 74): aggregate rating, counts, a score trend, and
recent inspection DATES only — no checklist/template names, no
per-inspection scores, no issue descriptions, and no severity/SLA detail.
"""
fid = facility.id
now = now_eastern()
cutoff = now - timedelta(days=90)
cutoff_90 = now - timedelta(days=90)
cutoff_30 = now - timedelta(days=30)
cutoff_60 = now - timedelta(days=60)
# Most recent completed, scored inspection
# Most recent completed, scored inspection (for last-inspected date)
last_insp = (
Inspection.query
.filter(Inspection.facility_id == fid,
@@ -77,15 +84,18 @@ def _build_summary(facility: Facility) -> dict:
.first()
)
def _avg_between(start, end=None):
q = (db.session.query(func.avg(Inspection.overall_score))
.filter(Inspection.facility_id == fid,
Inspection.status == 'completed',
Inspection.overall_score.isnot(None),
Inspection.inspection_date >= start))
if end is not None:
q = q.filter(Inspection.inspection_date < end)
return q.scalar()
# Average score over the last 90 days (fallback: all-time) for the rating
avg_90 = (
db.session.query(func.avg(Inspection.overall_score))
.filter(Inspection.facility_id == fid,
Inspection.status == 'completed',
Inspection.overall_score.isnot(None),
Inspection.inspection_date >= cutoff)
.scalar()
)
avg_90 = _avg_between(cutoff_90)
if avg_90 is None:
avg_90 = (
db.session.query(func.avg(Inspection.overall_score))
@@ -96,6 +106,34 @@ def _build_summary(facility: Facility) -> dict:
)
avg_score = round(float(avg_90), 1) if avg_90 is not None else None
# Completed-inspection count over the last 90 days
inspections_90 = (
Inspection.query
.filter(Inspection.facility_id == fid,
Inspection.status == 'completed',
Inspection.inspection_date >= cutoff_90)
.count()
)
# Score trend: last 30 days vs the prior 30 days (aggregate only)
avg_cur = _avg_between(cutoff_30)
avg_prior = _avg_between(cutoff_60, cutoff_30)
if avg_cur is not None and avg_prior is not None:
trend_delta = round(float(avg_cur) - float(avg_prior), 1)
else:
trend_delta = None
# Recent inspection DATES only (no checklist names, no scores)
recent = (
Inspection.query
.filter(Inspection.facility_id == fid,
Inspection.status == 'completed')
.order_by(Inspection.inspection_date.desc())
.limit(5)
.all()
)
recent_dates = [i.inspection_date for i in recent]
# Open-issue COUNT (linked directly or via an area) — no details exposed
open_issue_count = (
Issue.query
@@ -105,6 +143,17 @@ def _build_summary(facility: Facility) -> dict:
.count()
)
# Resolved-issue COUNT over the last 90 days — no details exposed
resolved_90 = (
Issue.query
.outerjoin(Area, Issue.area_id == Area.id)
.filter(Issue.status == 'resolved',
Issue.resolved_at.isnot(None),
Issue.resolved_at >= cutoff_90,
db.or_(Issue.facility_id == fid, Area.facility_id == fid))
.count()
)
label, colour = _rating_label(avg_score)
return {
@@ -112,10 +161,12 @@ def _build_summary(facility: Facility) -> dict:
'avg_score': avg_score,
'rating_label': label,
'rating_colour': colour,
'last_inspected': last_insp.inspection_date if last_insp else None,
'last_score': (round(float(last_insp.overall_score), 1)
if last_insp and last_insp.overall_score is not None else None),
'inspections_90': inspections_90,
'open_issue_count': open_issue_count,
'resolved_90': resolved_90,
'trend_delta': trend_delta,
'last_inspected': last_insp.inspection_date if last_insp else None,
'recent_dates': recent_dates,
}