Migrate Mail surfaces to interface patterns

This commit is contained in:
2026-08-03 10:06:13 +02:00
parent 5b5077cde7
commit 7844d9cab4
12 changed files with 460 additions and 44 deletions
+68
View File
@@ -0,0 +1,68 @@
# Mail Interface Pattern Migration
This inventory records the Mail-owned part of the GovOPlaN interface pattern
language. Core owns the shell and shared components; Mail owns the transport,
mailbox, policy, and delivery-evidence consequences described here.
## Surface inventory
| Surface | Primary task | Archetype | Consequence | Pattern evidence |
| --- | --- | --- | --- | --- |
| `/mail` folder, message, and preview panes | Browse and inspect an authorized mailbox without changing provider state | Directory/explorer | Medium because message metadata and content are private, although navigation is read-only | Full-height three-pane workspace, bounded paging, stable keyboard selection, contextual Help Center link, explicit no-profile blocker |
| `/mail` toolbar, page filter, and pagination | Select a profile, refresh bounded indexes, and find a message on the current page | Explorer actions and local filtering | Low for refresh; medium for provider access | Shared actions expose loading/profile/folder blockers; profile transport summary is non-secret; loading and errors use Core components |
| System/tenant/group/user/campaign profile surfaces | Compare profiles, protocol servers, reusable credentials, status, and scope | Administration/configuration | High because endpoints, credentials, and inheritance control external communication | Shared `ConnectionTree`, stable row actions, textual status, permission/target blockers, and contextual admin help |
| Profile creation and focused profile/server/credential editors | Create a governed transport identity or edit one hierarchy object | Guided setup plus adaptive create/edit | High because saving may enable provider access or replace encrypted credentials | Shared `Dialog` and `StageRail` for multi-object setup; focused edit modes show only the selected hierarchy object; field help, connection tests, unsaved-draft guard, and disabled-save reasons |
| Mail profile policy card | Narrow visible profiles, lower-scope definitions, hosts, senders, and recipients | Effective-policy editor | High because inherited allow/deny rules govern delivery and lower scopes | Shared policy rows, typed selectors, source path, locked/read-only blocker, dirty-save state, and contextual policy help |
| `/mail/bounces` watcher table | Configure bounded IMAP evidence sources and run an explicit scan | Operational administration | High because it accesses a provider mailbox and changes durable evidence cursors | Shared `DataGrid`, status, loading/error feedback, field help, actionable no-profile blocker, and stable row actions |
| `/mail/bounces` observation table | Inspect correlated or unmatched delivery-status evidence | Evidence/reporting | Medium because recipient and diagnostic data may be sensitive | Bounded sanitized rows, textual status, filters, correlation state, and no raw bounce body |
| Bounce watcher removal | Stop future scans while retaining evidence | Destructive confirmation | Medium and reversible by recreating the watcher; observations are retained | Shared `ConfirmDialog` states the immediate consequence and retained evidence |
| `mail.profiles` and credential-reference capabilities | Let another module select or validate Mail-owned transport without receiving secrets | Governed capability composition | High because the selected identity can perform external effects | Stable references and Core capability boundaries; no sibling-private WebUI import; authorization and credential resolution remain Mail-owned |
## State and consequence contract
- Loading, success, error, empty results, permission blockers, and destructive
confirmation use Core components. Mail does not reproduce the shell.
- A target-dependent profile surface cannot load until a concrete user, group,
or campaign is selected. The blocker identifies the responsible actor and
destination instead of silently hiding the editor.
- Profile, server, credential, policy, mailbox refresh, connection-test, and
bounce actions remain visible when structurally relevant. Missing authority,
required input, or an in-progress operation is exposed through a focusable
disabled-action explanation.
- Connection tests never save the draft and explicitly require the relevant
hostname. Save remains the committing action. Policy save is unavailable
until a local change exists.
- Effective policy keeps inherited source/provenance visible. A locked parent
limit or governed workflow cannot be represented as an editable local value.
- Removing a bounce watcher retains observations and delivery evidence.
Profile/server deactivation and credential unlinking use confirmations whose
copy distinguishes retained reusable credentials from scrubbed owned secrets.
- Mailbox browsing is read-only. Listing or previewing must not mark messages
read, move, delete, reply, or expose unbounded content.
## Accessibility, responsive, and privacy evidence
Shared `Dialog` owns focus entry, Escape handling, focus containment, and focus
return. Toolbar and form DOM order is keyboard order; mailbox rows support
Enter and Space, arrow navigation is bounded to the visible page, and disabled
reasons are keyboard-focusable. Status always has text in addition to color.
Contextual links identify their destination to assistive technology.
Profile/policy grids collapse to one column below 900 px. The mailbox changes
from three panes to two below 1250 px and to a single-column toolbar and message
rows below 760 px while preserving source order and independent scroll regions.
Long identities and transport summaries wrap or ellipsize inside stable bounds.
Profile and mailbox APIs return non-secret transport metadata and bounded
message content only. Passwords are write-only and rendered only as a saved
state marker. Bounce observations contain bounded sanitized diagnostics and a
raw digest, not the raw provider message. Optional Campaign, Addresses, Audit,
Calendar, and Notifications integrations remain capability-driven; Mail WebUI
does not import their private packages.
The focused structural test guards shared components, contextual help,
actionable blockers, confirmation, optional-module boundaries, responsive
rules, and the absence of browser-native confirmation. Mail backend tests,
Core component tests, manifest-shape checks, module permutations, structural
localization audit, theme contract, and bundle budgets provide integration
evidence.
+19
View File
@@ -43,6 +43,25 @@ session primitives, cryptographic secret helpers, audit infrastructure, and the
module registry. Optional consumers provide narrow context through capabilities;
Mail does not import their ORM or service implementations.
## Interface patterns and unavailable actions
Mail uses the platform's shared explorer, connection tree, adaptive form,
effective-policy, dialog, status, alert, and confirmation components. The
module-owned surface inventory and consequence classification are recorded in
[Mail interface pattern migration](INTERFACE_PATTERN_MIGRATION.md).
An unavailable action remains visible when it belongs to the current task. Its
hover/focus explanation identifies the missing field, active operation, or
permission. Larger blockers state what must change, who can change it, and
where to go. Contextual Help Center links resolve to the configured Docs module
when installed and otherwise use the public documentation fallback.
Mailbox reads, profile reloads, connection tests, policy saves, bounce scans,
and destructive actions each expose their current loading or blocked state.
Removing a bounce watcher and deactivating profile hierarchy items use shared
confirmation dialogs. Removing a watcher retains existing observations;
deactivating a profile may scrub Mail-owned credentials as described below.
## Concepts
### Profile