Repo Interface für tests

This commit is contained in:
2026-03-05 08:26:51 +01:00
parent 8f4dd5840d
commit 4b31fc7664
171 changed files with 3518 additions and 2297 deletions

View File

@@ -1,6 +1,6 @@
# Architektur-Kompass
Letzte Aktualisierung: 2026-02-25
Letzte Aktualisierung: 2026-03-04
## Ziel
@@ -34,8 +34,10 @@ Verbindliche Kurzregeln für Architekturentscheidungen.
- In `pages/admin/**` keine `Factory::class`-Referenzen.
- Request-Input in Actions nur über `requestInput()` lesen.
- Validierungsfehler über `FormErrors` führen und für APIs mit `ApiResponse::validationFromFormErrors(...)` ausgeben.
- In `pages/api/v1/**` kein direktes JSON-Body-Lesen über `ApiResponse::readJsonBody(...)`.
- `Flash` nur für Redirect-/Outcome-Meldungen verwenden, nicht als primäre Validation-Struktur.
- Listen-Endpoints in `pages/**/data().php` sind GET-only (`gridRequireGetRequest()`).
- Query-Filter in `data().php` über `gridParseFilters(...)` + `filter-schema.php` normalisieren.
- Grid-Query-Parameter (`limit`, `offset`, `order`, `dir`) in `data().php` über `gridQueryLimitOffset()` und `gridQueryOrderDir()` normalisieren.
## Instanziierungsregeln (MUSS)
@@ -61,6 +63,13 @@ Verbindliche Kurzregeln für Architekturentscheidungen.
- Für einzelne Views setzen Actions explizit `$viewAuth['page']` (bevorzugt über `UiCapabilityMap` + `UiAccessService::pageCapabilities()`).
- In `templates/**` keine direkten `can('...')`- oder Permission-Key-Checks.
## Frontend-Page-Module (MUSS)
- In `pages/**` und `templates/**` sind inline `<script type="module">...</script>` ohne `src` verboten.
- Seiteninitialisierung liegt in dedizierten ESM-Page-Modulen unter `web/js/pages/*`.
- Pro Seite wird Konfiguration per `<script type="application/json" id="page-config-<page-key>">...</script>` bereitgestellt und im Modul über `readPageConfig(...)` gelesen.
- In `pages/**` und `templates/**` muessen alle JS-`src` (eigene und Vendor) ueber `assetVersion('...js...')` laufen.
## Mindestchecks vor Merge
```bash
@@ -80,6 +89,7 @@ Struktur-Gates zusätzlich:
(rg -n '\bDB::' pages -g '*.php' || true) | wc -l
(rg -n 'app\([^\n]*Factory::class\)->create' pages/admin -g '*.php' || true) | wc -l
(rg -n 'Factory::class' pages/admin -g '*.php' || true) | wc -l
(rg -n 'ApiResponse::readJsonBody\(' pages/api/v1 -g '*.php' || true) | wc -l
```
Architektur-Contract:

View File

@@ -38,6 +38,9 @@ Kurze Definition of Done vor Merge.
- [ ] Aktive Filter-Chips vorhanden (`data-active-filter-chips`) und Remove/Clear funktionieren
- [ ] Kein Legacy-Toggle in Listen (`data-toolbar-toggle`, `data-filter-overflow`, `data-filter-toggle`)
- [ ] Falls Save-Filter vorhanden: gespeicherter Zustand stammt aus Applied State (`gridConfig.baseUrl()`)
- [ ] Keine inline `<script type="module">`-Blöcke in `pages/**`/`templates/**`; Seitenlogik liegt in `web/js/pages/*`
- [ ] Für Seitenmodule ist Config über `<script type="application/json" id="page-config-...">` bereitgestellt
- [ ] JS-`src` in `pages/**`/`templates/**` nur über `assetVersion('...js...')`
- [ ] Service-Auflösung in `pages/**`/`templates/**`/`lib/Support/**` nur via `app(Foo::class)`
- [ ] Keine `new ...Factory()` in `lib/Service/**` außerhalb `*Factory.php`
- [ ] Keine direkten `new ...Service()`, `new ...Gateway()`, `new ...Repository()` in `lib/Service/**` außerhalb `*Factory.php`
@@ -52,6 +55,7 @@ Kurze Definition of Done vor Merge.
- [ ] Keine sensiblen Daten in Fehlern/Logs
- [ ] Für `pages/**/data().php`: GET-only + Query-Normalisierung (`gridRequireGetRequest`, `gridParseFilters`)
- [ ] Für `pages/**/data().php`: Filter über `gridParseFilters(...)` statt Inline-Parsing
- [ ] Für `pages/api/v1/**`: kein `ApiResponse::readJsonBody(...)`, Input nur über `requestInput()`
- [ ] Bei MultiSelect-Filtern: CSV-Query (`foo=a,b`) + serverseitige `IN`-Filter mit Limit
- [ ] Keine Listen-Alias-Keys (`*_id` neben `*_ids`) neu einführen
- [ ] Input nur über `requestInput()` und Validation über `FormErrors` (`/docs/request-input-validation.md`)

View File

@@ -33,7 +33,18 @@ Empfohlenes Muster:
Template für neue Komponenten:
- `/web/js/components/_template.js`
- bestehende Komponenten als Referenz verwenden (`/web/js/components/*.js`)
## Page Module Contract (Hard Cut)
Für seitenbezogene Initialisierung gilt verbindlich:
- Kein inline `<script type="module">` in `pages/**` oder `templates/**`.
- Pro Seite genau ein externes Modul unter `web/js/pages/*` laden.
- Serverseitige Daten für dieses Modul über
`<script type="application/json" id="page-config-...">...</script>` bereitstellen.
- Page-Module lesen Config zentral über `readPageConfig(...)` aus `web/js/core/app-page-config.js`.
- JS-`src` in `pages/**` und `templates/**` nur über `assetVersion('...js...')`.
## Defensive DOM-Nutzung