diff --git a/containers/backupchecks/src/backend/app/main/routes_api.py b/containers/backupchecks/src/backend/app/main/routes_api.py index 395968a..3b7b740 100644 --- a/containers/backupchecks/src/backend/app/main/routes_api.py +++ b/containers/backupchecks/src/backend/app/main/routes_api.py @@ -16,7 +16,8 @@ def api_job_run_alerts(run_id: int): tickets = [] remarks = [] - # Tickets active for this job on this run date (including resolved-on-day) + # Tickets linked to this specific run + # Only show tickets that were explicitly linked via ticket_job_runs try: rows = ( db.session.execute( @@ -30,19 +31,13 @@ def api_job_run_alerts(run_id: int): t.active_from_date FROM tickets t JOIN ticket_scopes ts ON ts.ticket_id = t.id - WHERE ts.job_id = :job_id - AND t.active_from_date <= :run_date - AND ( - COALESCE(ts.resolved_at, t.resolved_at) IS NULL - OR ((COALESCE(ts.resolved_at, t.resolved_at) AT TIME ZONE 'UTC' AT TIME ZONE :ui_tz)::date) >= :run_date - ) + JOIN ticket_job_runs tjr ON tjr.ticket_id = t.id + WHERE tjr.job_run_id = :run_id ORDER BY t.start_date DESC """ ), { - "job_id": job.id if job else None, - "run_date": run_date, - "ui_tz": _get_ui_timezone_name(), + "run_id": run_id, }, ) .mappings() @@ -71,7 +66,8 @@ def api_job_run_alerts(run_id: int): except Exception as exc: return jsonify({"status": "error", "message": str(exc) or "Failed to load tickets."}), 500 - # Remarks active for this job on this run date (including resolved-on-day) + # Remarks linked to this specific run + # Only show remarks that were explicitly linked via remark_job_runs try: rows = ( db.session.execute( @@ -80,22 +76,13 @@ def api_job_run_alerts(run_id: int): SELECT r.id, r.body, r.start_date, r.resolved_at, r.active_from_date FROM remarks r JOIN remark_scopes rs ON rs.remark_id = r.id - WHERE rs.job_id = :job_id - AND COALESCE( - r.active_from_date, - ((r.start_date AT TIME ZONE 'UTC' AT TIME ZONE :ui_tz)::date) - ) <= :run_date - AND ( - r.resolved_at IS NULL - OR ((r.resolved_at AT TIME ZONE 'UTC' AT TIME ZONE :ui_tz)::date) >= :run_date - ) + JOIN remark_job_runs rjr ON rjr.remark_id = r.id + WHERE rjr.job_run_id = :run_id ORDER BY r.start_date DESC """ ), { - "job_id": job.id if job else None, - "run_date": run_date, - "ui_tz": _get_ui_timezone_name(), + "run_id": run_id, }, ) .mappings() diff --git a/docs/changelog-claude.md b/docs/changelog-claude.md index cf284d4..05cee96 100644 --- a/docs/changelog-claude.md +++ b/docs/changelog-claude.md @@ -9,6 +9,7 @@ This file documents all changes made to this project via Claude Code. - Fixed internal and Autotask tickets being linked to new runs even after being resolved by removing date-based "open" logic from ticket query (tickets now only link to new runs if they are genuinely unresolved, not based on run date comparisons) - Fixed Job Details page showing resolved tickets for ALL runs by implementing two-source ticket display: directly linked tickets (via ticket_job_runs) are always shown for audit trail, while active window tickets (via scope query) are only shown if unresolved, preserving historical ticket links while preventing resolved tickets from appearing on new runs - Fixed Run Checks page showing resolved ticket indicators by removing date-based logic from ticket/remark existence queries (tickets and remarks now only show indicators if genuinely unresolved) +- Fixed Run Checks popup showing resolved tickets for runs where they were never linked by replacing date-based ticket/remark queries in `/api/job-runs//alerts` endpoint with explicit link-based queries (now only shows tickets/remarks that were actually linked to the specific run via ticket_job_runs/remark_job_runs tables, completing the transition from date-based to explicit-link ticket system) ### Changed - Added debug logging to ticket linking function to troubleshoot resolved ticket propagation issues (writes to AuditLog table with event_type "ticket_link_debug", visible on Logging page, logs EVERY run import to show whether tickets were found and their resolved_at status, uses commit instead of flush to ensure persistence)