docs: define the interface pattern language
This commit is contained in:
392
docs/INTERFACE_PATTERN_LANGUAGE.md
Normal file
392
docs/INTERFACE_PATTERN_LANGUAGE.md
Normal file
@@ -0,0 +1,392 @@
|
||||
# GovOPlaN Interface Pattern Language
|
||||
|
||||
This document is the cross-repository pattern language for GovOPlaN user
|
||||
interfaces. It turns the existing ethical doctrine, binding UI/UX decisions,
|
||||
layout principles, and module boundary into a common composition and review
|
||||
grammar. It does not replace those sources.
|
||||
|
||||
The companion [interface surface inventory](INTERFACE_SURFACE_INVENTORY.md)
|
||||
records which surfaces the current code contributes and where each surface
|
||||
enters the rollout.
|
||||
|
||||
## Source Of Truth And Precedence
|
||||
|
||||
Use the narrowest owning document when changing a rule:
|
||||
|
||||
1. `govoplan-core/docs/INTERFACE_ETHICS_AND_DESIGN_DOCTRINE.md` owns why a
|
||||
consequential interface must preserve context, decision, consequence,
|
||||
responsibility, contestability, and traceability.
|
||||
2. `govoplan-core/docs/UI_UX_DECISION_LEDGER.md` owns accepted product decisions
|
||||
such as progressive disclosure, adaptive forms, blocker language, guided
|
||||
operations, and the platform theme contract.
|
||||
3. `docs/FRONTEND_LAYOUT_PRINCIPLES.md` owns the high-level choice between a
|
||||
full-space structured-data workspace and a heading/menu/card workflow or
|
||||
configuration surface.
|
||||
4. `govoplan-core/docs/MODULE_ARCHITECTURE.md` owns the shell, route, navigation,
|
||||
UI-capability, and shared-component boundaries.
|
||||
5. This document owns the common pattern names, placement grammar, wording and
|
||||
state conventions, focused-view composition, and definition of done across
|
||||
those sources.
|
||||
|
||||
If two rules appear to conflict, do not create a third local convention. Record
|
||||
the conflict in the owning decision ledger, resolve it there, and update the
|
||||
affected patterns and surfaces together.
|
||||
|
||||
## Product Contract
|
||||
|
||||
GovOPlaN should feel calm because it shows what is relevant to the task, not
|
||||
because it hides authority, risk, or evidence. Every surface follows these
|
||||
rules:
|
||||
|
||||
- Start with the user's current object and task.
|
||||
- Show common actions before advanced controls.
|
||||
- Keep context, status, problems, and the next action spatially connected.
|
||||
- Make consequential effects explicit before execution and observed effects
|
||||
inspectable afterwards.
|
||||
- Treat permissions, policy, privacy, and module availability as behavior, not
|
||||
decoration.
|
||||
- Keep optional modules optional. Compose through core route and UI-capability
|
||||
contracts, never sibling-private components.
|
||||
- Preserve a stable way back to the containing object and the broader system.
|
||||
- Do not let navigation, selection, or a view switch imply consent.
|
||||
|
||||
## Surface Archetypes
|
||||
|
||||
Choose an archetype from the task, then specialize it for the domain. A route
|
||||
may contain more than one bounded archetype, but it should have one dominant
|
||||
one.
|
||||
|
||||
| Archetype | Use when | Standard anatomy | Do not use when |
|
||||
| --- | --- | --- | --- |
|
||||
| Directory or explorer | Users browse hierarchical collections such as files, mailboxes, calendars, addresses, or records. | Collection/source pane, collection actions, filter in the pane it affects, main list/content pane, optional detail pane. | The content is a set of unrelated settings or workflow stages. |
|
||||
| List-detail workspace | Users repeatedly find objects, inspect one, and act without losing list context. | Search/filter/list, persistent selected-object context, detail/actions, stable selection and URL. | A single guided operation is the primary task. |
|
||||
| Focused task view | Only a bounded composition is needed to complete one task. | Task identity and reason, selected object, necessary module regions/actions, progress or status, obvious exit to the full system. | Hiding a surface would obscure a consequence, blocker, or required evidence. |
|
||||
| Create or edit | Users change one coherent object state. | Adaptive typed form, field-level validation, advanced section, save/cancel, unsaved-change guard. | Discovery-heavy setup or a broad consequential change needs staged review. |
|
||||
| Guided setup or import | The user must discover, upload, map, test, or preflight before a safe result exists. | Named steps, current progress, preserved inputs, validation/problem list, review, resumable completion where work is durable. | An ordinary edit can be understood as one coherent form. |
|
||||
| Review or decision | A person must inspect evidence and deliberately approve, reject, send, publish, or otherwise commit. | Decision context, evidence/problems, consequence and reversibility, authority/provenance, explicit action, resulting record. | The interaction is passive inspection. |
|
||||
| Monitoring, progress, or report | Users observe asynchronous or aggregate state and intervene when needed. | Summary, filters, durable job/item state, last update, retry/reconcile/intervention, detail and evidence. | A toast is sufficient for a short, non-durable local action. |
|
||||
| Administration or configuration | Users compare and configure separate concerns. | Heading and scope, grouped subnavigation, overview/list plus selected details, adaptive editor or guided risky operation, effective policy and source. | The primary task is browsing one structured object space. |
|
||||
| Dashboard | Users need a task-oriented starting point across modules. | Prioritized actionable widgets, scoped status, clear destination per widget, explicit refresh/staleness. | It merely duplicates every module navigation item or metric. |
|
||||
| Public service or entry | An unauthenticated or external participant starts or resumes a service. | Service identity, eligibility/context, privacy and evidence expectations, accessible form/task, save/resume or handoff. | The actor is performing internal administration. |
|
||||
|
||||
## Placement Grammar
|
||||
|
||||
### Shell And Navigation
|
||||
|
||||
- The global title bar and rail belong to core. A module contributes routes,
|
||||
navigation metadata, and explicit UI capabilities; it does not reproduce the
|
||||
shell.
|
||||
- Global navigation answers "which service area?" Local subnavigation answers
|
||||
"which stable facet of this object or area?" A progress indicator answers
|
||||
"where am I in this operation?" Do not use those three controls
|
||||
interchangeably.
|
||||
- Keep the current tenant, actor, object, and selected version or scope stable
|
||||
across local navigation. Guard unsaved work before navigation.
|
||||
- Permission and capability filtering happens before view composition. A
|
||||
missing menu item is not evidence that an actor lacks backend access, and a
|
||||
visible item is never authorization by itself.
|
||||
- Route, selection, panel, and view changes must not execute consequential
|
||||
actions.
|
||||
|
||||
### Page And Workspace
|
||||
|
||||
- Structured directories use the full available content space and persistent
|
||||
panes. They do not add a decorative heading row that reduces working height.
|
||||
- Workflow, configuration, dashboard, and explanatory pages may use a heading.
|
||||
The heading names the task or scoped object and contains only route-level
|
||||
actions.
|
||||
- Put filters beside the list or pane they affect. Put bulk actions immediately
|
||||
above or beside the current selection. Put object actions with the object
|
||||
detail, not in the global title bar.
|
||||
- Full-page create and edit surfaces put their persistent action cluster in the
|
||||
upper-right of the page heading. `Discard` comes before `Save …`, with the
|
||||
primary save action at the far right. Keep both controls in the same place
|
||||
across validation, loading, and saved states; guard unsaved work when the
|
||||
user discards or navigates away.
|
||||
- A page or panel has one visually primary action for its current state. Put
|
||||
secondary actions beside it. Separate destructive actions and name their real
|
||||
effect.
|
||||
- Dialog actions use a stable footer: cancel/back first, then the primary action
|
||||
at the end. Header and footer stay fixed while long bodies scroll.
|
||||
- Use cards for independent groups, summaries, and settings blocks. Do not wrap
|
||||
every region in a card or nest cards merely to create spacing.
|
||||
- When a collapsible card contains one table and no other content, the table
|
||||
uses the card's full available width and body height. The card/table region
|
||||
owns overflow; do not add an inner max-width, decorative wrapper, duplicate
|
||||
padding, or nested scroll container that reduces the working area.
|
||||
- Row actions in tables are icon-only controls in a stable rightmost action
|
||||
column. Order them by intent: inspect/open, edit, copy/duplicate,
|
||||
transfer/share/download, retry/restore, then remove/delete last. Omit actions
|
||||
that do not apply without closing the gap or changing the relative order.
|
||||
Every icon has a translated accessible name and matching tooltip. Separate
|
||||
destructive actions visually, and use a named confirmation/review surface
|
||||
when the consequence cannot be understood from the icon and row context.
|
||||
- Transient feedback should not shift the workspace. Durable failures, partial
|
||||
results, and blockers remain attached to the affected item or operation.
|
||||
|
||||
### Detail And Explanation
|
||||
|
||||
- Keep the selected object's identity and material status visible while its
|
||||
detail changes.
|
||||
- Short field help sits with the label. Longer "Why?", policy source,
|
||||
diagnostics, or provenance belongs in an expandable area, detail panel, or
|
||||
review step.
|
||||
- Empty space is not an error. An empty state states what is empty, why that can
|
||||
happen, and the permitted next action. Do not show creation actions to actors
|
||||
who cannot create.
|
||||
|
||||
## Visual Grammar
|
||||
|
||||
- Core owns the appearance contract and shared CSS tokens. Modules use core
|
||||
colors, spacing, radii, shadows, focus treatment, status colors, and disabled
|
||||
treatment; module CSS may specialize layout only.
|
||||
- Establish hierarchy through spacing, typography, grouping, and placement
|
||||
before adding borders or color.
|
||||
- Color never carries status or required action alone. Pair it with text and,
|
||||
where useful, an icon.
|
||||
- Icons support recognition but do not replace accessible names. Use the core
|
||||
icon-name mapping for navigation.
|
||||
- Keep list columns, tree indentation, headers, dialog dimensions, and action
|
||||
positions stable as content changes.
|
||||
- Density is a user preference, not a license to remove labels, focus targets,
|
||||
explanations, or consequences.
|
||||
- Respect system/light/dark themes and reduced-motion preferences through the
|
||||
core contract. Do not build module-local theme systems.
|
||||
|
||||
## Wording Grammar
|
||||
|
||||
Use the same noun for the same domain object in navigation, headings, fields,
|
||||
actions, states, API-facing explanations, and documentation. Prefer the most
|
||||
specific user-facing noun: "Recipients" rather than "Data", "Delivery job"
|
||||
rather than "Process", and "Mail profile" rather than "Configuration" when
|
||||
that is what the user is acting on.
|
||||
|
||||
Actions use a verb plus the object or consequence:
|
||||
|
||||
- Prefer `Save campaign`, `Review messages`, `Queue delivery`, `Retry failed
|
||||
deliveries`, or `Delete calendar`.
|
||||
- Avoid `Submit`, `OK`, `Continue`, or `Execute` when a more precise action is
|
||||
available.
|
||||
- Use `Continue` only when it advances a reversible guided flow without
|
||||
committing the final effect.
|
||||
- Do not say `Undo` when the system can only cancel future work, create a
|
||||
correction, supersede a record, or request retraction.
|
||||
|
||||
State text describes observed state, not optimism. Use stable shared terms where
|
||||
they fit: `Draft`, `Ready for review`, `Blocked`, `Queued`, `Running`,
|
||||
`Retry scheduled`, `Partially completed`, `Completed`, `Failed`, and
|
||||
`Cancelled`. Domain-specific states may refine these terms but should not give a
|
||||
shared term a contradictory meaning.
|
||||
|
||||
Blocked and failed actions use the structured language from DUE-005:
|
||||
|
||||
- what is unavailable or failed
|
||||
- why, in plain language
|
||||
- what must happen next
|
||||
- who can do it
|
||||
- where to go
|
||||
- optional technical details behind deliberate disclosure
|
||||
|
||||
Errors should identify the affected object and whether saved state or external
|
||||
effects may already exist. Never expose raw exception text as the only user
|
||||
message.
|
||||
|
||||
## State Contract
|
||||
|
||||
Every surface implements the states it can reach; it does not render a blank
|
||||
region while waiting or collapse distinct outcomes into a generic error.
|
||||
|
||||
| State | Required treatment |
|
||||
| --- | --- |
|
||||
| Loading | Keep the stable shell and context visible. Name what is loading; preserve usable prior data when safe. |
|
||||
| Empty | State the scope and reason, then show only permitted next actions. |
|
||||
| Validation problem | Attach the problem to the field/item and provide a navigable summary when problems span regions or steps. |
|
||||
| Permission denied | Name the unavailable action or object, the required actor/role where safe, and a valid exit. Do not leak protected data. |
|
||||
| Capability unavailable | Distinguish not installed, disabled, not configured, unhealthy, and not permitted when the actor may know. Give the responsible actor and target. |
|
||||
| Offline or unreachable | Preserve local context and unsaved input, show last-known/stale state, and offer a safe retry. Do not present network absence as an authentication failure. |
|
||||
| Stale or conflicting | Show which data changed, preserve both values where feasible, and offer reload, merge, or explicit overwrite according to policy. |
|
||||
| Partial result | Show completed and incomplete effects separately. Never label a partial operation successful without qualification. |
|
||||
| Asynchronous work | Show durable job identity, queued/running/retry/block/final state, last update, progress if meaningful, and leave/return behavior. |
|
||||
| Success | State the resulting object/effect and provide its evidence or destination. Use a transient toast only when the result is already visible and durable elsewhere. |
|
||||
| Destructive or corrective action | Preview scope, downstream effects, reversibility limit, evidence, and required confirmation or approval. |
|
||||
|
||||
Long-running or external work must expose retry and reconciliation as observable
|
||||
states. The UI must not imply that a request and its external effect were one
|
||||
atomic success when an outbox, worker, or remote system sits between them.
|
||||
|
||||
## Consequence And Provenance
|
||||
|
||||
Before an action affects records, rights, policy, retention, communications,
|
||||
money, external systems, or workflow state, its action surface must answer the
|
||||
decision-surface questions in the interface doctrine. At minimum show:
|
||||
|
||||
- affected object and scope
|
||||
- acting identity or system actor and relevant authority
|
||||
- immediate and possible downstream effects
|
||||
- whether the operation is reversible, cancellable, corrective, or final
|
||||
- blockers and their resolution path
|
||||
- audit/evidence that will be created
|
||||
- effective policy or configuration source when it changes the decision
|
||||
|
||||
After execution, users must be able to reach the command/job, observed effects,
|
||||
policy result, failures, retries, reconciliation outcome, actor, time, and source
|
||||
data that explain the result. Provenance may be quiet by default, but it must not
|
||||
be absent.
|
||||
|
||||
Privacy follows the same rule: lists, previews, logs, notifications, and
|
||||
diagnostics show only the personal or secret data needed for the actor's task.
|
||||
Redaction must be explicit enough that users do not mistake a redacted value for
|
||||
missing source data.
|
||||
|
||||
## Focused Views
|
||||
|
||||
A focused view is a declarative UI composition for a task. It selects the
|
||||
routes, local regions, navigation entries, and actions relevant to that task
|
||||
after installed-module, capability, permission, and policy filtering. It does
|
||||
not change backend authorization or domain state.
|
||||
|
||||
A view definition must be able to explain:
|
||||
|
||||
- its stable identifier, label, and task purpose
|
||||
- the current object/scope and default destination
|
||||
- included navigation and contributed regions/actions, with deterministic order
|
||||
- the visible escape to the containing module and full system
|
||||
- why the view is active and how the user may switch when switching is allowed
|
||||
- what happens to unsaved work when entering, leaving, or switching views
|
||||
|
||||
Focused views follow these invariants:
|
||||
|
||||
- Do not hide a blocker, material consequence, provenance, or required review
|
||||
merely to make the screen quieter.
|
||||
- Preserve the global tenant/actor context and provide an obvious exit.
|
||||
- Filter unavailable contributions without leaving broken separators, empty
|
||||
groups, or dead destinations.
|
||||
- A manual or automatic switch is navigation, not consent. Guard unsaved work
|
||||
and never execute a domain action as a side effect.
|
||||
- Display why a non-manual default was selected, for example a role or task
|
||||
default, without exposing protected policy details.
|
||||
- Treat an unknown or invalid view as a recoverable fallback to the normal
|
||||
module surface.
|
||||
|
||||
When more than one source proposes a focused view, use this precedence:
|
||||
|
||||
1. a manual view pinned for the current user session
|
||||
2. a current-task suggestion, including a future workflow-step suggestion
|
||||
3. the user's saved default
|
||||
4. the role or tenant default
|
||||
5. the normal full interface
|
||||
|
||||
Show the active source and an escape to the full interface. A task or workflow
|
||||
suggestion is never an authorization change and never locks the user into the
|
||||
composition; tenant policy may constrain which views are selectable, but it
|
||||
must not hide required evidence or remove that escape. Workflow implementation
|
||||
is explicitly postponed and is not a prerequisite for defining, manually
|
||||
selecting, testing, or piloting focused views. A future workflow module may
|
||||
request a view through a core contract; it must not own the view composition
|
||||
implementation.
|
||||
|
||||
## Accessibility And Responsive Contract
|
||||
|
||||
- Every action is reachable and operable by keyboard in a logical order.
|
||||
- Use semantic headings, landmarks, labels, tables/lists, and native controls
|
||||
before adding ARIA. Icon-only controls need stable accessible names.
|
||||
- Focus is visible. Dialogs trap focus, announce their name, and return focus to
|
||||
the control that opened them. Validation moves or links focus to the first
|
||||
relevant problem without losing the problem summary.
|
||||
- Loading, saved, failed, queued, progress, and externally updated states are
|
||||
announced without repeatedly interrupting the user.
|
||||
- Disabled primary actions need a focusable explanation; a pointer-only tooltip
|
||||
is insufficient.
|
||||
- Do not rely on color, hover, drag-and-drop, pointer precision, or animation as
|
||||
the only interaction. Provide keyboard and explicit-control equivalents.
|
||||
- At narrow widths and high zoom, preserve task order and action access. Collapse
|
||||
secondary panes into an explicit drawer/step and never move a destructive
|
||||
action into the primary position.
|
||||
- Honor reduced motion. Avoid motion that implies progress when the operation is
|
||||
merely waiting.
|
||||
- Truncation has an accessible full-value path. Personal or secret values remain
|
||||
redacted according to permission and policy in that path.
|
||||
|
||||
## Component Ownership
|
||||
|
||||
Core already exports shell, navigation, access-boundary, form, dialog, loading,
|
||||
status, policy/provenance, blocker, review, table, tree, message-display, and
|
||||
unsaved-change primitives. Reuse them when their contract fits.
|
||||
|
||||
Do not promote a component only because two screens look similar. Promote it to
|
||||
`@govoplan/core-webui` after a second consumer or a clear platform contract has
|
||||
proved shared behavior, accessibility, state, and extension needs. Modules own
|
||||
domain composition, wording, and policy semantics; core owns generic contracts
|
||||
and appearance.
|
||||
|
||||
## Test Expectations
|
||||
|
||||
For every changed surface, select tests from each applicable layer:
|
||||
|
||||
- route and permission tests: module enabled/disabled permutations, route guard,
|
||||
contribution filtering, fallback, and direct-link behavior
|
||||
- behavior tests: primary task, validation, unsaved-change guard, confirmation,
|
||||
retry/reconcile, partial result, and leave/return behavior
|
||||
- accessibility tests: semantic names/roles, keyboard order, focus entry/return,
|
||||
live-state announcements, and non-color status meaning
|
||||
- state tests: loading, empty, denied, capability-missing, stale/conflict,
|
||||
offline, partial, success, and destructive/corrective outcomes as applicable
|
||||
- composition tests: absent optional module, duplicate/unknown contribution,
|
||||
deterministic ordering, and focused-view fallback
|
||||
- presentation checks: supported widths/zoom, light/dark/system theme, reduced
|
||||
motion, comfortable/compact density, and long translated text
|
||||
- i18n checks: user-facing strings owned by the rendering package and structural
|
||||
audits passing
|
||||
- visual regression: useful for geometry and hierarchy after behavior and
|
||||
accessibility assertions exist; never the only evidence
|
||||
|
||||
If the current harness cannot automate a required check, record the gap and the
|
||||
manual evidence in the owning issue. "Not tested" is an inventory state, not a
|
||||
reason to infer that a pattern is satisfied.
|
||||
|
||||
## Definition Of Done For A Surface
|
||||
|
||||
- The dominant task and archetype are recorded in the inventory.
|
||||
- Placement, action hierarchy, wording, and every reachable state follow this
|
||||
pattern language or an explicit ledger exception.
|
||||
- Permission, capability, privacy, and redaction behavior are verified.
|
||||
- Consequence, reversibility, authority, evidence, and provenance are present
|
||||
where applicable.
|
||||
- Keyboard, focus, announcement, responsive, theme, density, motion, and i18n
|
||||
behavior are covered in proportion to the surface.
|
||||
- Optional modules remain optional and no sibling-private UI import was added.
|
||||
- Behavioral/accessibility evidence is linked from the rollout matrix and issue.
|
||||
- Configured-system help can reach the applicable pattern or reference topic
|
||||
when [Docs #15](https://git.add-ideas.de/add-ideas/govoplan-docs/issues/15)
|
||||
supplies that experience.
|
||||
|
||||
## First Pilot: Campaign
|
||||
|
||||
[Campaign #74](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/74)
|
||||
is the first full-domain audit and migration. It should prove patterns before
|
||||
generic extraction:
|
||||
|
||||
- [#59](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/59) and
|
||||
[#73](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/73): stable,
|
||||
accessible preview and attachment-detail overlays
|
||||
- [#63](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/63): review
|
||||
stages, outcomes, blockers, and intervention vocabulary
|
||||
- [#62](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/62): explicit
|
||||
synchronous/asynchronous send mode and durable delivery progress
|
||||
- [#65](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/65): one
|
||||
coherent report filtering and count-affordance model
|
||||
- [#35](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/35): guided
|
||||
first-campaign entry
|
||||
|
||||
These slices do not depend on the Workflow runtime. Campaign's current
|
||||
domain-owned review/send state is enough to prove layout, wording, focused-view,
|
||||
progress, intervention, and evidence patterns.
|
||||
|
||||
## Revision Procedure
|
||||
|
||||
1. Record a changed product decision in the core UI/UX decision ledger.
|
||||
2. Update the relevant pattern here without copying the full owning doctrine.
|
||||
3. Update the surface inventory and rollout owner/issues.
|
||||
4. Change shared components only where the proven contract belongs to core.
|
||||
5. Migrate and test affected module surfaces.
|
||||
6. Publish configured-system pattern/reference help through the Docs module.
|
||||
Reference in New Issue
Block a user