Files
govoplan-search/docs/INTERFACE_PATTERN_MIGRATION.md
T
zemion 6ad7c6e0ef
Module Package Release / publish-packages (push) Successful in 11s
Release govoplan-search v0.1.20: centralize filtering and refresh behavior
2026-09-08 01:32:53 +02:00

6.0 KiB

Search Interface Pattern Migration

This is the bounded interface-pattern evidence for GovOPlaN Search. Search owns presentation and aggregation; source modules continue to own result data and authorization, and optional external engines remain provider capabilities.

Surface Task and archetype Consequence and state contract
Title-bar Search command and overlay Global or context-sensitive focused lookup The left-most titlebar command, F3, and Ctrl/Cmd+K open the same focus-contained Core dialog with a full-width query field. Arrow keys move through the listbox, Enter opens the selected result, Escape closes it and restores focus.
Overlay and page filters Shared Search-owned SearchFilters with Core multi-select dropdowns Modules and Result types use one implementation with visible selection summaries, Select all, Deselect all, and Clear filters. Multiple selected values are alternatives within a group; both groups must match. Tab, Space, and Escape work inside the Search dialog without closing it when only a dropdown should close.
/search Full-page search/results fallback Query and filters are URL-stable, including explicitly empty selections. Clearing filters preserves the query, context, and unrelated URL parameters. Loading, empty, provider-partial, failed, and paged states remain inside the result region.
Result entries Permission-filtered list-detail destinations A source module supplies the title, safe summary, breadcrumbs, and destination. Search does not infer or bypass source authorization.
Administration > Search index Operator table and bounded recovery actions Operators inspect source coverage and queue health, process pending changes, reconcile module activation, and advance one bounded rebuild page at a time. Quarantined work remains visible.

All surfaces use Core buttons, icon buttons, dialog, alerts, loading, scrolling, and documentation-help primitives. Provider diagnostics are partial-state evidence: safe results remain usable and a failing provider is identified without exposing source data. Search has no destructive action. The responsive layout collapses filters and results at narrow widths, and result activation is available without pointer interaction.

Filter and request contract

Both Search surfaces use the same Search-owned selection, catalogue, and request helpers; the visual dropdown and its selection body are shared Core components, also used by DataGrid and Notifications. Search does not define a second popover or a parallel removable-chip interface.

  • All selected means unrestricted (null in the UI). Select all does not freeze the list to the currently loaded catalogue; newly available sources remain eligible. No options selected ([]) intentionally returns no results without calling search providers. A subset uses OR within its group and AND across the module and result-type groups.
  • The existing API remains compatible: omitted or empty module and resource_type arrays still mean unrestricted. The UI's matchNone shortcut never becomes a backend request parameter. /search uses module_none=1 and resource_type_none=1 to preserve explicit empty selections; these flags take precedence over contradictory repeated values. Subsets keep the existing repeated URL parameters.
  • Contextual overlay search remains bounded to its module and declared result types. An empty intersection is no match, not an instruction to search all types. Clear filters preserves the active context and query. Global module selections are retained when temporarily switching to contextual search.
  • Choices combine source catalogue metadata, observed result values, and previously selected values that are no longer in the catalogue, so stale selections remain removable. Labels use source descriptors and localized module names. This is not a faceted result-count endpoint: catalogue entries do not establish object access or guarantee matching objects.
  • Query, filter, context, account/tenant authority, or API identity changes abort obsolete requests and discard their results and cursors. The shared lifecycle also guards delayed and load-more responses, so a previous search cannot populate the new search or remain keyboard-activatable during the overlay debounce. Cookie-backed tenant switches invalidate results even when the API token stays unchanged.

Bedienung auf Deutsch

Die Suchüberlagerung und die vollständige Suchseite verwenden dieselben Auswahllisten für Module und Ergebnistypen. Mehrere gewählte Werte sind Alternativen innerhalb einer Gruppe; zwischen den Gruppen gilt eine gemeinsame Einschränkung. Alle auswählen hebt die Einschränkung auf. Alle abwählen zeigt bewusst keine Ergebnisse und startet keine Anbietersuche. Filter zurücksetzen behält Suchbegriff und aktuellen Kontext bei.

Im Modulkontext bleiben die Ergebnisse auf das Modul und seine vorgesehenen Typen begrenzt; eine unvereinbare Auswahl erweitert die Suche niemals. Die vollständige Suchseite erhält auch eine ausdrücklich leere Auswahl in ihrer URL. Die Optionen stammen aus Quellenkatalog und beobachteten Ergebnissen, nicht aus einer berechtigungsgefilterten Trefferzählung. Unabhängig von den Filtern prüft die Quelle weiterhin die Berechtigung für jedes Ergebnis.

Mit Tab werden die Filtersteuerungen erreicht, die Leertaste schaltet Optionen um. Escape schließt zuerst die geöffnete Auswahlliste und setzt den Fokus auf ihre Schaltfläche zurück; erst ein weiteres Escape schließt die Suchüberlagerung. Bei einem Such- oder Filterwechsel werden veraltete Anfragen und Ergebnisse verworfen, auch beim Nachladen weiterer Ergebnisseiten. Das gilt auch bei einem Konto- oder Mandantenwechsel mit unverändertem API-Token.

Verification:

  • npm run test:search-filters
  • npm run test:search-overlay
  • npm run test:interface-pattern
  • the Core TypeScript graph, structural localization audit, theme check, module permutations, and full-product bundle budget
  • Search backend compatibility, cursor binding, and bilingual manifest tests