Jul 31 - Update to ensure customers don't get notification for internal comments

This commit is contained in:
2026-07-31 15:03:47 -04:00
parent 31ffeb0abf
commit f9c93ca3ed
2 changed files with 48 additions and 9 deletions
+46 -8
View File
@@ -30,17 +30,31 @@ logger = logging.getLogger(__name__)
# ── Shared helper ─────────────────────────────────────────────────────────────
def _notify_followers(issue, title, body, exclude_user_ids=None):
"""Dispatch a notification to every follower of the given issue."""
def _notify_followers(issue, title, body, exclude_user_ids=None,
customer_body=None, skip_customers=False):
"""Dispatch a notification to every follower of the given issue.
Customer followers are handled separately so a staff-only (internal) comment
never leaks to them: pass ``skip_customers=True`` to omit customer followers
entirely, or ``customer_body`` to send them a customer-safe message in place
of ``body``. Non-customer followers always receive ``body``.
"""
exclude = set(exclude_user_ids or [])
issue_link = url_for('issues.view', issue_id=issue.id)
for follower in issue.followers.all():
if follower.user_id in exclude:
continue
is_customer = bool(follower.user) and follower.user.role == 'customer'
if is_customer:
if skip_customers:
continue
f_body = customer_body if customer_body is not None else body
else:
f_body = body
notify(
recipient = follower.user,
title = title,
body = body,
body = f_body,
link = issue_link,
issue_id = issue.id,
event_type = EVENT_ISSUE_FOLLOW,
@@ -585,34 +599,58 @@ def view(issue_id):
if old_assigned_to:
exclude_ids.add(old_assigned_to)
# Whether the comment just added is visible to customers. Internal
# (staff-only) comments must NEVER reach customer accounts — they only
# ever hear about comments explicitly shared with them. Only staff reach
# this branch (customers POST via the earlier customer-only path), so the
# checkbox governs. `changes` drives staff-facing notifications;
# `customer_changes` drives every customer-facing dispatch.
comment_customer_visible = bool(comment_body) and ('is_customer_visible' in request.form)
changes = []
customer_changes = []
if old_status != issue.status:
changes.append(
_c = (
f'status changed from "{old_status.replace("_"," ").title()}" '
f'to "{issue.status.replace("_"," ").title()}"'
)
changes.append(_c)
customer_changes.append(_c)
if old_assigned_to != new_assigned_to:
_new_assignee_obj = db.session.get(User, new_assigned_to) if new_assigned_to else None
new_name = _new_assignee_obj.username if _new_assignee_obj else 'Unassigned'
changes.append(f'reassigned to {new_name}')
_c = f'reassigned to {new_name}'
changes.append(_c)
customer_changes.append(_c)
if comment_body:
changes.append(f'new comment added by {current_user.username}')
if comment_customer_visible:
customer_changes.append(f'new comment added by {current_user.username}')
if changes:
_loc = issue.area.name if issue.area else issue.resolved_facility.name if issue.resolved_facility else ''
customer_relevant = bool(customer_changes)
_notify_followers(
issue = issue,
title = f'Issue #{issue.id} Updated',
body = (
f'Issue #{issue.id} in {issue.area.name if issue.area else issue.resolved_facility.name if issue.resolved_facility else ''} was updated by '
f'Issue #{issue.id} in {_loc} was updated by '
f'{current_user.username}: {"; ".join(changes)}.'
),
customer_body = (
f'Issue #{issue.id} in {_loc} was updated by '
f'{current_user.username}: {"; ".join(customer_changes)}.'
) if customer_relevant else None,
skip_customers = not customer_relevant,
exclude_user_ids = exclude_ids,
)
# ── Notify via matrix (issue_updated_customer) ───────────────
# Gated on `customer_changes`: an update whose ONLY change is an internal
# comment leaves this empty, so no customer notification fires.
facility_id = issue.resolved_facility.id if issue.resolved_facility else None
if facility_id and changes:
changes_summary = '; '.join(changes)
if facility_id and customer_changes:
changes_summary = '; '.join(customer_changes)
notify_by_matrix(
event_type = 'issue_updated_customer',
title = f'Issue #{issue.id} Updated at {issue.resolved_facility.name if issue.resolved_facility else ''}',