1
0

feat: extend module platform with UI slots, runtime components, CLI tooling and {{userId}} search support

Completes the generic module platform that enables modules to contribute
UI elements, runtime JS components, and search resources without any
core hardcoding.

New generic UI slot types:
- topbar.right_item: module-contributed topbar buttons
- layout.body_end_template: module-contributed dialog/overlay templates
- layout.head_style: module-contributed global CSS
- runtime.component: declarative JS component registration with phase ordering

New infrastructure:
- ModuleAutoloader: PSR-4 autoloading for module-local PHP classes
- ModuleRuntimePageBuilder: symlinks module pages into runtime directory
- ModuleRuntimeAssetPublisher: publishes module CSS/JS to web/modules/
- ModulePermissionSynchronizer: syncs module permissions to DB
- CLI scripts: module-runtime-sync, module-build, module-migrate,
  module-permissions-sync, module-assets-sync
- {{userId}} placeholder in SearchDataService for user-scoped search queries
- Component runtime with phased initialization (early/default/late)
- AppContainer.protectExistingBindings() to prevent module→core overwrites
- Architecture tests: ModuleStructureContractTest, CoreTemplateIsolationTest,
  FrontendComponentRuntimeContractTest, AppContainerIsolationContractTest

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-18 22:19:56 +01:00
parent c364e2b46d
commit c7b8fd516a
139 changed files with 7591 additions and 2535 deletions

View File

@@ -1,6 +1,6 @@
# Frontend JavaScript
Letzte Aktualisierung: 2026-03-06
Letzte Aktualisierung: 2026-03-18
## Ordnerstruktur
@@ -18,7 +18,7 @@ Letzte Aktualisierung: 2026-03-06
- setzt früh UI-States (no-js/js, Sidebar-/Contrast-LocalStorage)
- `/web/js/app-init.js`
- Modul-Entrypoint für Standardseiten
- importiert Komponenten zentral
- initialisiert Runtime + globale Komponenten zentral
- `/web/js/app-login-init.js`
- reduzierter Entrypoint für Loginseiten
@@ -30,6 +30,34 @@ Empfohlenes Muster:
2. Früher Guard auf fehlende Elemente
3. Keine stillen Fehler verschlucken
4. Nur DOM/UI-Verhalten, keine Fachlogik
5. Lifecycle-Contract für Runtime-Komponenten: `init(root, config)` gibt API mit `destroy()` zurück
6. Runtime-Komponenten dürfen keinen eigenen Auto-Init via `DOMContentLoaded`/Sideeffect enthalten
## Component Runtime (Restmigration)
- Zentrale Runtime: `web/js/core/app-component-runtime.js`.
- Runtime-Page-Configs:
- Standardseiten: `<script type="application/json" id="page-config-app-components">...</script>`
- Loginseiten: `<script type="application/json" id="page-config-login-components">...</script>`
- Runtime liest Config über `readPageConfig(...)` und mountet registrierte Komponenten pro Entrypoint:
- `web/js/app-init.js` (default)
- `web/js/app-login-init.js` (login)
- Komponenteninterner Contract:
- Init-Signatur: `initX(root, config)`
- Rueckgabe: `{ destroy() }`
- `destroy()` muss alle Listener/Timer/Observer abbauen.
- Hybrid Host-Policy:
- Host-gebundene UI-Komponenten nutzen explizite `data-app-component`-Hosts im Markup.
- Tabs sind host-gebunden und laufen ausschliesslich ueber `data-app-component="tabs"`.
- Globale Utilities ohne natuerliches Host-Element werden runtime-global (`scope: 'global'`) registriert, aber mit demselben Lifecycle-Contract.
- Root-Strict gilt fuer host-gebundene Komponenten: keine `document.querySelector`-Fallback-Pfade.
- Projektseitige Custom-Globals auf `window.*` sind verboten; Komponenten kommunizieren ueber Core-Channels.
## UI Storage Contract
- Persistente UI-States laufen fuer Runtime-Komponenten ueber `web/js/core/app-ui-storage.js`.
- Storage-Keys sind namespaced (`namespace:version:scope:*`) statt ungeordnet verteilt.
- Hard-Cut-Policy: keine Legacy-Key-Fallbacks und kein Legacy-Key-Sync in migrierten Runtime-Komponenten/Core-Modulen.
Template für neue Komponenten:
@@ -257,7 +285,7 @@ Für Create/Edit-Detailseiten gilt:
- Hauptformular über `data-standard-detail-form="1"` explizit opt-in markieren.
- Initialisierung läuft zentral über `initStandardDetailPage(...)` aus `web/js/core/app-detail-page-factory.js`.
- Auto-Init erfolgt über `web/js/components/app-standard-detail-page.js` (in `app-init.js` eingebunden).
- Runtime-Init erfolgt über `web/js/app-init.js` (Komponente `standard-detail-page`).
Standardverhalten: