{% extends "base.html" %} {% block title %}Onboard clients & jobs — BackupWatch{% endblock %} {% block main_class %}onboarding-workspace{% endblock %} {% block content %}
Import inventory, verify report routing, then activate selected jobs. Drafts and observing jobs stay visible here.
{% if msg %}{% endif %}Mailbox: {{ 'a successful poll has been recorded' if mailbox_ok else 'awaiting first successful poll' }}. Mailbox settings
Schedule timezone: {{ timezone }}. Alerts go to {{ recipients or 'no destination configured' }}.
Notification delivery: {{ notification_test or 'not confirmed during onboarding' }}. Send a test in Settings
A received failure can verify routing. Monitoring still requires a successful report within the expected window.
Download CSV template. Use a stable client code and job reference. Reimports preserve blank settings; updates require explicit selection.
Group up to 500 reports from a date range into proposed jobs. Discovery does not send alerts, move messages or change their read state. An inventory is still needed to find jobs that never report.
Maximum 90 days. Mailbox discovery uses provider date boundaries (Microsoft 365: UTC); stored reports use {{ timezone }}. Narrow the range if the sample limit is reached.
Groups every report waiting in the Review queue, for every client, using the same heuristic grouping as "Discover jobs from reports" above — nothing is filed, matched or marked read. When AI assistance is enabled in Settings, each client with waiting mail also gets its own Claude refinement pass, sent one client at a time, shown for review before anything sends.
Search the Review queue for mail this client's email identifiers claim, grouped into proposed jobs. Nothing is filed, created or marked read until you save a job in the wizard.
{% if find %} {% if find.error %} {% else %}Searched {{ find.searched }} waiting report(s) in that range{% if find.capped %} — sample limit reached; narrow the range{% endif %}. {{ find.groups|length }} group(s) match {{ find.client.display_name }}{% if find.ai_applied %} — refined by Claude{% endif %}.
{% if find.ai_snapshot and not find.ai_applied %} {# the button never sends: it opens a dialog showing the stored snapshot first #} {% endif %}| Proposed job | Reports | Rules it would use | |||||||
|---|---|---|---|---|---|---|---|---|---|
| {{ g.name }}{% if g.refined %} AI{% endif %} | {{ g.count }} | {% if g.sender_rule %}from contains {{ g.sender_rule }} {% endif %}{% if g.subject_rule %}subject contains {{ g.subject_rule }}{% endif %} Vendor: {{ vendor_labels.get(g.vendor, g.vendor) }} |
{% if g.existing_job %}Already covered by {{ g.existing_job }}{% else %}Create job in wizard{% endif %} | ||||||
Show the {{ g.samples|length }} email(s) behind “{{ g.name }}”
…and {{ g.extra }} more not shown. {% endif %} | |||||||||
| No waiting mail matches this client's identifiers in that range. Check the identifiers on the client page, or widen the dates. | |||||||||
{{ find.uncovered|length }} group(s) below were not sent to Claude.
| Proposed job | Reports | Rules it would use | |||||||
|---|---|---|---|---|---|---|---|---|---|
| {{ g.name }} | {{ g.count }} | {% if g.sender_rule %}from contains {{ g.sender_rule }} {% endif %}{% if g.subject_rule %}subject contains {{ g.subject_rule }}{% endif %} Vendor: {{ vendor_labels.get(g.vendor, g.vendor) }} |
{% if g.existing_job %}Already covered by {{ g.existing_job }}{% else %}Create job in wizard{% endif %} | ||||||
Show the {{ g.samples|length }} email(s) behind “{{ g.name }}”
…and {{ g.extra }} more not shown. {% endif %} | |||||||||
Resume previews and correct failed rows. A saved row is never applied twice.
| Created | Batch | Technician |
|---|---|---|
| {{ batch.created_at|dt }} | {{ batch.kind|capitalize }} · {{ batch.id[:8] }} | {{ batch.created_by }} |
| No batches yet. | ||