Extended /api/job-runs/<run_id>/alerts endpoint to include both:
- Tickets explicitly linked to run via ticket_job_runs (audit trail)
- Tickets linked to job via ticket_scopes (active on run date)
Previously only ticket_job_runs was queried, causing newly created
tickets to not appear in the Meldingen section of the Run Checks modal.
They would only appear after being resolved (which creates a
ticket_job_runs entry). Now both sources are queried and duplicates
are prevented.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added ready-to-send email template for requesting expanded API access:
- Complete email with subject line
- Detailed explanation of current limitations
- Specific requests (MSP-level access, status fields, timestamps, errors)
- Technical details and test results reference
- Professional business justification (MSP use case)
- Alternative contact methods listed
User can copy-paste this email on Thursday to contact N-able support.
Template requests:
1. MSP-level API user creation
2. Access to restricted column codes (status, timestamps, errors)
3. Documentation of column code meanings
4. Alternative integration methods if API expansion not possible
Ready for action on Thursday.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added comprehensive API test results document (with ChatGPT assistance):
- docs/cove_data_protection_api_calls_known_info.md
Key findings from live API testing:
- API works: JSON-RPC 2.0 at https://api.backup.management/jsonapi
- Authentication: Login method → visa token
- Method tested: EnumerateAccountStatistics (limited success)
CRITICAL LIMITATIONS DISCOVERED:
- Security error 13501 blocks most useful columns
- No backup status fields (success/failed/warning) accessible
- No error messages (D02Fxx/D03Fxx ranges blocked)
- No reliable backup timestamps
- No detailed run history
- API users are customer-scoped (not MSP-level)
- EnumerateAccounts method always fails (security block)
Working columns (allow-list only):
- I1 (account ID), I14 (storage bytes), I18 (hostname)
- D01F00-D01F07, D09F00 (numeric metrics, semantics unclear)
Impact on Backupchecks:
- Current API access INSUFFICIENT for backup monitoring
- Cannot determine if backups succeeded or failed
- No error messages to show users
- Core Backupchecks functionality not achievable with current API
Added decision matrix with 4 options:
A. Implement metrics-only (low value, storage usage only)
B. Request expanded access from N-able (requires vendor cooperation)
C. Explore alternative methods (webhooks, reports, email)
D. Defer integration until better API access available
Recommendation: Option B or C before implementing anything
- Contact N-able support for MSP-level API user + expanded columns
- OR investigate if Cove has webhook/reporting alternatives
This represents a significant blocker for Cove integration.
Full integration requires either vendor cooperation or alternative approach.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Major discovery - found comprehensive JSON API documentation on N-able site!
Added documentation sections:
- Core API docs: login, authentication, construct API calls
- Key endpoints: enumerate-customers, enumerate-devices, enumerate-device-statistics
- Reference docs: API column codes, schema documentation
- Architecture and security guides
Key findings:
- API docs located in "unused" folder but still functional
- JSON API structure (likely JSON-RPC or custom format)
- Three critical endpoints identified for backup monitoring:
1. enumerate-customers (list all customers)
2. enumerate-devices (list backup devices)
3. enumerate-device-statistics (backup job results - KEY ENDPOINT!)
Updated status:
- Marked API documentation as found
- Changed next action from "find docs" to "read auth docs and test"
- Updated Phase 1 to start with reading login/auth documentation
Next steps:
1. Read login.htm to understand token authentication
2. Read construct-a-call.htm to understand request format
3. Read enumerate-device-statistics.htm - likely contains backup status data
4. Test in Postman with documented format
Documentation base URL:
https://documentation.n-able.com/covedataprotection/USERGUIDE/documentation/Content/unused/service-management/json-api/
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replaced curl examples with detailed Postman testing guide:
- Step-by-step Postman setup instructions
- Two authentication methods to test (Bearer Token vs X-API-Key)
- Multiple base URLs to try (api.backup.management, backup.management)
- Expected response codes and what they mean (200, 401, 403, 404)
- Endpoint discovery list (accounts, customers, devices, jobs)
- Tips for finding API documentation
Added Postman best practices:
- Create Cove API collection
- Use environment variables (cove_token, cove_base_url)
- Save response examples
- Check rate limit headers
- Export collection to JSON
Added structured template for documenting test results:
- Working configuration (base URL, auth method)
- Available endpoints table
- Key response fields mapping to Backupchecks
- Pagination and rate limiting details
- Location to save Postman collection export
Ready for immediate API testing with Postman!
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Major progress update:
- API user successfully created in Cove portal
- Credentials: SuperUser role, top-level customer access, token generated
- Portal URL identified: https://backup.management
- API user management: https://backup.management/#/api-users
Added comprehensive testing section:
- Likely API base URLs to test (api.backup.management, backup.management/api)
- Step-by-step Phase 1 testing instructions
- Multiple curl command examples for authentication testing
- Different auth header formats to try (Bearer, X-API-Key)
- Common endpoints to discover (accounts, customers, devices)
- POC Python script template
Next steps:
1. Test API authentication with curl commands
2. Find working API base URL and auth method
3. Discover available endpoints
4. Document API response format
5. Create POC script for data retrieval
Status: Ready for immediate API testing!
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added critical information from user:
- Confirmed: Cove Data Protection HAS API access (documented)
- Problem: Location/method to enable API access is unknown
Changes:
- Added Phase 0: API Access Activation (critical first step)
- Marked API availability as confirmed
- Added checklist for finding API activation in admin portal
- Listed possible admin portal locations to check
- Added support channel suggestions if activation unclear
- Updated current status section with latest info
Next action: Investigate Cove admin portal or contact support for
API activation instructions.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed TODO document language from Dutch to English to align with
project documentation standards (all code and docs in English).
No content changes, only translation.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Created comprehensive TODO document for integrating Cove Data Protection
(formerly N-able Backup) into Backupchecks.
Key challenges:
- Cove does not use email notifications like other backup systems
- Need to research API availability and authentication methods
- Must determine optimal integration strategy (polling vs webhooks)
Document includes:
- Research questions (API availability, data structure, multi-tenancy)
- Three architecture options for integration
- Implementation phases (research, database, import, scheduling, UI)
- Success criteria and open questions
- References section for documentation links
Status: Research phase - waiting on API documentation investigation
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes:
- Added copy ticket button (⧉) next to ticket numbers in Job Details modal
- Implemented robust cross-browser clipboard copy mechanism:
1. Modern navigator.clipboard API (works in HTTPS contexts)
2. Legacy document.execCommand('copy') fallback (works in older browsers)
3. Prompt fallback as last resort
- Applied improved copy function to both Run Checks and Job Details pages
- Copy now works directly in all browsers (Firefox, Edge, Chrome) without popup
This eliminates the manual copy step in Edge that previously required a popup.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
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>
Release v0.1.26 - Ticket system bug fixes
This release resolves critical ticket system display issues where
resolved tickets were incorrectly appearing on new runs across
multiple pages.
Key changes:
- Fixed ticket propagation logic (4 locations)
- Transitioned from date-based to link-based queries
- Fixed Run Checks popup showing resolved tickets
- Updated Settings Maintenance UI text
- Test email generation reduced to 1 per button
Total commits: 10
Branch: v20260210-01-autotask-ticket-propagation-fix
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 previous changelog entry lacked context about why debug logging
was added and what it did. Future readers need this information.
Changes:
- Restored full debug logging description in Changed section
- Marked as "LATER REMOVED" for clarity
- Expanded Removed section with full context about purpose
- Now clear: logging was temporary troubleshooting tool
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>