listen ansichten verbessert
This commit is contained in:
@@ -13,6 +13,54 @@ Verbindliche Kurzregeln für Architekturentscheidungen.
|
||||
- Autorisierung läuft zentral über Policies.
|
||||
- Externe API-Verträge sind UUID-first.
|
||||
|
||||
## Schichtenübersicht
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Browser([Browser / API-Client])
|
||||
|
||||
subgraph APP["lib/App/ — Composition Root"]
|
||||
DI["AppContainer + Registrars"]
|
||||
end
|
||||
|
||||
subgraph SVC["lib/Service/"]
|
||||
direction LR
|
||||
FAC["Factory"]
|
||||
SERVICE["Service"]
|
||||
GW["Gateway"]
|
||||
POL["Policy"]
|
||||
end
|
||||
|
||||
subgraph REPO["lib/Repository/"]
|
||||
REP["Repository"]
|
||||
end
|
||||
|
||||
subgraph pages["pages/**"]
|
||||
ACT["Action (*.php)"]
|
||||
VIEW["View (*.phtml)"]
|
||||
end
|
||||
|
||||
subgraph TPL["templates/"]
|
||||
LAY["Layouts & Partials"]
|
||||
end
|
||||
|
||||
DB[(MariaDB)]
|
||||
|
||||
DI -->|"ruft zur Laufzeit"| FAC
|
||||
FAC -->|"erzeugt"| SERVICE
|
||||
FAC -->|"erzeugt"| GW
|
||||
|
||||
Browser --> ACT
|
||||
ACT -->|"Input · AuthZ · Response"| SERVICE
|
||||
ACT --> POL
|
||||
ACT --> VIEW
|
||||
VIEW --> LAY
|
||||
SERVICE --> GW
|
||||
GW --> REP
|
||||
SERVICE --> REP
|
||||
REP --> DB
|
||||
```
|
||||
|
||||
## Request-Flow
|
||||
|
||||
1. `web/index.php` bootstrappt Routing/Konfiguration und initialisiert den `AppContainer`.
|
||||
|
||||
@@ -95,6 +95,45 @@ Hinweise:
|
||||
- `order` nur bekannte Sort-Key-Spalten
|
||||
- Bei Search-/Filter-Änderung wird auf Seite 1 zurückgesetzt.
|
||||
|
||||
### Row Interaction (Globaler Standard)
|
||||
|
||||
Listen mit `rowDblClick.getUrl(...)` nutzen standardmäßig eine zugängliche Row-Interaktion:
|
||||
|
||||
- sichtbare Action-Spalte rechts (`Open`/`Edit`)
|
||||
- Doppelklick bleibt als Fallback aktiv
|
||||
- `Enter` auf fokussierter Zeile navigiert zur selben URL
|
||||
|
||||
Optionale Konfiguration über `createServerGrid(...)`:
|
||||
|
||||
```js
|
||||
createServerGrid({
|
||||
// ...
|
||||
rowDblClick: {
|
||||
getUrl: (rowData) => new URL(`admin/users/edit/${rowData?.cells?.[1]?.data}`, appBase).toString(),
|
||||
},
|
||||
rowInteraction: {
|
||||
enabled: true,
|
||||
showActionButton: true,
|
||||
keepDblClick: true,
|
||||
enableEnterOnRow: true,
|
||||
actionColumnLabel: 'Actions',
|
||||
resolveActionLabel: (url) => (url.includes('/edit/') ? 'Edit' : 'Open'),
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Defaults:
|
||||
|
||||
- `rowInteraction.enabled`: `true`, wenn `rowDblClick.getUrl` vorhanden ist
|
||||
- `showActionButton`: `true`
|
||||
- `keepDblClick`: `true`
|
||||
- `enableEnterOnRow`: `true`
|
||||
- `actionColumnLabel`: `language.actions.column` oder `'Actions'`
|
||||
|
||||
Hinweis:
|
||||
|
||||
- Falls eine Seite `actions.enabled: true` explizit setzt, wird keine zusätzliche automatische Row-Action-Spalte injiziert.
|
||||
|
||||
### Filter UX 2.0 (Globaler Standard)
|
||||
|
||||
Für Listen gilt standardmäßig:
|
||||
@@ -275,5 +314,5 @@ Prüfen im Browser:
|
||||
|
||||
1. DevTools öffnen (Console, optional Preserve log aktivieren).
|
||||
2. Kernseiten laden (`/admin/users`, `/address-book`, Audit-Listen).
|
||||
3. Filter setzen/zurücksetzen, Doppelklick-Navigation und Bulk-Aktionen testen.
|
||||
3. Filter setzen/zurücksetzen, Row-Action-Button + Enter + Doppelklick sowie Bulk-Aktionen testen.
|
||||
4. Erwartung: keine JavaScript-Errors und keine Unhandled Promise Rejections.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# lib-Standards
|
||||
|
||||
Letzte Aktualisierung: 2026-03-03
|
||||
Letzte Aktualisierung: 2026-03-05
|
||||
|
||||
Praktische Regeln nur für `lib/**`. Ergänzt `docs/architektur.md`.
|
||||
|
||||
@@ -9,12 +9,17 @@ Praktische Regeln nur für `lib/**`. Ergänzt `docs/architektur.md`.
|
||||
- Verantwortlich für SQL, Filter, Paging und Mapping.
|
||||
- Keine HTTP-, Session-, Redirect- oder Policy-Logik.
|
||||
|
||||
## 2) Service-Regeln
|
||||
## 2) Service-Schicht im Detail
|
||||
|
||||
`lib/Service/` enthält vier klar getrennte Typen — jeder hat eine eigene Verantwortung:
|
||||
|
||||
### 2a) Service (`*Service.php`)
|
||||
|
||||
- Verantwortlich für Fachlogik und Orchestrierung.
|
||||
- Koordiniert Repositories und Gateways; enthält Business-Regeln und Validierung.
|
||||
- Keine Superglobals (`$_POST`, `$_GET`, `$_SESSION`).
|
||||
- Keine Header- oder Redirect-Ausgabe.
|
||||
- Keine direkten `DB::...`-Aufrufe im Service.
|
||||
- Keine direkten `DB::...`-Aufrufe.
|
||||
- Abhängigkeiten per Constructor Injection.
|
||||
- DB-Locks und Transaktionen über Repository-Schicht (z. B. `DatabaseSessionRepository`).
|
||||
- Audit-Hooks für fachliche Schreibaktionen laufen in Services (`SystemAuditService`), nicht in Templates.
|
||||
@@ -22,6 +27,28 @@ Praktische Regeln nur für `lib/**`. Ergänzt `docs/architektur.md`.
|
||||
- Scheduler-Run-/Job-Ereignisse werden zentral im `SchedulerRunService` in `SystemAuditService` geschrieben.
|
||||
- CLI-System-Audit für zentrale Commands wird am Entrypoint (`bin/**`) geschrieben, mit minimaler Metadata (ohne Argumentwerte).
|
||||
|
||||
### 2b) Gateway (`*Gateway.php`)
|
||||
|
||||
- Adapter-Schicht: kapselt eine einzelne externe Abhängigkeit für Services.
|
||||
- Typische Abhängigkeiten: ein Repository, Settings-Zugriff, externe HTTP-APIs, Scope-Daten.
|
||||
- Kein Fach-Orchestrierungsfluss — ein Gateway löst genau eine Infrastruktur-Frage.
|
||||
- Beispiele: `AuthPermissionGateway` (Permission-Lookup), `UserSettingsGateway` (Settings-Zugriff), `OidcHttpGateway` (externe OIDC-API).
|
||||
- Abhängigkeiten per Constructor Injection; keine direkten `new ...Repository()` außerhalb von Factories.
|
||||
|
||||
### 2c) Factory (`*Factory.php` / `*ServicesFactory.php` / `*GatewayFactory.php`)
|
||||
|
||||
- Einzige erlaubte Stelle für `new ...Service()`, `new ...Gateway()`, `new ...Repository()` innerhalb von `lib/Service/`.
|
||||
- Erzeugt konfigurierte Service-/Gateway-Gruppen für den DI-Container.
|
||||
- Keine Fachlogik; reine Kompositions-Helfer.
|
||||
- Werden im Composition Root (`lib/App/registerContainer.php`) registriert.
|
||||
|
||||
### 2d) Policy (`*Policy.php` / `*AuthorizationPolicy.php`)
|
||||
|
||||
- Liegen in `lib/Service/Access/`.
|
||||
- Treffen Authorization-Entscheidungen (Ability-Checks) für einen bestimmten Ressourcentyp.
|
||||
- Geben `AuthorizationDecision` zurück; kein HTTP-Redirect, keine Fachlogik.
|
||||
- Werden über `AccessPolicyFactory` + `AuthorizationService` aufgelöst — nie direkt in Actions instanziiert.
|
||||
|
||||
## 3) Instanziierung
|
||||
|
||||
- Composition Root ist `web/index.php` + `lib/App/registerContainer.php`
|
||||
|
||||
Reference in New Issue
Block a user