Commit Graph

635 Commits

Author SHA1 Message Date
0d9159ef6f Fix Run Checks popup showing resolved tickets
The Run Checks popup modal was still showing resolved tickets
for runs where they were never actually linked. This was the last
remaining location using date-based ticket logic.

Root cause:
The /api/job-runs/<run_id>/alerts endpoint used the old date-based
logic that showed all tickets scoped to the job if active_from_date
was before the run date. This ignored whether the ticket was actually
linked to that specific run.

Changes:
- Replaced date-based query with explicit ticket_job_runs join
- Replaced date-based query with explicit remark_job_runs join
- Now only returns tickets/remarks actually linked to this run
- Removed unused run_date, job_id, ui_tz query parameters
- Simplified queries: no timezone conversions, no date comparisons

Result: Resolved tickets no longer appear in popup unless they were
linked to that run when they were still open. Completes transition
from date-based to explicit-link ticket system across entire UI.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 11:07:28 +01:00
5b940e34f2 Fix Run Checks page showing resolved ticket indicators
The Run Checks main page has ticket/remark indicators (🎫/💬) that
use queries to check if active tickets/remarks exist for each job.
These queries still used the old date-based logic.

Changes:
- Removed date-based OR clause from ticket indicator query
- Removed date-based OR clause from remark indicator query
- Simplified parameters (removed ui_tz from ticket query)
- Now consistent with Job Details and linking behavior

Result: Run Checks indicators no longer show for resolved tickets,
matching the behavior across all pages.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 10:57:14 +01:00
43502ae6f3 Fix: Show resolved tickets only on runs where they were linked
Previous fix removed ALL resolved tickets from display, breaking
audit trail. Users need to see which tickets were associated with
historical runs, even after resolution.

Solution: Two-source ticket display
1. Direct links (ticket_job_runs): Always show, even if resolved
   - Preserves audit trail
   - Shows tickets that were explicitly linked to runs
2. Active window (ticket_scopes): Only show unresolved
   - Prevents resolved tickets from appearing on NEW runs
   - Uses active_from_date without date-based resolved logic

Changes:
- Added direct_ticket_links map to fetch linked tickets per run
- Query ticket_job_runs for audit trail tickets
- Modified ticket_codes building to use both sources
- Removed date-based resolved_date comparison (resd >= rd)

Result:
- Run 1 with ticket → ticket resolved → ticket still visible on Run 1
- Run 2 created → ticket NOT shown on Run 2 (correctly filtered)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 10:53:45 +01:00
a9cae0f8f5 Fix Job Details page showing resolved tickets
The Job Details page used the same date-based logic that was causing
resolved tickets to appear for runs on the same day as the resolve date.

The linking was already fixed in ticketing_utils.py, but the display
query in routes_jobs.py still used the old logic, causing a mismatch:
- New runs were correctly NOT linked to resolved tickets
- But the UI still SHOWED resolved tickets due to the display query

Changes:
- Removed date-based OR clause from tickets query (line 201-204)
- Removed date-based OR clause from remarks query (line 239-242)
- Simplified query parameters (removed min_date and ui_tz)
- Now both linking AND display use consistent logic: resolved = hidden

Result: Resolved tickets and remarks no longer appear in Job Details
or any other view, matching the expected behavior.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 10:29:43 +01:00
1b5effc5d2 Reduce test email generation from 3 to 1 per status
User requested simpler test scenario with just 1 email per status
instead of 3, making testing and debugging easier.

Changes:
- Success: 1 email instead of 3
- Warning: 1 email instead of 3
- Error: 1 email instead of 3
- Each button now creates exactly 1 test mail
- Kept the most recent email (2026-02-09) from each set

This makes it easier to test ticket linking behavior without having
to deal with multiple runs per test cycle.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 10:14:32 +01:00
c1aeee2a8c Always log ticket linking attempts, not just when tickets found
Previous debug code only logged when tickets were found, making it
impossible to verify that the function was being called at all.

Changes:
- Move logging outside the if rows: block
- Always create audit log entry for every run import
- Log "No open tickets found" when rows is empty
- Use commit() instead of flush() to ensure persistence
- Add exception logging to catch any errors in debug code
- New event_type "ticket_link_error" for debug code failures

Now every email import will create a ticket_link_debug entry showing:
- Whether the function was called
- How many tickets were found (0 or more)
- Details of each ticket if found

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 10:10:23 +01:00
aea6a866c9 Change debug logging to write to AuditLog table
Flask logger output was not visible in Portainer logs or Logging page.
Changed to write debug info to audit_logs table instead, which is
visible on the Logging page in the UI.

Changes:
- Debug entries use event_type "ticket_link_debug"
- User field set to "system"
- Details field contains ticket info (one per line)
- Visible on Settings → Logging page

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 10:06:03 +01:00
c228d6db19 Add debug logging for ticket linking investigation
User reports that resolved internal tickets are still being linked to
new runs, even though Autotask tickets correctly stop linking. Added
debug logging to understand what the query is finding.

Changes:
- Query now returns resolved_at values for both ticket and scope
- Added logger.info statements showing found tickets and their status
- This will help diagnose whether tickets are truly resolved in DB

Temporary debug code to be removed after issue is identified.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 10:00:35 +01:00
88b267b8bd Remove date-based logic from ticket propagation
The ticket linking query had date-based logic that considered tickets
"open" for runs if:
- The ticket was unresolved, OR
- The resolved date >= run date

This caused resolved tickets to still link to new runs, which was
unexpected behavior. User confirmed tickets should ONLY link to new
runs if they are genuinely unresolved, regardless of dates.

Changes:
- Simplified query to only find tickets where resolved_at IS NULL
- Removed OR clause with date comparison
- Removed ui_tz parameter (no longer needed)
- Simplified Strategy 1 code (no extra resolved check needed)

Now tickets cleanly stop linking to new runs as soon as they are
resolved, for both internal and Autotask tickets.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 09:55:58 +01:00
4f208aedd0 Auto-commit local changes before build (2026-02-10 09:41:33) 2026-02-10 09:41:33 +01:00
caff435f96 Fix Autotask propagation to also check resolved status
The previous fix only checked if tickets were deleted, but Autotask
tickets can also be resolved (which is tracked via the internal Ticket
table, not the JobRun table).

Updated Strategy 2 to:
1. Find most recent non-deleted Autotask ticket
2. Check if its internal ticket is resolved
3. Only propagate if ticket is not deleted AND not resolved

This ensures tickets stop propagating when they are resolved in Autotask
(synced via PSA polling), matching the expected behavior.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 09:40:27 +01:00
f3b1b56b6a Fix Autotask ticket propagation to new runs
When a new run is created, Autotask tickets were not being propagated
if the associated internal ticket was resolved. This caused users to
have to manually re-link tickets on each new run.

The previous implementation relied on finding an open internal ticket
first, then using its ticket code to find a matching Autotask-linked run.
If the internal ticket was resolved, the Autotask propagation would fail.

This commit implements a two-strategy approach:
1. Strategy 1: Use internal ticket code (existing logic, improved error handling)
2. Strategy 2: Direct Autotask propagation - find most recent non-deleted
   Autotask ticket for the job, independent of internal ticket status

Now Autotask tickets remain linked across runs regardless of internal
ticket resolution status, matching the behavior of internal tickets.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 09:32:23 +01:00
596fc94e69 Merge branch 'v20260209-08-veeam-vbo365-not-started' into main 2026-02-09 17:26:15 +01:00
49f24595c3 Merge branch 'v20260209-07-synology-drive-health-parser' into main 2026-02-09 17:26:04 +01:00
fd3f3765c3 Merge branch 'v20260209-06-synology-firmware-update-parser' into main 2026-02-09 17:25:30 +01:00
2a03ff0764 Merge branch 'v20260209-05-responsive-navbar-fix' into main 2026-02-09 17:25:19 +01:00
d7f6de7c23 Release v0.1.25 on branch v20260209-08-veeam-vbo365-not-started (bump type 1) 2026-02-09 17:21:39 +01:00
57196948a7 Add v0.1.25 to website changelog
Update changelog.md and changelog.py with comprehensive v0.1.25 release notes
consolidating all changes from 2026-02-09:

Sections:
- Parser Enhancements: Synology (Drive Health, DSM Updates, ABB Skipped) and
  Veeam (Job Not Started)
- Maintenance Improvements: Orphaned Jobs Cleanup, Test Email Generation
- Data Privacy: Parser Registry Cleanup, Autotask Title Simplification
- Bug Fixes: Responsive Navbar Overlap Fix

This release focuses on parser coverage expansion and system maintenance
capabilities while improving data privacy practices.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 17:17:47 +01:00
acb9fbb0ea Auto-commit local changes before build (2026-02-09 17:13:17) 2026-02-09 17:13:17 +01:00
3b48cd401a Add Veeam parser support for "Job did not start on schedule" error notifications
Extend Veeam parser to recognize and handle error notifications when a backup
job fails to start on its scheduled time. This commonly occurs when proxy
servers are offline or other infrastructure issues prevent job execution.

Features:
- Detects "Job did not start on schedule" pattern in subject line
- Extracts backup type from subject (e.g., "Veeam Backup for Microsoft 365")
- Extracts job name from subject after colon (e.g., "Backup MDS at Work")
- Reads error message from plain text body (handles base64 UTF-16 encoding)
- Sets overall_status to "Error" for failed-to-start jobs
- Example message: "Proxy server was offline at the time the job was scheduled to run."

This handles VBO365 and other Veeam backup types that send plain text error
notifications instead of the usual HTML formatted reports.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 17:12:53 +01:00
21f5c01148 Auto-commit local changes before build (2026-02-09 17:02:31) 2026-02-09 17:02:31 +01:00
f539d62daf Add Synology monthly drive health report parser
Add parser for Synology monthly drive health reports with support for both
Dutch and English notifications. Reports are classified as informational
and excluded from schedule learning and reporting logic.

Features:
- Recognizes Dutch ("Maandelijks schijfintegriteitsrapport", "Gezond") and
  English ("Monthly Drive Health Report", "Healthy") variants
- Extracts hostname from subject or body ("Van/From NAS-HOSTNAME")
- Automatic status detection: Healthy/Gezond/No problem detected → Success,
  otherwise → Warning
- Backup type: "Health Report", Job name: "Monthly Drive Health"
- Added registry entry (order 237) for /parsers page visibility

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 17:02:08 +01:00
b6a85d1c8e Extend Synology DSM update parser with automatic installation announcement patterns
Add detection patterns for DSM update notifications that announce automatic
installation ("belangrijke DSM-update", "kritieke oplossingen", "wordt
automatisch geïnstalleerd", "is beschikbaar op"). This is the fourth variant
of DSM update notifications now handled by the same Updates parser job.

All changes maintain backward compatibility by extending existing pattern lists.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 16:45:23 +01:00
5549323ff2 Extend Synology Active Backup for Business parser for skipped tasks
Extended the parser to recognize backup tasks that were skipped/ignored
because a previous backup was still running. These are treated as Warning
status for monitoring purposes.

Changes:
- Extended _ABB_COMPLETED_RE regex to match "genegeerd" (NL) and "skipped"/"ignored" (EN)
- Added "van deze taak" pattern for Dutch phrasing variations
- Added status detection for skipped tasks (Warning with "Skipped" message)
- All existing patterns remain functional (backward compatible)
- Updated changelog

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 16:25:27 +01:00
b4aa7ef2f6 Extend Synology Updates parser for new DSM update available notifications
Extended the parser to recognize DSM update available notifications in addition
to update cancelled and package out-of-date notifications. All variants fall
under same Updates job type for unified monitoring.

Changes:
- Added "new DSM update", "Auto Update has detected", "new version of DSM", "Update & Restore" to detection patterns
- Extended hostname extraction regex to match "detected on HOSTNAME"
- Now recognizes three notification types: update cancelled, packages out-of-date, update available
- All existing patterns remain functional (backward compatible)
- Updated changelog

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 16:03:11 +01:00
9576d1047e Extend Synology Updates parser to recognize out-of-date package notifications
Extended the parser to recognize both DSM update cancelled notifications AND
out-of-date package notifications under the same "Updates" job type, as they
can appear together in combined notifications.

Changes:
- Added "Packages on", "out-of-date", "Package Center" to detection patterns
- Extended hostname extraction regex to match "Packages on HOSTNAME" and "running on HOSTNAME"
- Both notification types now fall under same job (backup_type: Updates)
- All existing patterns remain functional (backward compatible)
- Updated changelog

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 15:58:08 +01:00
1e3a64a78a Auto-commit local changes before build (2026-02-09 15:46:49) 2026-02-09 15:46:49 +01:00
a05dbab574 Extend Synology DSM update parser with additional detection patterns
Extended the parser to recognize more email variants for Synology DSM
automatic update cancelled notifications while maintaining backward
compatibility with existing patterns.

Changes:
- Added "Automatische DSM-update" and "DSM-update op" to detection patterns
- Extended hostname extraction regex to match "DSM-update op HOSTNAME" and "DSM update on HOSTNAME"
- All existing patterns remain functional (backward compatible)
- Updated changelog

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 15:41:20 +01:00
0827fddaa5 Add Synology DSM update parser and remove customer names from registry
Added parser registry entry for Synology DSM automatic update cancelled
notifications. These are informational messages that don't participate in
schedule learning or reporting logic.

Also removed real customer names from parser registry examples to prevent
customer information from being stored in the codebase. Replaced with
generic placeholders like NAS-HOSTNAME, SERVER-HOSTNAME, VM-HOSTNAME.

Changes:
- Added synology_dsm_update parser entry in registry.py (order 236)
- Parser matches on DSM-update/DSM update in subject and automatic/automatische in body
- Returns backup_software: Synology, backup_type: Updates, informational status
- Replaced customer names in NTFS Auditing example (bouter.nl → example.local)
- Replaced customer names in QNAP example (BETSIES-NAS01 → NAS-HOSTNAME)
- Replaced customer names in NAKIVO example (kuiperbv.nl → VM-HOSTNAME)
- Updated changelog

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 15:36:40 +01:00
61b8e97e34 Auto-commit local changes before build (2026-02-09 15:14:18) 2026-02-09 15:14:18 +01:00
9197c311f2 Fix responsive navbar overlapping content on smaller screens
Added dynamic padding adjustment that measures the actual navbar height and
applies it to the main content padding-top. This prevents the navbar from
overlapping page content when it becomes taller on narrow screens.

Changes:
- Removed fixed padding-top: 80px from main content
- Added id="main-content" to main element for JavaScript targeting
- Added JavaScript function that measures navbar.offsetHeight
- Function applies dynamic padding-top with 20px buffer for spacing
- Triggers on: page load, window load, window resize (debounced), navbar collapse toggle
- Includes fallback to 80px if measurement fails
- Updated changelog

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 15:11:47 +01:00
26848998e1 Fix test email generator to use correct Veeam format and consistent job name
Changed test emails to use proper Veeam Backup Job format that matches parser
expectations. All test emails now use the same job name "Test-Backup-Job" so
they appear as different runs of the same job, enabling proper status testing.

Changes:
- Switched from multiple backup software to Veeam only for simplicity
- Fixed subject format to: Veeam Backup Job "Test-Backup-Job" finished with Success/WARNING/Failed
- Fixed body format to include: Backup job: Test-Backup-Job
- All 3 emails per set use same job name but different dates
- Added realistic VM objects (VM-APP01, VM-DB01, VM-WEB01) with status details
- Each set shows different failure scenarios for testing
- Updated changelog description

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 14:54:42 +01:00
19ef9dc32a Update test email generator with fixed sets and separate buttons
Changed from configurable count input to three separate buttons for
success, warning, and error test emails. Each button generates exactly
3 emails with consistent data for reproducible testing.

Changes:
- Updated routes_settings.py to use fixed email sets instead of random data
- Changed route from /settings/test-emails/generate to /settings/test-emails/generate/<status_type>
- Created three predefined email sets (success, warning, error) with fixed content
- Updated settings.html UI to show three separate buttons instead of count input
- Each set contains 3 emails simulating Veeam, Synology, and NAKIVO backups
- Updated changelog with detailed description

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 14:44:19 +01:00
e187bc3fa5 Auto-commit local changes before build (2026-02-09 14:37:36) 2026-02-09 14:37:36 +01:00
96092517b4 Add test email generator for testing and development
Added feature to generate test emails in inbox for testing purposes:
- Simulates backup notifications from Veeam, Synology, and NAKIVO
- Configurable count (1-50 emails)
- Random job names, statuses, and timestamps
- Emails are parser-compatible for testing inbox approval workflow
- Useful for testing orphaned jobs cleanup and other maintenance ops
- Admin-only feature in Settings → Maintenance

Templates include:
- Veeam: Various job statuses with detailed backup info
- Synology: Backup task notifications
- NAKIVO: Job completion reports

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 14:37:02 +01:00
08437aff7f Fix audit logging call for orphaned jobs deletion
Added missing 'message' parameter to _log_admin_event call and
converted details dict to JSON string to match the function signature.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 14:31:34 +01:00
710aba97e4 Fix foreign key constraint: delete mail_objects before mails
Added deletion of mail_objects before deleting mail_messages to
avoid foreign key constraint violation. The mail_objects table
has a foreign key to mail_messages.

Complete deletion order:
1. Clean up auxiliary tables
2. Unlink mails from jobs
3. Delete mail_objects
4. Delete jobs (cascades to runs)
5. Delete mails

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 14:26:53 +01:00
ff4942272f Fix foreign key constraint: unlink mails from jobs before deletion
Added UPDATE to set mail_messages.job_id = NULL before deleting jobs
to avoid foreign key constraint violation. The mail_messages table
has a foreign key to jobs, so we must unlink them first.

Complete correct order:
1. Clean up auxiliary tables
2. Unlink mails from jobs (SET job_id = NULL)
3. Delete jobs (cascades to runs)
4. Delete mails

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 14:25:13 +01:00
f332e61288 Fix foreign key constraint error when deleting orphaned jobs
Moved mail deletion to after job deletion to avoid foreign key
constraint violations. The job_runs have a foreign key to
mail_messages, so jobs (and their cascaded runs) must be deleted
first before the mails can be deleted.

Correct order:
1. Clean up auxiliary tables (ticket_job_runs, remark_job_runs, etc)
2. Delete jobs (cascades to runs via ORM)
3. Delete mails (no more foreign key references)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 14:14:17 +01:00
82fff08ebb Remove redundant Step 1 text from maintenance card
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 14:11:52 +01:00
e932fdf30a Remove direct delete button, enforce preview step
Removed 'Delete orphaned jobs' button from maintenance page to
enforce verification workflow. Users must now:
1. Click 'Preview orphaned jobs' to see the list
2. Verify which jobs will be deleted
3. Click 'Delete All' on the preview page

This prevents accidental deletion without verification.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 14:10:33 +01:00
7f8dffa3ae Add preview page for orphaned jobs before deletion
Added verification step before deleting orphaned jobs:
- New GET endpoint /settings/jobs/orphaned to preview the list
- Shows detailed table with job name, backup software/type, customer ID,
  run count, and email count
- "Preview orphaned jobs" button on maintenance page
- Delete button on preview page shows exact count
- Summary shows total jobs, runs, and emails to be deleted

This allows admins to verify which jobs will be deleted before
taking the destructive action.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 14:07:12 +01:00
fec28b2bfa Auto-commit local changes before build (2026-02-09 13:49:21) 2026-02-09 13:49:21 +01:00
91062bdb0d Update .last-branch 2026-02-09 13:49:02 +01:00
ff316d653a Auto-commit local changes before build (2026-02-09 13:46:55) 2026-02-09 13:46:55 +01:00
60c7e89dc2 Add cleanup orphaned jobs maintenance option
Added new maintenance option in Settings → Maintenance to delete
jobs that are no longer linked to an existing customer (customer_id
is NULL or customer doesn't exist).

Features:
- Finds all jobs without valid customer link
- Deletes jobs, runs, and related emails permanently
- Cleans up auxiliary tables (ticket_job_runs, remark_job_runs,
  scopes, overrides)
- Provides feedback on deleted items count
- Logs action to audit log

Use case: When customers are removed, their jobs and emails should
be completely removed from the database.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 13:46:07 +01:00
b0efa7f21d Remove customer name from Autotask ticket titles
Changed ticket title format from:
  [Backupchecks] Customer Name - Job Name - Status
To:
  [Backupchecks] Job Name - Status

Customer information is already available in the ticket's company
field, making it redundant in the title and causing unnecessarily
long ticket titles.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-09 13:34:21 +01:00
b7875dbf55 Merge v20260209-01-fix-ticket-description into main (v0.1.24) 2026-02-09 13:16:04 +01:00
d400534069 Merge v20260207-02-wiki-documentation into main (v0.1.23) 2026-02-09 13:15:58 +01:00
bb701d5f00 Release v0.1.24 on branch v20260209-01-fix-ticket-description (bump type 1) 2026-02-09 13:03:06 +01:00