Ships the design spec at docs/superpowers/specs/2026-05-27-owner-approval-flow-design.md.
What's new on central (fusion_helpdesk_central 19.0.1.2.0 -> 19.0.2.0.0):
- Engagement model: 8 new fields on helpdesk.ticket (state, snapshotted
owner email/name, single-use UUID4 token, sent/reminded/decided
timestamps, AI summary, stored-computed turnaround hours).
- Wizard: single + bulk modes on one fusion.helpdesk.engagement.wizard
TransientModel with a child wizard.line for per-ticket bulk summaries.
default_get pulls the OpenAI summary on open; AI fan-out for bulk is
parallel via ThreadPoolExecutor (max 5 workers, 30s overall cap).
- OpenAI client in utils.py — stdlib urllib, 15s per-call timeout, every
failure collapses to '' so the wizard's manual-summary fallback fires.
- Public portal: /fusion_helpdesk/engagement/<token>/<decision> GET +
POST, four branded standalone QWeb pages (confirm/done/invalid/error).
Token is single-use, cleared on confirm. Decision posts a public
comment attributed to the resolved owner partner; chatter propagates
to the employee's My Tickets thread per the "fully visible" UX choice.
- Mail templates (single + bulk) with magic-link buttons. Bulk template
renders one card per ticket, each with its own approve/reject URL.
- Reminder cron: daily, single-shot per engagement, configurable via
fusion_helpdesk_central.engagement_reminder_days ICP (default 3, 0
disables).
- Reporting dashboard: pivot/graph/list/kanban over helpdesk.ticket
filtered to engaged ones, with avg-turnaround measure. Menu lives
under Helpdesk > Reporting > Owner Engagements.
- Client_key extended with owner_email/owner_name fields; ticket.create
upserts them from the client-side piggyback (no new sync endpoint).
- 100% coverage on utils + integration tests on wizard, controllers,
re-engagement, cron, computed turnaround. OpenAI mocked in CI.
What's new on client (fusion_helpdesk 19.0.1.7.1 -> 19.0.2.0.0):
- Two new ICP settings: fusion_helpdesk.owner_email / .owner_name with
a new "Owner Approval" block in Settings > Fusion Helpdesk.
- controllers/main.py::submit piggybacks both keys on every ticket
payload so central keeps client_key.owner_email/name fresh
automatically.
Verified live end-to-end on entech -> nexa: payload upsert, wizard with
mocked AI, action_send, portal GET/POST/GET-again cycle, second click
hits the friendly invalid-token page. Token entropy = 122 bits (UUID4).
Three coordinated changes on top of the section grouping:
1. **Mark as Critical** — a red chip on the New tab sets priority='3'
when submitted. The central post-create hook auto-applies a "Critical"
helpdesk.tag (shipped via fusion_helpdesk_central data XML, noupdate=1
so support can recolor without losing it on upgrade), giving support
a kanban-groupable signal that doesn't rely on remembering what
priority='3' means. Scoped to in-app-channel tickets only, so a
support agent manually setting Urgent on their own ticket isn't
silently tagged.
2. **KPI cards above the sections** — Total / Open / Closed / Critical
in a 4-up grid (auto-collapses to 2x2 under 540px). Each card uses
its own saturated gradient so it reads on both light and dark mode —
the dialog backdrop is irrelevant because the gradient brings its
own background. Counts are computed in JS from state.tickets so they
always match what's rendered below.
3. **Colored stage pills** — red Critical, green Solved, dark-yellow New,
orange Cancelled, blue for In Progress / Testing / On Hold. Critical
priority gets a *separate* red pill alongside the stage pill so you
keep stage info even on escalated tickets. Stage matching is
substring-based (lowercased) so a renamed "Resolved" or "Done" stage
on central still maps to the green pill.
Tests cover the new is_critical=True → priority='3' wiring and the
default omission so SLA / stage defaults keep working for normal
tickets. Bumps fusion_helpdesk to 19.0.1.7.0 and
fusion_helpdesk_central to 19.0.1.2.0. End-to-end smoke test verified
live: priority=3 + x_fc_client_label triggers the Critical tag.
The flat write_date-sorted list was hard to scan with 50+ tickets — solved
ones were intermixed with active ones, and there was no signal for
priority. Bucket each ticket server-side into 'critical' (open + priority
High/Urgent), 'solved' (stage marked fold=True on central) or 'open'
(everything else), and render three labelled sections in the dialog with
sticky headers, count badges, and per-group accent colours. Backend keeps
its write_date desc order so latest is always at top within each bucket.
Bucketing uses helpdesk.stage.fold (not the stage name) so renaming
"Solved" to "Done" on the central won't quietly mis-categorise rows.
Adds bucket_ticket() in utils.py with unit tests covering the
folded-wins-over-priority precedence and the missing-priority fallback.
Also surfaces a small Urgent (triangle) / High (arrow) icon on each row
so a critical ticket reads at a glance even after a user scrolls past
the section header.
Bumps fusion_helpdesk to 19.0.1.6.0.
Squash-merge of feat/helpdesk-customer-followup. The billing and
fusion_login_audit work from that branch is already on main (landed
separately); this lands only the helpdesk feature.
- Identity keystone: submit() forwards partner_email/partner_name/
x_fc_client_label so the central Helpdesk find-or-creates the customer
partner and subscribes them as a follower (enables reply emails + magic link).
- Embedded in-app 'My Tickets' inbox: server-side scoped read/reply RPC
endpoints, per-user seen tracking (fusion.helpdesk.ticket.seen), systray
unread badge. Defense-in-depth scope domain + _norm_email normalisation
(wildcard emails cannot widen scope).
- fusion_helpdesk_central: x_fc_client_label field + list/search views +
branded acknowledgement email template.
- Deployed and smoke-tested live: nexa central 19.0.1.1.0, entech client
19.0.1.4.1 (requires Contact Creation on the central service account).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>