From a9678cf9945ab653fda0f735703b2b95532cd7a7 Mon Sep 17 00:00:00 2001 From: NguyenND Date: Wed, 6 May 2026 11:19:38 -0400 Subject: [PATCH] 05/06 Fix Issue's SQL problems --- app/routes/issues.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/app/routes/issues.py b/app/routes/issues.py index cd0b035..394b69b 100644 --- a/app/routes/issues.py +++ b/app/routes/issues.py @@ -219,7 +219,10 @@ def view(issue_id): ) db.session.add(comment) - db.session.commit() + # NOTE: do NOT commit here — the issue, comment, and all notification + # rows are staged together and committed atomically at the end of the + # notification block below. Committing early risks partial state if the + # server crashes between the two commits. current_app.logger.info( 'ISSUE UPDATED | id=%s | status=%s | result_photos_added=%s | comment=%s | updated_by=%s', issue.id, issue.status, len(new_photos), bool(comment_body), current_user.username @@ -349,7 +352,7 @@ def view(issue_id): facility_id = facility_id, exclude_user_ids = {current_user.id}, ) - db.session.commit() # Commit all notifications + db.session.commit() # Single atomic commit: issue fields + comment + all notification rows log_action(ACTION_UPDATE, 'Issue', issue.id, f'#{issue.id} in {issue.area.name if issue.area else issue.resolved_facility.name if issue.resolved_facility else '—'}', f'status={issue.status}; assigned_to={issue.assigned_to}') @@ -591,11 +594,14 @@ def verification_queue(): from app.models.facility import Facility, Area from app.utils.sla import sla_status, sla_hours_remaining + # outerjoin so that standalone issues (area_id=NULL, facility_id set directly) + # are included alongside area-linked issues. An INNER JOIN would silently + # drop every issue created via /issues/new which carries no area_id. pending = ( Issue.query - .join(Area, Issue.area_id == Area.id) + .outerjoin(Area, Issue.area_id == Area.id) .filter(Issue.status == 'pending_verification') - .order_by(Area.facility_id, Issue.reported_at.asc()) + .order_by(Issue.reported_at.asc()) .all() )