From fd0051cb297f0d06fcd4a07a87407216bc3d153b Mon Sep 17 00:00:00 2001 From: Ivo Oskamp Date: Tue, 13 Jan 2026 16:30:32 +0100 Subject: [PATCH 1/3] Auto-commit local changes before build (2026-01-13 16:30:32) --- .last-branch | 2 +- .../src/backend/app/job_matching.py | 49 +++++++++++++++++++ .../src/backend/app/parsers/veeam.py | 39 --------------- docs/changelog.md | 9 ++++ 4 files changed, 59 insertions(+), 40 deletions(-) diff --git a/.last-branch b/.last-branch index 96a874e..2da1383 100644 --- a/.last-branch +++ b/.last-branch @@ -1 +1 @@ -v20260113-08-vspc-object-linking +v20260113-08-vspc-object-linking-normalize diff --git a/containers/backupchecks/src/backend/app/job_matching.py b/containers/backupchecks/src/backend/app/job_matching.py index 496a718..6d95708 100644 --- a/containers/backupchecks/src/backend/app/job_matching.py +++ b/containers/backupchecks/src/backend/app/job_matching.py @@ -68,4 +68,53 @@ def find_matching_job(msg: MailMessage) -> Optional[Job]: if len(matches) == 1: return matches[0] + # Backwards-compatible matching for Veeam VSPC Active Alarms summary per-company jobs. + # Earlier versions could store company names with slightly different whitespace / HTML entities, + # while parsers store objects using a normalized company prefix. When the exact match fails, + # try a normalized company comparison so existing jobs continue to match. + try: + bsw = (backup or "").strip().lower() + bt = (btype or "").strip().lower() + jn = (job_name or "").strip() + if bsw == "veeam" and bt == "service provider console" and "|" in jn: + left, right = [p.strip() for p in jn.split("|", 1)] + if left.lower() == "active alarms summary" and right: + from .parsers.veeam import normalize_vspc_company_name # lazy import + + target_company = normalize_vspc_company_name(right) + if not target_company: + return None + + q2 = Job.query + if norm_from is None: + q2 = q2.filter(Job.from_address.is_(None)) + else: + q2 = q2.filter(Job.from_address == norm_from) + q2 = q2.filter(Job.backup_software == backup) + q2 = q2.filter(Job.backup_type == btype) + q2 = q2.filter(Job.job_name.ilike("Active alarms summary | %")) + + # Load a small set of candidates and compare the company portion. + candidates = q2.order_by(Job.updated_at.desc(), Job.id.desc()).limit(25).all() + normalized_matches: list[Job] = [] + for cand in candidates: + cand_name = (cand.job_name or "").strip() + if "|" not in cand_name: + continue + c_left, c_right = [p.strip() for p in cand_name.split("|", 1)] + if c_left.lower() != "active alarms summary" or not c_right: + continue + if normalize_vspc_company_name(c_right) == target_company: + normalized_matches.append(cand) + + if len(normalized_matches) > 1: + customer_ids = {m.customer_id for m in normalized_matches} + if len(customer_ids) == 1: + return normalized_matches[0] + return None + if len(normalized_matches) == 1: + return normalized_matches[0] + except Exception: + pass + return None diff --git a/containers/backupchecks/src/backend/app/parsers/veeam.py b/containers/backupchecks/src/backend/app/parsers/veeam.py index c3437b5..297220d 100644 --- a/containers/backupchecks/src/backend/app/parsers/veeam.py +++ b/containers/backupchecks/src/backend/app/parsers/veeam.py @@ -228,45 +228,6 @@ def _parse_vspc_active_alarms_from_html(html: str) -> Tuple[List[Dict], str, Opt return objects, overall_status, overall_message -def extract_vspc_active_alarms_companies(raw: str) -> List[str]: - """Extract company names with alarms > 0 from a VSPC Active Alarms summary body.""" - if not raw: - return [] - - txt = raw - if "<" in txt and ">" in txt: - txt = re.sub(r"<[^>]+>", " ", txt) - txt = _html.unescape(txt) - txt = txt.replace("\xa0", " ") - txt = re.sub(r"\s+", " ", txt).strip() - - seen: set[str] = set() - out: List[str] = [] - - for m in re.finditer( - r"\bCompany:\s*([^\(\r\n]+?)\s*\(\s*alarms?\s*:\s*(\d+)\s*\)", - txt, - flags=re.IGNORECASE, - ): - cname = (m.group(1) or "").strip() - cname = cname.replace("\xa0", " ") - cname = re.sub(r"\s+", " ", cname).strip() - try: - alarms = int(m.group(2)) - except Exception: - alarms = 0 - - if not cname or alarms <= 0: - continue - if cname in seen: - continue - seen.add(cname) - out.append(cname) - - return out - - - def _parse_cloud_connect_report_from_html(html: str) -> Tuple[List[Dict], str]: """Parse Veeam Cloud Connect daily report (provider) HTML. diff --git a/docs/changelog.md b/docs/changelog.md index 3f9c492..289bb54 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -62,6 +62,15 @@ - Uses case-insensitive matching for " | " mail objects. - Added best-effort retroactive processing after approving VSPC company mappings to automatically link older inbox messages that are now fully mapped. +--- + +## v20260113-08-vspc-object-linking-normalize + +- Fixed duplicate definition of the VSPC Active Alarms company extraction logic, which caused inconsistent company normalization. +- Ensured consistent company name normalization is used when creating per-company VSPC jobs and when linking objects to those jobs. +- Improved object linking for VSPC Active Alarms so real objects (e.g. HV01, USB Disk) are correctly associated with their jobs. +- Restored automatic re-linking of previously approved companies and objects for new and historical VSPC mails. +- Added backward-compatible matching to prevent existing VSPC jobs from breaking due to earlier inconsistent company naming. *** ## v0.1.20 -- 2.45.2 From beda8cc0f9b0406d6005fbcae0594309c4d2579f Mon Sep 17 00:00:00 2001 From: Ivo Oskamp Date: Tue, 13 Jan 2026 16:43:00 +0100 Subject: [PATCH 2/3] Auto-commit local changes before build (2026-01-13 16:43:00) --- docs/changelog.md | 102 +++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 289bb54..0ac4238 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,77 +1,75 @@ -## v20260113-01-changelog-markdown-render -- Updated the changelog route to render remote Markdown content with proper formatting. -- Enabled Markdown parsing so headings, lists, links, and code blocks are displayed as intended. -- Ensured the changelog always fetches the latest version from the source repository at request time. -- Removed plain-text rendering to prevent loss of Markdown structure. +*** ---- +## v0.1.21 -## v20260113-02-edge-mail-lightmode +This release focuses on improving correctness, consistency, and access control across core application workflows, with particular attention to changelog rendering, browser-specific mail readability, Run Checks visibility, role-based access restrictions, override flexibility, and VSPC object linking reliability. The goal is to ensure predictable behavior, clearer diagnostics, and safer administration across both day-to-day operations and complex multi-entity reports. -- Forced light color-scheme for embedded mail content to prevent Edge auto dark mode rendering. -- Added explicit color-scheme and forced-color-adjust rules so original mail CSS is respected. -- Ensured consistent mail readability across Edge and Firefox in Inbox, Deleted Inbox, Job Detail, Run Checks, Daily Jobs, and Admin All Mail views. +### Changelog Rendering and Documentation Accuracy ---- +- Updated the Changelog route to render remote Markdown content instead of plain text. +- Enabled full Markdown parsing so headings, lists, links, and code blocks are displayed correctly. +- Ensured the changelog always fetches the latest version directly from the source repository at request time. +- Removed legacy plain-text rendering to prevent loss of structure and formatting. -## v20260113-03-runchecks-overall-remark +### Mail Rendering and Browser Compatibility -- Added support to display the overall remark (overall_message) on the Run Checks page. -- Ensured consistency between the Run Checks view and the Job Details page where the overall remark was already available. +- Forced a light color scheme for embedded mail content to prevent Microsoft Edge from applying automatic dark mode styling. +- Added explicit `color-scheme` and `forced-color-adjust` rules so original mail CSS is respected. +- Ensured consistent mail readability across Edge and Firefox. +- Applied these fixes consistently across Inbox, Deleted Inbox, Job Details, Run Checks, Daily Jobs, and Admin All Mail views. ---- +### Run Checks Visibility and Consistency -## v20260113-04-edge-initial-setup-users-exist -- Fixed incorrect redirect to the “Initial admin setup” page when users already exist. -- Changed the setup check from “admin user exists” to “any user exists”, so existing environments always show the login page instead of allowing a new initial admin to be created. -- Prevented direct access to the initial setup route when at least one user is present (redirects to login). +- Added support for displaying the overall remark (overall_message) directly on the Run Checks page. +- Ensured consistency between Run Checks and Job Details, where the overall remark was already available. +- Improved operator visibility of high-level run context without requiring navigation to job details. ---- +### Initial Setup and User Existence Safeguards -## v20260113-05-reporter-menu-restrict +- Fixed an incorrect redirect to the “Initial admin setup” page when users already exist. +- Changed setup detection logic from “admin user exists” to “any user exists”. +- Ensured existing environments always show the login page instead of allowing a new initial admin to be created. +- Prevented direct access to the initial setup route when at least one user is present. + +### Role-Based Access Control and Menu Restrictions - Restricted the Reporter role to only access Dashboard, Reports, Changelog, and Feedback. -- Updated menu rendering to hide all unauthorized menu items for Reporter users. -- Adjusted route access to ensure Feedback pages are accessible for the Reporter role. +- Updated menu rendering to fully hide unauthorized menu items for Reporter users. +- Adjusted route access to ensure Feedback pages remain accessible for the Reporter role. +- Improved overall consistency between visible navigation and backend access rules. ---- +### Override Matching Flexibility and Maintainability -## v20260113-06-overrides-error-match-modes -- Added configurable error text matching modes for overrides: contains, exact, starts with, ends with -- Updated override evaluation logic to apply the selected match mode across run remarks and object error messages -- Extended overrides UI with a match type selector and improved edit support for existing overrides -- Added database migration to create and backfill overrides.match_error_mode for existing records +- Added configurable error text matching modes for overrides: contains, exact, starts with, and ends with. +- Updated override evaluation logic to apply the selected match mode across run remarks and object error messages. +- Extended the overrides UI with a match type selector and improved edit support for existing overrides. +- Added a database migration to create and backfill the `overrides.match_error_mode` field for existing records. ---- +### Job Deletion Stability -## v20260113-07-job-delete-fix +- Fixed an error that occurred during job deletion. +- Corrected backend deletion logic to prevent runtime exceptions. +- Ensured related records are handled safely to avoid constraint or reference errors during removal. -- Fixed an error that occurred when deleting a job. -- Corrected backend deletion logic to prevent exceptions during job removal. -- Ensured related records are handled safely to avoid constraint or reference errors. +### VSPC Object Linking and Normalization ---- +- Fixed VSPC company name normalization so detection and object prefixing behave consistently. +- Ensured filtered object persistence respects the UNIQUE(customer_id, object_name) constraint. +- Correctly update `last_seen` timestamps for existing objects. +- Added automatic object persistence routing for VSPC per-company runs, ensuring objects are linked to the correct customer and job. +- Improved auto-approval for VSPC Active Alarms summaries with per-company run creation and case-insensitive object matching. +- Added best-effort retroactive processing to automatically link older inbox messages once company mappings are approved. -## v20260113-08-vspc-object-linking -- Fixed VSPC company name normalization so company detection and object prefixing match consistently. -- Fixed filtered object persistence to respect UNIQUE(customer_id, object_name) and to update last_seen timestamps correctly. -- Added auto object persistence routing for VSPC per-company runs so objects are linked to the correct customer/job (prefix stripped). -- Improved auto-approval for VSPC Active Alarms summary: - - Creates per-company runs automatically when company jobs are mapped (new imports and inbox re-parse). - - Uses case-insensitive matching for " | " mail objects. -- Added best-effort retroactive processing after approving VSPC company mappings to automatically link older inbox messages that are now fully mapped. +### VSPC Normalization Bug Fixes and Backward Compatibility ---- - -## v20260113-08-vspc-object-linking-normalize - -- Fixed duplicate definition of the VSPC Active Alarms company extraction logic, which caused inconsistent company normalization. -- Ensured consistent company name normalization is used when creating per-company VSPC jobs and when linking objects to those jobs. -- Improved object linking for VSPC Active Alarms so real objects (e.g. HV01, USB Disk) are correctly associated with their jobs. -- Restored automatic re-linking of previously approved companies and objects for new and historical VSPC mails. +- Removed duplicate definitions of VSPC Active Alarms company extraction logic that caused inconsistent normalization. +- Ensured a single, consistent normalization path is used when creating jobs and linking objects. +- Improved object linking so real objects (e.g. HV01, USB Disk) are reliably associated with their jobs. +- Restored automatic re-linking for both new and historical VSPC mails. - Added backward-compatible matching to prevent existing VSPC jobs from breaking due to earlier inconsistent company naming. -*** + +--- ## v0.1.20 -- 2.45.2 From c57c58cc3df891339402fd70713abb295b315a3d Mon Sep 17 00:00:00 2001 From: Ivo Oskamp Date: Tue, 13 Jan 2026 16:43:25 +0100 Subject: [PATCH 3/3] Release v0.1.20 on branch v20260113-08-vspc-object-linking-normalize (bump type 1) --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 02dc6f6..c43cb2f 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v0.1.19 +v0.1.20 -- 2.45.2