From 4900ddc2cc9591fe0bb39aa39b5930caf811c284 Mon Sep 17 00:00:00 2001 From: NguyenND Date: Thu, 16 Jul 2026 15:56:18 -0400 Subject: [PATCH] Jul 16 - Update submission will trigger notification to self inspector only --- CLAUDE.md | 4 ++++ app/models/notification_matrix.py | 4 ++++ app/utils/notifications.py | 14 ++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index a311ad3..4ca4691 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -715,6 +715,10 @@ EVENT_SCORE_ALERT = 'score_alert' ← Phase 27 EVENT_SCHEDULED_INSPECTION = 'scheduled_inspection' ← Phase 36 ``` +### Inspector role scoping for `inspection_completed` + +`notify_by_matrix()` special-cases the **inspector** role for the `inspection_completed` event: instead of notifying every active inspector, it notifies **only the inspection's own inspector** (`Inspection.inspector_id`, resolved from the passed `inspection_id`). So enabling the "Inspector" column for "Inspection completed" in the matrix alerts just the inspector who submitted that inspection — not the whole inspector pool. All three dispatch sites (web `routes/inspections.py`, both mobile-API `api/inspections.py`) pass `inspection_id`, so the scoping applies uniformly; if `inspection_id` is ever omitted for this event, the inspector role notifies no one (fail-closed). Other roles/events are unaffected. + ### Per-Contract Additional Recipients (Phase 33) `notify_by_matrix()` is the single dispatch point for all broadcast events. After routing to the global matrix roles + global custom emails, it calls `_notify_contract_recipients()`, which: diff --git a/app/models/notification_matrix.py b/app/models/notification_matrix.py index 80e7a7b..d7b1e20 100644 --- a/app/models/notification_matrix.py +++ b/app/models/notification_matrix.py @@ -10,6 +10,10 @@ role_key values admin — all users with role='admin' director — all users with role='director' inspector — all users with role='inspector' + EXCEPTION: for event 'inspection_completed', the inspector + column notifies ONLY the inspection's own inspector + (the submitter), not the whole inspector pool. Scoping is + applied in notify_by_matrix() via the inspection_id. project_manager — all users with role='project_manager' customer — all customer-portal users assigned to the relevant facility assignee — the specific user the issue/inspection is assigned to diff --git a/app/utils/notifications.py b/app/utils/notifications.py index f3716dc..e504e0d 100644 --- a/app/utils/notifications.py +++ b/app/utils/notifications.py @@ -569,6 +569,20 @@ def notify_by_matrix( logger.info('MATRIX NOTIFY | event=%s | role=%s | users_found=%s', event_type, role_key, [u.username for u in users]) + # Scope the inspector role for "inspection_completed" to the inspection's + # OWN inspector (the person who did the work), not the whole inspector + # pool. Without this, enabling the Inspector column for this event would + # notify every inspector on every submission. + if role_key == 'inspector' and event_type == 'inspection_completed': + target_id = None + if inspection_id: + from app.models.inspection import Inspection + insp = db.session.get(Inspection, inspection_id) + target_id = insp.inspector_id if insp else None + users = [u for u in users if u.id == target_id] if target_id else [] + logger.info('MATRIX NOTIFY | event=%s | role=inspector scoped to ' + 'submitting inspector_id=%s', event_type, target_id) + # Scope customer role to facility if provided if role_key == 'customer' and facility_id: from app.utils.notifications import notify_customers_for_facility