Wait for more runs to be imported, then schedule inference will update automatically
+
Cove Workstations Don't Show "Missed"
+
+
+
+ Cove Data Protection workstation jobs are intentionally excluded from
+ schedule-based missed-run detection. PCs are commonly powered off outside business hours,
+ which produced false-positive Missed alerts; they no longer appear here for those jobs.
+
+
+ Cove Server and Microsoft 365 jobs continue to use the regular
+ schedule-based missed-run logic.
+
diff --git a/containers/backupchecks/src/templates/documentation/backup-review/overrides.html b/containers/backupchecks/src/templates/documentation/backup-review/overrides.html
index 01044f4..aeb28f6 100644
--- a/containers/backupchecks/src/templates/documentation/backup-review/overrides.html
+++ b/containers/backupchecks/src/templates/documentation/backup-review/overrides.html
@@ -159,7 +159,28 @@
When you create an override without a start date, it is applied retroactively to existing unreviewed runs. This means jobs that match the override will immediately show the "Treat as success" status in Daily Jobs, even if they ran before the override was created.
-
Creating an Override
+
Creating Overrides Directly From Run Checks
+
+
The fastest way to create an override is from the run you are reviewing. After clicking
+ Mark as Success in the Run Checks modal, a follow-up dialog
+ "Apply override for future runs?" appears with:
+
+
+
Scope:
+
+
Only this run — no override is created.
+
This job, same error message — creates a job-scoped override.
+
All jobs with same software/type and error — creates a global override.
+
+
+
Duration: 1 week, 1 month, or permanent (until manually disabled).
+
The error text from the run's problem objects is pre-filled, ready to be trimmed.
+
+
+
Broader overrides created this way are audit-logged with their scope, duration, and source
+ run. This path covers most day-to-day use cases without ever opening the Overrides page.
+
+
Creating an Override (Overrides Page)
To create a new override:
diff --git a/containers/backupchecks/src/templates/documentation/backup-review/run-checks-modal.html b/containers/backupchecks/src/templates/documentation/backup-review/run-checks-modal.html
index b3815e3..942eca0 100644
--- a/containers/backupchecks/src/templates/documentation/backup-review/run-checks-modal.html
+++ b/containers/backupchecks/src/templates/documentation/backup-review/run-checks-modal.html
@@ -132,9 +132,34 @@
Backup objects are only shown if the parser extracted them from the email. Not all backup software emails include object-level details. If no objects are shown, the parser didn't detect individual items in the email.
+
Cove / Cloud Connect Summary Panels
+
+
For runs imported via the Cove API or Veeam Cloud Connect (no source email), the modal hides
+ the email section and shows a structured summary panel instead:
+
+
+
Cove summary: account name, computer, customer, active datasources, last
+ session timestamp and status. Per-datasource objects appear in the Backup Objects table.
+
Cloud Connect summary: tenant, repository, used / quota / free storage and
+ a link to the source provider report.
+ 💡 Cove same-day suppression:
+ For Cove jobs, once the first complete success run on a given local day is recorded
+ (status Success with all object statuses Success), all newer Cove
+ runs on that same day are hidden from Run Checks — regardless of status. This prevents
+ duplicate review of the same day's backup activity.
+
+
Email Content
-
The original email body from the backup software is displayed in an embedded iframe:
+
For email-imported runs, the original email body from the backup software is displayed in
+ an embedded iframe:
HTML emails are rendered with their original formatting
@@ -187,6 +212,36 @@
All runs for this job are immediately marked as reviewed and the job disappears from the Run Checks page
+
Mark as Success (with optional override)
+
+
For warning or failed runs that should be treated as successful, use Mark as Success:
+
+
+
Open the run details and click Mark as Success.
+
The run is recorded as success-by-override and removed from the unreviewed list.
+
A follow-up dialog asks "Apply override for future runs?" with two choices that
+ persist beyond this single run:
+
+
Only this run (default — no future override is created).
+
This job, same error message — creates a job-scoped override that
+ treats future occurrences with the same error text as success.
+
All jobs with same software/type and error — creates a global override
+ across the same backup software/type combination.
+
+
+
Choose a duration: 1 week, 1 month, or permanent (until manually disabled).
+
The error text is pre-filled from the run's problem objects so you can review and trim it
+ before saving.
+
+
+
+ 💡 When to use which scope:
+ Use "Only this run" for one-off events, "This job" for issues specific to a single environment
+ (e.g. a particular VM that always warns), and "All jobs" for known cosmetic warnings from a
+ backup product that recur across many customers. Broader overrides are audit-logged with
+ scope, duration, and source run details.
+
+
Mark as Reviewed (Bulk)
For efficiency, especially with successful backups:
diff --git a/containers/backupchecks/src/templates/documentation/customers-jobs/job-schedules.html b/containers/backupchecks/src/templates/documentation/customers-jobs/job-schedules.html
index 8e0ac1f..2b73745 100644
--- a/containers/backupchecks/src/templates/documentation/customers-jobs/job-schedules.html
+++ b/containers/backupchecks/src/templates/documentation/customers-jobs/job-schedules.html
@@ -140,6 +140,23 @@
New jobs without learned schedules will not appear on Daily Jobs until a pattern is established.
+
Cove Workstations: Missed-Run Detection Disabled
+
+
+ Schedule-based missed-run detection (synthetic Missed rows for past slots
+ without a real run) is not applied to Cove Data Protection workstation jobs.
+ Workstation devices are routinely powered off outside business hours, which produced
+ false-positive Missed alerts. Cove Server and Microsoft 365 jobs continue
+ to use the regular missed-run logic.
+
+
+
+ For workstation inactivity, enable colorbar-based offline detection in
+ Settings → Integrations → Cove. See
+ Cove Data Protection
+ for details.
+
+
Schedule Accuracy
Schedule learning is based on pattern recognition and may not be 100% accurate in all cases:
diff --git a/containers/backupchecks/src/templates/documentation/getting-started/what-is-backupchecks.html b/containers/backupchecks/src/templates/documentation/getting-started/what-is-backupchecks.html
index 01de937..69f30c2 100644
--- a/containers/backupchecks/src/templates/documentation/getting-started/what-is-backupchecks.html
+++ b/containers/backupchecks/src/templates/documentation/getting-started/what-is-backupchecks.html
@@ -8,15 +8,11 @@
verify that backups are running successfully across their customer infrastructure.
-
- 📝 Coming Soon:
- This page is under construction. Screenshots and additional content will be added in future updates.
-
-
Key Features
Automated Mail Parsing: Import backup reports via email and automatically parse results
+
API Integrations: Direct API import for Cove Data Protection (N-able) and Veeam Cloud Connect — no email needed
Review Workflow: Review all backup jobs daily and mark them as reviewed (goal: clear the Run Checks queue)
Customer Management: Organize backups by customer and manage multiple backup jobs per customer
Autotask Integration: Manually create tickets in Autotask PSA for failed backups requiring follow-up
@@ -24,11 +20,6 @@
Role-Based Access: Admin, Operator, Reporter, and Viewer roles
-
- 💡 Note:
- Screenshots will be added in a future update to illustrate the dashboard and key features.
-
Cove runs are stored as API runs (source_type = cove_api).
-
Cove run details are visible in Job Detail and Run Checks with a Cove summary panel.
+
Cove run details are visible in Job Detail and Run Checks with a Cove summary panel (no mail section is shown for Cove runs).
No mail message is required for Cove runs.
Historical backfill can create runs from Cove 28-day colorbar data.
+
+ Same-day duplicate suppression: once the first complete success
+ run for a Cove job/day is recorded (status Success with at least one persisted
+ object and all object statuses equal to Success), all newer Cove runs on that
+ same local day are hidden in Run Checks — regardless of whether they are
+ Success, Warning, or Failed/Error. Sort order in the modal
+ stays newest → oldest.
+
+
Workstation Offline Handling
+
+
+ Cove workstation devices are commonly powered off outside business hours, which used to
+ produce false-positive missed-run alerts. Two mechanisms reduce this noise:
+
+
+
Schedule-based missed runs are skipped (always on)
+
+
+ For jobs with backup_software = "Cove Data Protection" and
+ backup_type = "Workstation", the missed-run generator is disabled.
+ No synthetic Missed rows are created when a workstation is off during a
+ scheduled slot.
+
+
+ Cove Server and Microsoft 365 jobs keep the regular schedule-based
+ missed-run logic.
+
+
+ Real Cove statuses (Failed, Warning, Not started)
+ continue to surface via the normal import flow, so genuine problems still get reported.
+
Enable colorbar-based offline detection — off by default.
+
Warning after N inactive days — default 7 (range 1–28).
+
Error after N inactive days — default 14 (range 1–28).
+
+
+ When enabled, every Cove import cycle checks each linked workstation's 28-day colorbar
+ (D09F08) and counts the consecutive trailing days with status 0
+ (no backup activity). If the streak crosses the warning or error threshold, a single synthetic
+ JobRun is upserted for that account so the alert appears in Run Checks. The same
+ row is reused across cycles, so it escalates Warning → Error in place and is removed
+ automatically once activity resumes. Runs that have already been reviewed in Run Checks are
+ never mutated or removed, so acknowledged alerts do not reappear.
+
+
Troubleshooting
diff --git a/containers/backupchecks/src/templates/documentation/mail-import/inbox-management.html b/containers/backupchecks/src/templates/documentation/mail-import/inbox-management.html
index de3138f..4a0b426 100644
--- a/containers/backupchecks/src/templates/documentation/mail-import/inbox-management.html
+++ b/containers/backupchecks/src/templates/documentation/mail-import/inbox-management.html
@@ -40,6 +40,25 @@
Once you approve an email, it immediately disappears from the inbox and the job appears in operational views (Jobs, Daily Jobs, Run Checks). The inbox only contains emails awaiting approval or deletion.
+
+ 💡 Archived jobs are filtered out:
+ Mail messages whose linked job has been archived are hidden from the inbox.
+ Messages without a linked job remain visible. To process emails for an archived job, unarchive
+ the job first in Jobs.
+
+
+
+ 💡 Parallel inboxes for API integrations:
+ This Inbox handles email-imported reports. API-based integrations have their own staging
+ pages with the same approve-and-link flow:
+
+
Cove Accounts — Cove Data Protection accounts awaiting link to a job
+ (see Cove Data Protection).
+
Cloud Connect Accounts — Veeam Cloud Connect tenants awaiting link
+ (see Veeam Cloud Connect).
Delete orphaned: removes orphaned jobs and related run/email data.
+
Generate Test Run
+
+
Creates a single JobRun with three persisted run objects, attached to a fixed
+ test job (__test-override-job__) and customer that are auto-created on first use.
+ Designed for exercising the Smart Override flow in Run Checks without needing a live backup.
+
+
+
Choose a status: Success, Warning, or Failed.
+
Choose an error scenario: VSS, connection timeout, disk space, license,
+ network, permissions, or a custom free-text message.
+
Delete all test runs removes all generated test data (runs and objects).
+
+
Generate Test Emails
-
Generates one Veeam test email per selected status: Success, Warning, or Error.
-
Useful for parser testing and maintenance validation.
+
Generates one Veeam test email in the inbox per selected status: Success, Warning, or Error.
+
Useful for parser testing and inbox-flow validation.
Jobs Maintenance
diff --git a/containers/backupchecks/src/templates/documentation/users/login-authentication.html b/containers/backupchecks/src/templates/documentation/users/login-authentication.html
index a421292..b54dbb8 100644
--- a/containers/backupchecks/src/templates/documentation/users/login-authentication.html
+++ b/containers/backupchecks/src/templates/documentation/users/login-authentication.html
@@ -7,14 +7,9 @@
Learn how to log in to BackupChecks and manage your authentication session.
-
- 📝 Coming Soon:
- This page is under construction. Screenshots will be added in a future update.
-
-
Logging In
-
BackupChecks uses a traditional username and password authentication system.
+
BackupChecks supports local username/password authentication and, optionally, Microsoft Entra (Azure AD) Single Sign-On.
Login Steps
@@ -23,15 +18,17 @@
You will be automatically redirected to the login page if not authenticated
Enter your username in the username field
Enter your password in the password field
-
Complete the captcha by solving the simple math problem (e.g., "3 + 5 = ?")
+
If the login captcha is enabled, solve the simple math problem (e.g., "3 + 5 = ?")
Click the Login button
-
If your credentials are correct and the captcha is solved, you will be redirected to the dashboard.
+
If your credentials are correct (and the captcha, if shown, is solved), you will be redirected to the dashboard.
- 📝 Future Change:
- The captcha requirement is planned to become optional via a system setting. Since BackupChecks is typically deployed in restricted local environments, the captcha may be disabled to streamline the login process.
+ 💡 Captcha is configurable:
+ The login captcha is controlled by the login_captcha_enabled setting in
+ Settings → General. It is enabled by default; administrators can disable it
+ for restricted internal deployments where the extra step is unnecessary.
First Login
@@ -50,17 +47,24 @@
Bookmark the BackupChecks URL for quick access. The system will remember your last active role between sessions.
-
Authentication Method
+
Authentication Methods
-
BackupChecks uses local database authentication:
+
BackupChecks supports the following authentication methods:
-
Username/Password: Credentials are stored securely in the database
+
Local Username/Password: Credentials are stored hashed in the database
+
Microsoft Entra SSO (OAuth/OIDC): Optional Single Sign-On via Microsoft Entra (Azure AD), configurable in Settings → Integrations → Entra SSO. See Entra SSO setup.
Session-Based: After login, a secure session is created and stored in a cookie
-
No SSO/OAuth: External authentication providers are not currently supported
No Two-Factor Authentication: 2FA is not currently implemented
+
+ ⚠️ Entra SSO is implemented but not yet validated in production:
+ The integration is wired up end-to-end (login flow, token exchange, optional auto-provisioning,
+ group filtering) but has not been tested against a live tenant in our deployment. Treat it as a
+ preview feature until verified. Local username/password remains the recommended login method.
+
+
💡 Note:
User accounts are created and managed by administrators via Settings → User Management.
diff --git a/containers/backupchecks/src/templates/main/run_checks.html b/containers/backupchecks/src/templates/main/run_checks.html
index 8788667..b40177c 100644
--- a/containers/backupchecks/src/templates/main/run_checks.html
+++ b/containers/backupchecks/src/templates/main/run_checks.html
@@ -440,6 +440,7 @@
@@ -447,6 +448,77 @@
+ Cove workstations are often powered off outside business hours, which causes
+ false-positive missed-run alerts. Schedule-based missed-run detection is
+ always disabled for Cove workstations. With this option enabled, a separate
+ check uses the 28-day Cove colorbar to flag a job only when the workstation
+ has truly been inactive for several days.
+
+
+
+
+
+
+
+
+
+
+
+
Consecutive days without a successful backup before a Warning is raised.
+
+
+
+
+
Consecutive days without a successful backup before an Error is raised.
+
+
+
@@ -750,26 +783,10 @@
-
-
-
Generate test emails
-
-
Generate Veeam test emails in the inbox for testing parsers and maintenance operations. Each button creates 1 Veeam Backup Job email with the specified status.
-
-
-
-
-
-
-
-
+
+
+
Jobs maintenance
@@ -805,6 +822,74 @@
+{% endif %}
+
+{% if section == 'testing' %}
+
+
+
Generate test run
+
+
Generate a single test run with objects for testing the Smart Override flow in Run Checks. Each click creates one run for a fixed test job (__test-override-job__).
+
+
+
+
+
+
+
+
Generate test emails
+
+
Generate Veeam test emails in the inbox for testing parsers and inbox flow. Each button creates 1 Veeam Backup Job email with the specified status.
+
+
+
+
+
+
+
+
{% endif %}
{% if section == 'general' %}
@@ -1083,4 +1168,31 @@
{% endif %}
+
+
{% endblock %}
diff --git a/docs/technical-notes-codex.md b/docs/TECHNICAL.md
similarity index 89%
rename from docs/technical-notes-codex.md
rename to docs/TECHNICAL.md
index d639d1d..e2be107 100644
--- a/docs/technical-notes-codex.md
+++ b/docs/TECHNICAL.md
@@ -1,6 +1,6 @@
# Technical Notes (Internal)
-Last updated: 2026-03-23
+Last updated: 2026-04-16
## Purpose
Internal technical snapshot of the `backupchecks` repository for faster onboarding, troubleshooting, and change impact analysis.
@@ -337,9 +337,63 @@ Cove run rows in the job detail history table are clickable even without a mail
- Once the first complete success exists on that day, all newer Cove runs for the same day are hidden in Run Checks (overview aggregation + details modal), regardless of status (`Success`, `Warning`, `Failed/Error`).
- Sort order in the modal remains unchanged (`newest -> oldest`).
+### Workstation Offline Handling (added 2026-05-01)
+Two layered behaviours reduce false-positive alerts for PCs that are routinely powered off:
+
+1. **Schedule-based missed-run skip (always on)** — `_ensure_missed_runs_for_job` in `routes_run_checks.py` early-returns for Cove + Workstation jobs. Servers and Microsoft 365 keep the existing missed-run generation. Real Cove statuses (Failed/Warning/Not started) continue to surface through the normal import path.
+2. **Colorbar-based offline detection (toggle in Settings → Integrations → Cove)** — when `cove_offline_detection_enabled = True`, `cove_importer._apply_offline_detection_for_workstations(settings)` runs once per import cycle. For every linked Cove workstation job it parses `cove_acc.colorbar_28d`, counts the trailing streak of `0` codes (no backup that day), and:
+ - `streak >= cove_workstation_error_days` → upsert synthetic `JobRun` with `status = "Error"`.
+ - `streak >= cove_workstation_warning_days` (and below error) → `status = "Warning"`.
+ - Otherwise → drop any existing unreviewed offline run for the job.
+
+ The synthetic run uses a **stable external_id** `cove-offline-{account_id}` so it escalates in place (Warning → Error) and is removed when activity resumes. Reviewed runs (`reviewed_at IS NOT NULL`) are never mutated or deleted, so previously acknowledged alerts do not reappear.
+
### Migrations
- `migrate_cove_integration()` — adds 8 columns to `system_settings`, `cove_account_id` to `jobs`, `source_type` + `external_id` to `job_runs`, dedup index on `job_runs.external_id`
- `migrate_cove_accounts_table()` — creates `cove_accounts` table with indexes
+- `migrate_cove_offline_detection()` — adds `cove_offline_detection_enabled`, `cove_workstation_warning_days`, `cove_workstation_error_days` to `system_settings`
+
+---
+
+## Override System
+
+### Overview
+Overrides allow operators to mark specific backup runs (or patterns of runs) as success, suppressing repeated alerts for known non-critical issues. The system operates at two levels: **object-level** (scoped to a specific job) and **global** (scoped to backup software/type).
+
+### Override Model (`overrides` table)
+- `level`: `"global"` or `"object"`
+- `backup_software`, `backup_type`: scope for global overrides (nullable)
+- `job_id`, `object_name`: scope for object overrides (nullable)
+- `match_status`, `match_error_contains`, `match_error_mode`: matching criteria (`contains`/`exact`/`starts_with`/`ends_with`)
+- `treat_as_success`, `active`: behavior flags
+- `start_at`, `end_at`: validity window (`end_at=NULL` for permanent overrides)
+- `comment`, `created_by`, `updated_by`: audit metadata
+
+### Override Evaluation (`_apply_overrides_to_run` in `routes_shared.py`)
+- Called per run to determine display status
+- Object-level overrides take precedence over global overrides
+- Uses wildcard matching (fnmatch) for `object_name`, configurable text matching for errors
+- Returns 5-tuple: `(display_status, override_applied, override_level, override_id, override_reason)`
+- `_recompute_override_flags_for_runs()` batch-updates `JobRun.override_applied` flag after override changes
+
+### Smart Overrides — Phase 1 (2026-04-16)
+"Mark as Success" in Run Checks now offers a follow-up dialog to create broader overrides for recurring issues.
+
+**API** (`POST /api/run-checks/mark-success-override`):
+- `scope` parameter: `"run"` (default, ±1 min window), `"job"` (object-level on job_id + error match), `"global"` (software + type + error match)
+- `duration` parameter: `"once"` (±1 min), `"1w"`, `"1m"`, `"permanent"` (end_at=NULL)
+- `error_text` parameter: pre-filled from problem objects, can be adjusted by operator
+- `comment` parameter: optional operator note
+- For `scope=run`: returns `run_info` object with error_text and job metadata so frontend can populate the follow-up dialog
+- For `scope=job/global`: creates the broader override and audit-logs it with `event_type=override_from_review`
+
+**Frontend flow** (`run_checks.html`):
+1. Operator clicks "Mark as Success" → scope=run override created → follow-up modal appears
+2. Modal shows scope choice (run/job/global), duration choice (1w/1m/permanent), error text preview
+3. If operator chooses a broader scope → second API call creates the additional override
+4. If operator dismisses → page reloads to reflect the initial run-level override
+
+**No database migrations required** — all fields already exist on the Override model.
---
@@ -735,6 +789,20 @@ File: `build-and-push.sh`
## Recent Changes
+### 2026-04-16
+- **Smart Overrides Phase 1** (`main/routes_run_checks.py`, `run_checks.html`):
+ - Extended `mark-success-override` API with `scope` (run/job/global) and `duration` (once/1w/1m/permanent) parameters.
+ - Added follow-up dialog modal in Run Checks for creating broader overrides after "Mark as Success".
+ - Broader overrides (job/global) are audit-logged with `event_type=override_from_review`.
+ - Restored "Mark as Success" button in Run Checks modal footer.
+ - Extracted helper functions: `_get_run_error_text()`, `_fetch_problem_objects()`, `_obj_is_problem()`, `_duration_to_end_at()`.
+- **Test run generator** (`main/routes_settings.py`, `settings.html`):
+ - `POST /settings/test-run/generate`: creates a single `JobRun` with 3 objects in `run_object_links` for a fixed test job (`__test-override-job__` under `__Test Customer__`). Operator chooses status (success/warning/failed) and error scenario (VSS, connection timeout, disk space, license, network, permissions, or custom text).
+ - `POST /settings/test-run/cleanup`: deletes all runs and `customer_objects` for the test job.
+ - New card on Settings → Maintenance with status radio buttons, error scenario dropdown, and cleanup button.
+- **Bug fix: inactive customer filter** (`main/routes_run_checks.py`, `main/routes_search.py`):
+ - Run Checks overview query was missing `Customer.active` filter — jobs for inactive customers were still shown. Added to both the overview aggregation query and the Search page Run Checks section.
+
### 2026-04-13
- **Run Checks Cove daily suppression** (`main/routes_run_checks.py`):
- Added Cove-specific filtering to suppress repeated same-day runs after the first complete success run.
diff --git a/docs/changelog-claude.md b/docs/changelog-develop.md
similarity index 92%
rename from docs/changelog-claude.md
rename to docs/changelog-develop.md
index ed41e22..367e3da 100644
--- a/docs/changelog-claude.md
+++ b/docs/changelog-develop.md
@@ -1,6 +1,61 @@
-# Changelog - Claude Code
+# Changelog - Develop
-This file documents all changes made to this project via Claude Code.
+This file is the long-form append-only development log. It captures every change in detail and is summarised into `docs/changelog.md` at release time. Release markers (`## YYYY-MM-DD — Released as vX.Y.Z`) indicate which entries are already published.
+
+## 2026-05-01 — Released as v0.3.0
+
+## [2026-05-01]
+
+### Documentation
+- In-app documentation refresh after several months without updates:
+ - **`integrations/cove-data-protection.html`**: added "Workstation Offline Handling" section covering the schedule-missed exclusion (always-on) and the new colorbar-based offline detection toggle with warning/error day thresholds. Same-day duplicate-suppression behaviour now documented.
+ - **`backup-review/daily-jobs.html`** and **`customers-jobs/job-schedules.html`**: noted that Cove workstation jobs are excluded from schedule-based missed-run detection.
+ - **`backup-review/run-checks-modal.html`**: documented the Cove and Cloud Connect summary panels shown for API-imported runs (mail section is hidden), Cove same-day suppression, and the Smart Overrides Phase 1 "Apply override for future runs?" follow-up dialog after Mark as Success (scope + duration choices).
+ - **`backup-review/overrides.html`**: added "Creating Overrides Directly From Run Checks" section.
+ - **`mail-import/inbox-management.html`**: noted that messages linked to archived jobs are now hidden from the inbox; cross-linked Cove Accounts and Cloud Connect Accounts staging pages.
+ - **`getting-started/what-is-backupchecks.html`**: removed stale "Coming Soon" callouts; expanded supported-software table to reflect actual parsers (Veeam, Veeam Cloud Connect, Cove API, NAKIVO, Synology, QNAP, Syncovery, BoxAfe, R-Drive, 3CX, NTFS Auditing) and architecture overview now lists Cove + Cloud Connect components.
+ - **`users/login-authentication.html`**: removed "No SSO/OAuth" claim; added Microsoft Entra SSO as an authentication method with an explicit "implemented but not yet validated in production" caveat. Captcha section corrected to reflect the existing `login_captcha_enabled` setting.
+ - **`settings/maintenance.html`**: added "Generate Test Run" subsection (test job auto-creation, status + scenario choices, "Delete all test runs" action).
+ - **`autotask/setup-configuration.html`**: aligned terminology with the Settings page (`Backupchecks Base URL`).
+
+### Changed
+- Cove workstation jobs no longer receive schedule-based "Missed" runs. Workstations are commonly powered off outside business hours; the synthetic missed-run generator (`_ensure_missed_runs_for_job` in `routes_run_checks.py`) now early-returns for jobs where `backup_software == "Cove Data Protection"` and `backup_type == "Workstation"`. Servers and Microsoft 365 Cove jobs remain unaffected. Real Cove statuses (Failed / Warning / Not started) still surface via the normal import flow.
+
+### Added
+- Cove workstation **offline detection** based on the 28-day colorbar (`D09F08`), configurable in Settings → Integrations → Cove:
+ - **Enable colorbar-based offline detection** (off by default).
+ - **Warning after N inactive days** (default 7, range 1–28).
+ - **Error after N inactive days** (default 14, range 1–28).
+ - When enabled, `cove_importer.run_cove_import` runs `_apply_offline_detection_for_workstations` once per cycle. For each linked Cove workstation job it counts the consecutive trailing colorbar days with status `0` (no backup). When the streak crosses the warning/error threshold, a synthetic `JobRun` is upserted with stable `external_id = "cove-offline-{account_id}"` (so the same row escalates Warning → Error and is removed once activity resumes). Reviewed runs are never mutated, so acknowledged offline alerts do not reappear.
+- New `system_settings` columns: `cove_offline_detection_enabled` (bool), `cove_workstation_warning_days` (int), `cove_workstation_error_days` (int) — added by `migrate_cove_offline_detection()`.
+
+## [2026-04-24]
+
+### Fixed
+- Inbox no longer lists mail messages linked to archived jobs. The inbox query now excludes messages whose `job_id` points to a job with `archived=True` (messages without a linked job remain visible).
+
+## [2026-04-16]
+
+### Added
+- Smart Overrides Phase 1: "Apply override for future runs?" follow-up dialog after Mark as Success in Run Checks:
+ - After marking a run as success, a follow-up dialog offers to create a broader override for future occurrences of the same error.
+ - **Scope options**: "Only this run" (default, existing behavior), "This job, same error message" (object-level override), "All jobs with same software/type and error" (global override).
+ - **Duration options**: 1 week, 1 month, or permanent (until manually disabled).
+ - Error text is pre-filled from the run's problem objects and shown in the dialog for operator review.
+ - Broader overrides (job/global scope) are audit-logged with `event_type=override_from_review` including scope, duration, and source run details.
+ - No database migrations required — uses existing Override model fields (`level`, `match_error_contains`, `start_at`, `end_at`).
+- Restored "Mark as Success" button in Run Checks modal footer (was previously removed from HTML but still referenced in JavaScript).
+
+### Added
+- Settings → Maintenance: new "Generate test run (override testing)" card:
+ - Generates a single JobRun with 3 objects in `run_object_links` for a fixed test job (`__test-override-job__`).
+ - Operator chooses status (Success/Warning/Failed) and error scenario (VSS, connection timeout, disk space, license, network, permissions, or custom).
+ - Test job and customer are auto-created on first use.
+ - "Delete all test runs" button cleans up all generated test data.
+
+### Fixed
+- Run Checks overview was not filtering out jobs belonging to inactive customers; only the missed-run sweep query had the `Customer.active` filter. Added `Customer.active` filter to the overview aggregation query.
+- Search page Run Checks section had the same missing `Customer.active` filter; now consistent with other views.
## [2026-04-13]
diff --git a/docs/changelog.md b/docs/changelog.md
index 3b10155..c390f8e 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,3 +1,33 @@
+## v0.3.0
+
+This release bundles all changes made since `v0.2.5`. Highlights: Smart Overrides Phase 1 (create overrides directly from Run Checks), Cove workstation offline handling (no more false-positive Missed alerts for powered-off PCs, plus an optional colorbar-based offline-detection toggle), a test-run generator in Settings → Maintenance, and a full in-app documentation refresh.
+
+### Added
+- **Smart Overrides Phase 1** — after marking a Run Checks run as Success, a follow-up dialog offers to create a broader override for future occurrences:
+ - Scope: only this run, this job + same error, or all jobs with same software/type + error.
+ - Duration: 1 week, 1 month, or permanent.
+ - Error text is pre-filled from the run's problem objects; broader overrides are audit-logged with scope, duration, and source run.
+ - No database migration required (uses existing `Override` model).
+- **Cove workstation offline detection** (Settings → Integrations → Cove) — optional colorbar-based check that flags Cove workstations as Warning / Error after a configurable number of consecutive inactive days. Disabled by default; thresholds default to 7 / 14 days. Synthetic offline runs use a stable `external_id` per account so they escalate in place and clear automatically once activity resumes; reviewed runs are never mutated.
+ - New `system_settings` columns: `cove_offline_detection_enabled`, `cove_workstation_warning_days`, `cove_workstation_error_days` (`migrate_cove_offline_detection`).
+- **Settings → Maintenance: Generate test run** card — creates a single `JobRun` with three persisted objects on a fixed test job (`__test-override-job__`) so operators can exercise the Smart Override flow without a real backup. "Delete all test runs" button cleans up.
+- Run Checks "Mark as Success" button restored in the modal footer (the JS hook existed but the button was missing).
+
+### Changed
+- **Cove workstation jobs are excluded from schedule-based missed-run detection.** Workstations are routinely powered off outside business hours, which produced false-positive Missed alerts. Cove Server and Microsoft 365 jobs are unaffected; real Cove statuses (Failed / Warning / Not started) still surface via the normal import flow.
+- In-app documentation refreshed across `getting-started`, `users`, `mail-import`, `integrations` (Cove), `settings`, `backup-review`, `customers-jobs`, and `autotask` to match current behaviour. Includes Smart Overrides documentation, Cove/Cloud Connect summary panels in the Run Checks modal, archived-jobs filter on the Inbox, captcha & Entra SSO authentication options (SSO marked as implemented but not yet validated in production), expanded supported-software list, and Cove offline-handling sections.
+
+### Fixed
+- **Run Checks Cove same-day suppression** — once the first complete success run for a Cove job/day is recorded (status Success with all object statuses Success), all newer Cove runs on that same local day are hidden from Run Checks (overview aggregation + modal details), regardless of status. Sort order in the modal stays newest → oldest.
+- **Inbox excludes mail messages from archived jobs** — messages whose `job_id` points to an archived job are filtered out (messages without a linked job remain visible).
+- **Run Checks / Search overview filters out inactive customers** — both queries now apply the `Customer.active` filter that was previously only on the missed-run sweep.
+
+### Build / Tooling
+- Adopted the shared `docker-build-and-push` script from `/docker/develop/shared-integrations/tooling/`. The new contract:
+ - Modes are `t` (test → push `:dev`) and `r` (release → push `:`, `:dev`, `:latest`); bump types `1`/`2`/`3` are no longer used.
+ - Release version is read from the first `## vX.Y.Z` heading in this file; the script no longer maintains `version.txt`.
+ - The script performs no git operations — commit, tag, and push are run manually after the registry has accepted the images.
+
## v0.2.5
This release bundles all changes made since `v0.2.4`, including schedule management improvements, Autotask/remark synchronization, Run Checks stability updates, and a full documentation refresh.
diff --git a/version.txt b/version.txt
deleted file mode 100644
index b88fb90..0000000
--- a/version.txt
+++ /dev/null
@@ -1 +0,0 @@
-v0.2.5