Critical bug: Same ticket appeared multiple times in popup
(e.g., T20260127.0061 showed 8 times).
Root Cause:
The JOIN with ticket_scopes/remark_scopes created duplicate rows
when a ticket had multiple scopes (Cartesian product).
Changes:
- Removed unnecessary JOIN ticket_scopes from tickets query
- Removed unnecessary JOIN remark_scopes from remarks query
- Added DISTINCT to prevent any duplicate rows
- Changed COALESCE(ts.resolved_at, t.resolved_at) to t.resolved_at
(ticket_scopes JOIN removed, only ticket resolution matters)
Result: Each ticket/remark now appears exactly once in popup.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added the Settings Maintenance page text update to the official
v0.1.26 release notes before the first build.
Changes:
- Updated docs/changelog.md with User Interface subsection
- Updated changelog.py with User Interface subsection
- Both now document the test email text change (3→1, Veeam only)
All three changelogs (changelog.md, changelog.py, changelog-claude.md)
now include this UI improvement in v0.1.26.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The UI text still mentioned "3 emails simulating Veeam, Synology,
and NAKIVO" but the actual behavior changed to 1 Veeam email per button.
Changes:
- Updated description: Now states "1 Veeam Backup Job email" per button
- Updated button labels: "emails (3)" → "email (1)"
- Clarified that only Veeam test emails are generated
This matches the actual implementation that was changed earlier.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Prepared official release documentation for v0.1.26 consolidating
all ticket system bug fixes from 2026-02-10.
Changes:
- Updated docs/changelog.md with v0.1.26 release notes
- Detailed root cause analysis of date-based logic issues
- Complete list of fixed pages (4 locations)
- Before/after behavior explanation
- Testing and troubleshooting section
- Updated changelog.py with v0.1.26 entry for website display
- Same content structured for Python data format
- Updated changelog-claude.md with release reference
Release Focus:
- Complete transition from date-based to link-based ticket queries
- Fixed resolved tickets appearing on new runs (4 pages affected)
- Preserved audit trail for historical runs
- Consistent behavior across entire application
Ready for production deployment.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The ticket propagation issues have been resolved. Debug logging
is no longer needed in production code.
Changes:
- Removed AuditLog debug logging from link_open_internal_tickets_to_run
- Preserved debug logging code in backupchecks-system.md for future use
- Updated changelog to document removal
The debug code is available in the technical documentation if
troubleshooting is needed again in the future.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Updated both docs/changelog.md and changelog.py with v0.1.24
release notes documenting the Autotask ticket description fix.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
When resolving Autotask tickets via the update_ticket_resolution_safe
function, the description field was not included in the PUT payload,
causing it to be set to NULL by Autotask.
Fixed by adding "description" to the optional_fields list so it is
preserved from the GET response and included in the PUT request.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed to clarify that Autotask integration supports MANUAL ticket creation
(not automatic creation on failures). The integration exists and handles:
- Manual ticket creation in Autotask from Run Checks modal
- Synchronization between BackupChecks and Autotask tickets
- Automatic resolution when Autotask tickets are resolved/deleted
Removed incorrect claim about automatic ticket creation on failures.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed entire "Integration with Autotask" section that incorrectly
described automatic ticket creation for backup failures. This feature
does not exist and is not planned.
Changes:
- Removed section explaining automatic ticket creation in Autotask
- Removed link to Autotask Integration from Next Steps
- Updated changelog with removal
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Corrected documentation to accurately reflect that review is done per-JOB
(not per individual run). When marking a job as reviewed, ALL runs within
that job are marked simultaneously and the job disappears from Run Checks.
Changes:
- Run Checks Modal: Removed non-existent "reviewed indicator", clarified
per-job review in Page Layout callout, updated Mark as Reviewed section
to explain all runs for job are marked together, changed bulk review from
"select multiple run checkboxes" to "select multiple job checkboxes",
updated Unmark Reviewed to reflect per-job unmarking, removed incorrect
statement that successful runs are automatically reviewed
- Approving Backups: Updated bulk review section from "runs" to "jobs" for
consistency with per-job review mechanism
- Changelog: Updated with all per-job review fixes
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed entire 'Complete Workflow Example' section (Day 1-15 scenario)
as the stage-by-stage descriptions (Stage 1-7) are clearer and more
focused. The detailed example was redundant and made the page too long.
The stage descriptions already provide sufficient detail for understanding
the backup review workflow.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added Success (Override) with blue badge to status indicators list
- Added callout clarifying Daily Jobs is NOT part of daily workflow
- Emphasized Daily Jobs is informational only (view schedules and status)
- Noted Daily Jobs may be deprecated in future version
- Changed link text from 'operational monitoring' to 'informational page'
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed Expected from 'Blue badge' to 'White badge (with border)' to match
actual CSS implementation and be consistent with Daily Jobs page.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed Expected badge from 'Light Blue' to 'White' (with border) to match actual
CSS implementation (background: #fff with border: 2px solid var(--bs-secondary)).
Status indicators now correctly show:
- Green = Success
- Blue = Success (Override)
- Yellow = Warning
- Red = Failed
- Gray = Missed
- White (with border) = Expected
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Corrected workflow based on user feedback:
- ALL runs must be marked as reviewed (including successes with overrides/tickets)
- Run Checks is THE primary daily tool (not Daily Jobs)
- Added blue badge for override-applied runs (not green)
- Goal: completely empty Run Checks page
- Added bulk review functionality for efficiency
- Rewrote Complete Workflow Example to focus on Run Checks
- Daily Jobs may be deprecated (only for viewing schedules)
Changed files:
- approving-backups.html: Stage 6/7 corrections, new workflow example
- daily-jobs.html: Added blue override badge, clarified secondary role
- run-checks-modal.html: Emphasized primary role, added bulk review
- overrides.html: Blue badge instead of green for overrides
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added comprehensive documentation for the Backup Review workflow:
- Daily Jobs View: Schedule inference, status tracking, override/ticket/remark indicators
- Run Checks Modal: Detailed review interface with objects, email content, Autotask info
- Overrides & Exceptions: Global and object-level override rules with match criteria
- Remarks & Tickets: Issue tracking with scopes, filtering, and lifecycle management
- Approving Backups: Complete workflow from email import to review completion
All content based on actual code implementation - no fabricated features.
Progress: 19 of 33 pages complete (58%)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Major corrections to Mail Parsing documentation - removed non-existent features:
Parsers Page Location:
- Fixed: "Parsers" page (separate navigation page), NOT "Settings → Parsers"
- Location corrected throughout document
Parser Information Table:
- REMOVED "Enabled" column (doesn't exist, suggested false capability)
- Added callout: "Read-Only Parser List" - parsers cannot be managed via UI
REMOVED Entire Section: "Enabling and Disabling Parsers"
- This feature DOES NOT EXIST
- Completely fabricated content about enabling/disabling parsers
- Removed all references to checkbox controls
- Removed all instructions about disabling parsers for troubleshooting
Re-parsing Emails:
- Clarified: ONLY "Re-parse all" available (not individual re-parse)
- Updated "When to Re-parse" - all actions done by developer, not users
- Removed "parser was disabled" scenario (impossible)
Custom Parsers Callout:
- Changed from "create one yourself" to "contact support"
- Emphasized: ONLY developer can create parsers
- Removed references to Python development skills
Troubleshooting Sections:
- REMOVED all references to "check if parser is enabled" (impossible)
- REMOVED "disable parser temporarily to test" (impossible)
- Changed to: "contact support with .eml files"
- Fixed all "Settings → Parsers" references to just "Parsers page"
REMOVED: "AI-Powered Parsing" Future Enhancement
- Completely fabricated claim about LLM parsing consideration
- NOT in planning, NOT being considered
- No source for this false information
Best Practices:
- REMOVED "Test new parsers" (users can't add parsers!)
- REMOVED "Keep parsers enabled" (users can't disable them!)
- Added: "Report parsing issues promptly to support"
- Focus on what users CAN do, not fabricated capabilities
All fabricated features removed. Documentation now reflects actual UI.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Critical corrections based on actual UI behavior:
Email Detail Modal Layout:
- Fixed layout description: TWO-COLUMN (not top/middle/bottom)
- Left side: Metadata + action buttons + parsed objects
- Right side: Email body in iframe
- Updated screenshot caption to reflect left/right layout
Action Buttons (Left Side):
- REMOVED "Re-parse" from modal (doesn't exist in modal!)
- Only available buttons: Approve, Delete, Download .eml
- Re-parse is ONLY on inbox page, not in modal
Approving Emails:
- FIXED: Job name is READ-ONLY during approval (cannot be edited!)
- Only customer selection is editable
- Added callout: "Job Name Cannot Be Changed"
- Removed all references to "edit job name" or "adjust job name"
Re-parsing Emails:
- REMOVED "Re-parse Single Email" section (doesn't exist!)
- Only "Re-parse all" available on inbox page
- Added callout: "No Individual Re-parse"
- Workaround: Delete unwanted emails, re-parse all, re-import
Deleting Emails:
- Fixed location: "Deleted Mails" page (Admin only)
- NOT in "Settings → Maintenance"
- It's a separate navigation page
Inbox Filters and Search:
- REMOVED entire section (not in planning, won't be implemented)
- No false expectations about future filtering features
Troubleshooting Unparsed Emails:
- FIXED: Parsers can ONLY be created by BackupChecks developer
- Users CANNOT create custom parsers
- Added warning callout about parser creation
- Instructions: Contact support with .eml samples
Best Practices:
- Removed "Edit job names during approval" (impossible!)
- Added "Verify parsed job names" - contact support if wrong
- Updated to reflect actual capabilities
All corrections ensure documentation matches actual UI behavior.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Critical corrections to Inbox Management documentation:
Overview & Page Layout:
- Clarified: Inbox displays only UNAPPROVED emails
- Added callout: "Inbox Shows Only Unapproved Emails"
- Explained: Approved emails immediately disappear from inbox
- Inbox is a staging area for emails awaiting approval/deletion
Email Detail Modal - Metadata Section:
- REMOVED incorrect fields that don't exist for inbox emails:
* "Customer: If already approved..." (approved emails aren't in inbox!)
* "Approved: Checkmark..." (no checkmark - they disappear when approved!)
- Added list of action buttons (Approve, Re-parse, Delete, Download .eml)
What Happens After Approval:
- Changed "moved out of inbox" to "immediately disappears from inbox"
- Added: Future emails are "automatically approved and linked WITHOUT
appearing in the inbox" - they go directly to operational views
- New callout: "Approved Emails Don't Return" explaining auto-approval flow
Inbox Filters and Search:
- Changed "all imported emails" to "all UNAPPROVED imported emails"
Common Workflows - Setting Up New Customer:
- Updated step 5: "approved emails disappear from inbox"
- Added step 6: Jobs appear in Jobs/Daily Jobs/Run Checks pages
- Updated step 7: Future reports auto-approved, never appear in inbox
This accurately reflects that the inbox is ONLY for unapproved emails.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Corrected Mail Import Setup documentation to accurately reflect UI:
Step 2.3: "Save Settings (Again)" instead of "Save Final Configuration"
- Clarified there is only ONE "Save settings" button on the page
- Same button is clicked TWICE: once after credentials, once after folders
- Added warning callout: "Same Button, Two Steps"
- Emphasized this is the same button from Step 2.1, not a separate button
Future Improvement note updated:
- Specifically mentions clicking same button twice is not obvious
- Suggests possible solutions: separate sections with distinct save buttons,
or visual feedback about which step user is on
This accurately reflects the current UI where a single "Save settings" button
serves double duty, which will be improved in a future version for clarity.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enhanced Mail Import Setup documentation to clarify configuration workflow:
Step 2.1 (Enter Graph Credentials):
- Added warning callout: Must save credentials FIRST before folder configuration
- Credentials must be saved and page refreshed before Step 2.2 works
Step 2.2 (Configure Mail Folders):
- Added prerequisite: Ensure credentials saved and page refreshed
- Clarified folder browser popup AUTOMATICALLY loads folder structure
- Emphasized: Don't type paths manually - click folders in popup
- Folder browser connects to Microsoft Graph and retrieves folders
- Added callout: Folder browser auto-generates correct path format
- Added note about planned UI improvement for clearer workflow
Step 2.3 (Save Final Configuration):
- Renamed from "Save Settings" to "Save Final Configuration"
- Clarified this is the SECOND save (first was in 2.1)
- Added tip callout explaining two-step save process
- Enhanced error checking list (credentials, folders, access policy)
This clarifies the actual user workflow where credentials enable folder browsing.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enhanced Mail Import Setup documentation with additional security measures:
- Step 1.3: Start with Mail.Read only (read-only) for initial testing
- Step 1.4 (NEW): Restrict access to one mailbox via Application Access Policy
- Exchange PowerShell commands to create and test policy
- Ensures app can only access backup mailbox, not all tenant mailboxes
- Marked as "Optional but Recommended" following principle of least privilege
- Step 1.5: Add Mail.ReadWrite after testing (moved from 1.3)
- Updated Security Best Practices section to emphasize mailbox restriction
- Added security notes about starting read-only and rotating secrets (12 months)
Based on setup documented in /docker/develop/HOWTO-CREATE-GRAPH-APP.md
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added comprehensive documentation for the Mail & Import section:
- Mail Import Setup: Microsoft Graph API configuration, Azure AD app registration,
folder setup, troubleshooting, and security best practices
- Inbox Management: Email review workflow, approval process, re-parsing,
deletion, and common workflows
- Mail Parsing: Parser system explanation, supported backup software,
match criteria, execution order, and troubleshooting
- Auto-Import Configuration: Automatic import scheduling, intervals, batch sizes,
auto-approval logic, manual import, and monitoring
Updated TODO-documentation.md to reflect progress (14 of 33 pages, 42% complete)
Updated changelog-claude.md with detailed content descriptions
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Corrected schedule display documentation based on actual UI:
Status Indicators (dots):
- Green dot: Job ran successfully
- Red dot: Job ran but failed
- White dot: Expected but not yet run (time not arrived)
- Gray dot: Expected but overdue (time passed, no run)
Run Count Badges:
- "1 run" (gray badge): Single run received
- "3 runs" (blue/cyan badge): Multiple runs received (stands out)
- Badge appears next to green dot when runs are successful
- Multiple runs (3+) highlighted with blue/cyan for attention
Removed incorrect description about:
- Run counters in parentheses (actually separate badges)
- Times shown only once (times can repeat for different runs)
Added Screenshot:
- schedule-indicators.png: Shows actual time slots with dots and badges
Enhanced workflow tip with specific actions for each indicator type.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added important details about schedule learning and Daily Jobs display:
Information Jobs:
- Added explanation for jobs without schedules (SSL cert updates, etc.)
- Information jobs are irregular and never learn a schedule pattern
- Will not appear on Daily Jobs page
Daily Jobs Color Indicators:
- Green: Ran successfully today
- Red: Ran with failure today
- White: Expected later today (time hasn't arrived yet)
- Gray: Expected but overdue (time has passed, no run received)
Multiple Runs Per Day:
- Schedule shows time only once
- Run counter displays number of runs (e.g., "10:00 (3)")
- Helps track jobs that run multiple times daily
Added callouts explaining:
- Information jobs concept
- Run counter meaning and usage
- White vs. gray indicator significance
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added documentation note about role-based column visibility:
Job History Table:
- "Reviewed by" column: Admin only
- "Reviewed at" column: Admin only
- Other columns visible to all roles with Jobs page access
Future Change Note:
- May be updated to show these columns to Operators as well
- Currently restricted to Admin role only
Added callout box explaining this restriction and potential future change.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Corrected documentation about archived jobs visibility:
Archived Jobs Access:
- No toggle/filter on Jobs page to show archived jobs
- Archived jobs are on a SEPARATE page
- Only accessible to Admin role (not Operators or Viewers)
- Separate menu item: "Archived Jobs"
Jobs Page:
- Shows only active jobs for active customers
- No option to view archived jobs on this page
- Archived jobs completely hidden from non-admin users
Unarchiving:
- Only admins can unarchive jobs
- Done from Archived Jobs page (not Jobs page)
- Unarchived jobs immediately reappear in operational views
Removed incorrect references to "Show archived jobs" toggle.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Corrected Jobs list and Job details page documentation:
Jobs List Table:
- Only 4 columns shown: Customer, Backup, Type, Job name
- Removed incorrect columns: Last Run, Status, Schedule, Actions
- Entire row is clickable (not just job name)
Job Details Page:
- Added comprehensive field descriptions:
- Customer, Backup, Type, Job name
- Tickets count (open/total)
- Remarks count (open/total)
- Schedule (inferred) with day/time table in 15-min blocks
- Archive button (gray)
- Delete job button (red)
Job History Table:
- Detailed column descriptions:
- Day run, Run time, Status (green dot for success)
- Tickets (with ticket numbers), Remarks, Override
- Reviewed by (username), Reviewed at (timestamp)
- Runs are clickable for full details
Removed:
- Job Status Indicators section (not shown in Jobs list)
- Incorrect Action buttons column
Added Screenshot:
- job-details.png: Shows complete job detail page with schedule and history
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Corrected documentation to reflect actual job detail functionality:
Job Detail Page:
- Can only Archive or Delete jobs
- Cannot edit job properties (customer, name, etc.)
- No edit function available on job detail page
Reassigning Jobs to Different Customer:
- Cannot change customer directly
- Must delete job to return emails to Inbox
- Re-approve from Inbox with correct customer selection
- Step-by-step process documented in Common Questions
Approved Jobs:
- Removed incorrect "Editing Job Information" section
- Replaced with "Job Detail Page" showing actual available actions
- Added warning that job properties cannot be edited
Configuring Jobs:
- Updated "Can I change the customer" question with correct process
- Emphasized delete-and-reapprove workflow
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated documentation to reflect that Mail Parsers can only be modified
by the system developer/maintainer, not by administrators:
- Configuring Jobs:
- Changed "parser must be updated (Admin only)" to "contact system developer/maintainer"
- Clarified parsers cannot be modified through BackupChecks UI
- Updated Common Questions section with same clarification
- Approved Jobs:
- Changed "Mail Parser configuration must be updated by administrator" to "contact system developer/maintainer"
- Added note that parsers are code-level components
Mail Parsers are Python code modules that require developer-level changes,
not configurable through the application interface.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Corrected job approval workflow based on actual UI:
Customer Selection:
- Customers CANNOT be created from Inbox
- Customers must be created on Customers page first
- Customer field has autocomplete with fuzzy matching
- Can type any part of customer name (e.g., "toso" finds "Contoso")
- "Select customer" placeholder text shown
- Approve job button only enabled when customer selected
Email Detail Modal:
- Added detailed field descriptions (From, Backup, Type, Job, Overall, etc.)
- Details panel shows parsed backup report content
- Success/failure status with color-coded header
- Backup statistics (start/end time, duration, size, compression)
- Catalog information and version details
- Approve job (blue), Delete (red), Close (gray) buttons
Added Screenshot:
- approve-job.png: Shows inbox email detail modal with customer selection
Removed incorrect information about automatic customer creation.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Corrected documentation to match actual customer management interface:
Customer Fields:
- Only customer name and active status (no contact fields)
- Customer name is not clickable
- Edit and Delete buttons on right side (no "Actions" column)
Edit Customer Dialog:
- Modal dialog with customer name and active checkbox
- Autotask mapping integrated in same dialog (not separate button)
- Search Autotask companies field with Search button
- Set mapping (blue), Refresh status (gray), Clear mapping (red) buttons
- Current mapping display with sync status timestamp
- Cancel and Save changes buttons
New Customer Interface:
- Simple form at top of page
- Only name field and Active checkbox
- Add button to create customer
- Browse... button for CSV file selection
- Import CSV and Export CSV buttons
- Refresh all Autotask mappings button
Added Screenshots:
- edit-customer.png: Shows edit dialog with Autotask mapping interface
- new-customers.png: Shows customer creation and CSV import/export controls
Removed incorrect information about contact person, email, phone, notes fields.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added comprehensive documentation for customer and job management:
- Managing Customers:
- Customer creation with contact information
- Editing customer details
- Active/inactive status and impact on job visibility
- Autotask company mapping workflow with auto-search
- CSV export/import for backup and migration
- Delete operations with warnings
- Job count indicators (red/bold when zero)
- Configuring Jobs:
- Inbox-based approval workflow (cannot manually create jobs)
- Mail Parser automatic configuration of all job fields
- Reparse All functionality for batch processing
- Job archiving vs deletion
- Job lifecycle stages
- Common questions and limitations
- Approved Jobs:
- Jobs list overview with status indicators
- Job detail page information
- Editable vs parser-determined fields
- Archive/unarchive workflow
- JSON export/import via Settings > Maintenance
- Status indicators (success/failed/warning/no runs)
- Job Schedules:
- Automatic schedule learning from historical runs
- Schedule types (daily/weekly/monthly/irregular)
- Minimum data requirements (3-5 runs)
- Daily Jobs integration and expected run detection
- Schedule accuracy scenarios
- Troubleshooting schedule issues
All pages include tables, callouts, cross-references, and practical examples.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added display: block to .doc-content img
- Changed margin from '20px 0' to '20px auto' for horizontal centering
- Images now centered like their figcaptions
- Applies to all documentation screenshots (user-management.png, user-settings.png)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Updated page description: only password change available in User Settings
- Added screenshot reference for user-settings.png
- Clarified theme selector location: navigation bar (between username and logout)
- Clarified role selector location: navigation bar (not in settings page)
- Simplified profile information: username and assigned roles (read-only)
- Removed non-existent Notification Preferences section
- Removed Session Information section (not displayed)
- Enhanced troubleshooting section with specific password change issues
- Maintained Data Privacy and Password sections
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added captcha requirement (simple math problem) to login steps
- Noted future plan to make captcha optional via system setting
- Clarified HTTPS context for browser security:
- Only relevant for external access via domain name
- Not applicable for internal IP-based deployments
- Marked Mozilla Firefox as recommended browser (most tested)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Created placeholder pages for all 30 documentation pages across 9 sections
- Fixed content errors in getting-started pages based on user feedback:
- Corrected review process (all jobs reviewed, not just successful)
- Changed Autotask tickets from automatic to manual creation
- Updated mail import from IMAP to Graph API
- Fixed job creation workflow (from Inbox via Approve job, not manual)
- Added Reparse all functionality explanation
- Corrected Daily Jobs vs Run Checks distinction
- Added manual import recommendation before enabling automatic
- Added role-based menu visibility explanation
- Added news items feature explanation
- All navigation links now work without Internal Server Errors
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Created documentation blueprint (doc_bp) with routes and navigation
- Added documentation menu item (📖) to navbar for all users
- Implemented hierarchical navigation with 9 sections, 33 pages
- Created base layout with sidebar, breadcrumb, and prev/next navigation
- Added documentation.css with dark mode support
- Created first 3 getting-started pages (what-is-backupchecks, first-login, quick-start)
- Updated changelog
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed the scheduling placeholder card from the main reports page as
scheduling will be configured per individual report instead of having
an overarching setting.
Changes:
- Removed entire scheduling placeholder card (delivery, frequency, recipients)
- Updated card header subtitle to reflect that scheduling is per-report
- Report definitions table now uses full page width
- Cleaner, more focused UI
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added explicit import for _log_admin_event function which is needed for
customer export/import audit logging. Functions with underscore prefix
are not automatically imported by 'from .routes_shared import *'.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit completes the audit logging expansion by adding comprehensive
logging for critical system operations:
- Settings: Log changes to General, Mail, and Autotask settings with
before/after values (passwords excluded for security)
- Exports: Log customer and jobs exports with format and record counts
- Imports: Log customer and jobs imports with operation statistics
Also updated UI to reflect "System Audit Log" nomenclature instead of
"Admin activity" for better semantic clarity.
All audit events use structured event_type identifiers and JSON details
for easy filtering and analysis.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The table name 'admin_logs' was misleading as it contains both admin actions
and automated system events. Renamed to 'audit_logs' to better reflect its
purpose as a comprehensive audit trail.
Changes:
- Renamed model: AdminLog → AuditLog (with backwards compatibility alias)
- Database migration: Renames admin_logs table to audit_logs (idempotent)
- Updated admin_logging.py: log_admin_event → log_audit_event (with alias)
- Updated imports in routes_core.py and routes_shared.py
- Updated all references to use AuditLog instead of AdminLog
- Backwards compatibility maintained via aliases for smooth transition
This is part 1 of audit logging expansion.
Part 2 will add logging for settings changes and export/import actions.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The filter now accepts both datetime objects and string representations.
This fixes AttributeError when datetime fields are stored/returned as
strings instead of datetime objects from the database.
Changes:
- Added string parsing logic for common datetime formats
- Tries multiple format patterns (ISO, standard, with/without microseconds)
- Returns original string if parsing fails (graceful degradation)
- Maintains full datetime object support
Fixes errors on:
- /customers (autotask_last_sync_at)
- /logging (created_at)
- /admin/all-mail (received_at, parsed_at)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extended both customer and jobs export/import to preserve Autotask
company mappings during data migration and system reset workflows.
Changes:
- Customer export (CSV): Added autotask_company_id and autotask_company_name columns
- Customer import (CSV): Reads and applies Autotask mapping fields, resets sync status
- Jobs export (JSON): Includes Autotask fields in customers array
- Jobs import (JSON): Processes customers array with Autotask mappings before jobs
- Backwards compatible: Old exports without Autotask fields continue to work
- Import feedback: Shows both created and updated customer counts
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Split Autotask settings into two separate forms with dedicated save
buttons and field validation:
1. Autotask Settings form:
- Save button inside card for better UX
- Required fields: Environment, Username, Password (if not set),
Tracking Identifier, Base URL
- Red asterisks indicate required fields
2. Ticket Defaults form:
- Separate save button inside card
- Required fields: Queue, Ticket Source, Status, Priority Warning,
Priority Error
- Prevents saving incomplete configurations
Benefits:
- Clear visual separation of concerns
- Prevents accidental saving of empty values
- HTML5 validation ensures all required fields are filled
- Better user experience with focused save actions
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enhanced save logic to protect against losing the default ticket
status value when saving settings with an empty dropdown:
- Only update to new value if a status is actually selected
- Only allow clearing if reference data is loaded (dropdown has options)
- Preserve existing value if dropdown is empty (no reference data)
This fixes the issue where saving settings before reference data
loaded would overwrite the previously configured default status
with NULL, causing "Create Autotask ticket" to fail with error
about missing default status.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed issue where Default Ticket Status dropdown was empty when
opening the settings page. Now automatically loads reference data
(queues, sources, statuses, priorities) when:
- Autotask integration is enabled
- API credentials are configured
- Reference data cache is empty
This eliminates the need to manually click "Refresh reference data"
before being able to select a default ticket status.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>