## Summary <!-- Kurz: Was ändert sich und warum? --> ## Spec-Driven Development (SDD) - [ ] Es gibt eine Spec unter `specs/<NNN>-<feature>/` - [ ] Enthaltene Dateien: `plan.md`, `tasks.md`, `spec.md` - [ ] Spec beschreibt Verhalten/Acceptance Criteria (nicht nur Implementation) - [ ] Wenn sich Anforderungen während der Umsetzung geändert haben: Spec/Plan/Tasks wurden aktualisiert ## Implementation - [ ] Implementierung entspricht der Spec - [ ] Edge cases / Fehlerfälle berücksichtigt - [ ] Keine unbeabsichtigten Änderungen außerhalb des Scopes ## Tests - [ ] Tests ergänzt/aktualisiert (Pest/PHPUnit) - [ ] Relevante Tests lokal ausgeführt (`./vendor/bin/sail artisan test` oder `php artisan test`) ## Migration / Config / Ops (falls relevant) - [ ] Migration(en) enthalten und getestet - [ ] Rollback bedacht (rückwärts kompatibel, sichere Migration) - [ ] Neue Env Vars dokumentiert (`.env.example` / Doku) - [ ] Queue/cron/storage Auswirkungen geprüft ## UI (Filament/Livewire) (falls relevant) - [ ] UI-Flows geprüft - [ ] Screenshots/Notizen hinzugefügt ## Notes <!-- Links, Screenshots, Follow-ups, offene Punkte --> Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #223
111 lines
6.8 KiB
Markdown
111 lines
6.8 KiB
Markdown
# Research: Baseline Compare Matrix: High-Density Operator Mode
|
|
|
|
## Decision: Keep the existing matrix route and truth model, and change presentation only
|
|
|
|
### Rationale
|
|
|
|
Spec 190 already established the correct workspace route, the correct baseline reference model, and the correct visible-set-only compare truth. The operator-density follow-up should stay on `/admin/baseline-profiles/{record}/compare-matrix` and must not introduce a second route, a second report artifact, or a second source of matrix truth.
|
|
|
|
### Alternatives considered
|
|
|
|
- Add a separate `dense report` page: rejected because it would duplicate the same baseline-scoped workflow on a second route.
|
|
- Add a stored matrix snapshot: rejected because the operator problem is scan efficiency, not missing persistence.
|
|
|
|
## Decision: Resolve presentation mode from visible tenant count, with a local override only
|
|
|
|
### Rationale
|
|
|
|
The core operator split is real: one visible tenant is a compact review problem, while several visible tenants create a cross-tenant scan problem. The narrowest implementation is one requested mode (`auto`, `dense`, or `compact`) and one resolved mode at render time. `auto` should remain the default, while manual override stays local to the matrix route and must not become stored user preference or domain truth.
|
|
|
|
### Alternatives considered
|
|
|
|
- Separate feature flags or separate navigation entries for each mode: rejected because the matrix should remain one operator surface.
|
|
- Persist mode preference per user: rejected because the current need is local workflow control, not profile-level personalization.
|
|
|
|
## Decision: Dense mode must be state-first, not action-first
|
|
|
|
### Rationale
|
|
|
|
In multi-tenant reading, the primary questions are where drift exists, how severe it is, whether the signal is trustworthy, and what deserves follow-up next. Dense cells should therefore foreground compare state, trust, freshness, and attention, while detailed reasons and repeated links move into compact secondary affordances.
|
|
|
|
### Alternatives considered
|
|
|
|
- Keep the current repeated open-link pattern in every cell: rejected because repeated actions visually outrank the state being scanned.
|
|
- Remove cell-level follow-up completely: rejected because the matrix must remain a decision surface, not a dead-end report.
|
|
|
|
## Decision: Single-tenant mode should be a compact compare list, not a one-column matrix
|
|
|
|
### Rationale
|
|
|
|
Once only one visible tenant remains, the value of cross-tenant columns disappears. The surface should switch to a shorter subject-result list that reuses the same truth but removes repeated tenant headers, empty width, and oversized cell chrome.
|
|
|
|
### Alternatives considered
|
|
|
|
- Reuse dense mode even for one tenant: rejected because it preserves the wrong reading model.
|
|
- Route single-tenant viewing away to the tenant compare page: rejected because the operator still started from the workspace baseline matrix context and should not lose that context automatically.
|
|
|
|
## Decision: Heavy filters should use staged apply/reset semantics
|
|
|
|
### Rationale
|
|
|
|
The current matrix is dense enough that chatty recomputation on every multi-select click works against operator flow. Policy types and other heavy matrix filters should stage changes locally, show that staged state clearly, and apply them deliberately. This improves calmness and makes the surface feel less like a form page.
|
|
|
|
### Alternatives considered
|
|
|
|
- Keep all filters live: rejected because heavy multi-select controls create noisy redraw behavior.
|
|
- Convert every filter to manual apply: rejected because lightweight interactions such as mode switching or focused-subject clearing should remain immediate.
|
|
|
|
## Decision: Replace the long policy-type checkbox stack with a more compact operator-first selector
|
|
|
|
### Rationale
|
|
|
|
The policy-type filter is the most visually expensive control on the page. The follow-up spec should use a denser selection pattern such as searchable multi-select, type-to-find, or another compact control that exposes the same filter truth without the current long vertical list.
|
|
|
|
### Alternatives considered
|
|
|
|
- Keep the long checkbox list and only restyle it: rejected because vertical space is the actual product problem.
|
|
- Hide policy type filtering behind a modal by default: rejected because the filter remains core enough to deserve immediate access.
|
|
|
|
## Decision: Legends should become grouped support context, optionally collapsible
|
|
|
|
### Rationale
|
|
|
|
State, freshness, and trust legends remain semantically valuable, especially for onboarding or occasional operators, but they should no longer compete with the matrix for top-of-screen attention. Grouped, compact legend blocks are the narrowest way to preserve semantics while reducing dominance.
|
|
|
|
### Alternatives considered
|
|
|
|
- Remove legends entirely: rejected because trust and freshness semantics still need an on-page reference.
|
|
- Leave three separate full-width legend sections: rejected because they displace the primary working surface.
|
|
|
|
## Decision: Separate loading, auto-refresh, and last-updated cues
|
|
|
|
### Rationale
|
|
|
|
Spec 190 already exposed the risk of background polling reading like permanent blocking load. This follow-up should make three states explicit: active loading for user-triggered refresh, passive auto-refresh while queued or running compare work exists, and last-updated time for the currently rendered matrix.
|
|
|
|
### Alternatives considered
|
|
|
|
- Reuse one generic refresh chip for all states: rejected because operators cannot tell whether the page is blocked or simply polling.
|
|
- Hide refresh state entirely: rejected because operator trust depends on understanding when the matrix is current.
|
|
|
|
## Decision: Reuse the existing drilldown and visible-set semantics without change
|
|
|
|
### Rationale
|
|
|
|
This spec is a presentation refactor, not a navigation or authorization redesign. The existing tenant compare, finding, run-detail, and canonical-navigation context from Spec 190 remain correct and should carry forward unchanged.
|
|
|
|
### Alternatives considered
|
|
|
|
- Introduce a dense-mode-specific drilldown model: rejected because it would create new behavior where existing follow-up paths are already sufficient.
|
|
- Add aggregated hidden-tenant remainder summaries: rejected because visible-set-only semantics explicitly avoid hidden-tenant leakage.
|
|
|
|
## Decision: Validate primarily with focused page, builder, guard, and browser coverage
|
|
|
|
### Rationale
|
|
|
|
The highest-risk changes are mode resolution, dense-cell hierarchy, compact single-tenant rendering, filter apply behavior, and non-blocking refresh cues. These are best covered with focused feature tests plus one browser smoke path for the interactive Livewire surface.
|
|
|
|
### Alternatives considered
|
|
|
|
- Browser-test every combination exhaustively: rejected because most of the behavior is deterministic and cheaper to validate through feature tests.
|
|
- Limit validation to visual inspection: rejected because mode resolution and filter workflow are important enough to guard in CI. |