Files
breadcrumb-the-shire/docs/reference-module-manifest-contract.md
fs c7b8fd516a 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>
2026-03-18 22:19:56 +01:00

3.3 KiB

Module Manifest Contract (V1.1)

Letzte Aktualisierung: 2026-03-18

Ziel

Verbindlicher Contract fuer modules/*/module.php, damit Module zur Runtime deterministisch geladen und validiert werden.

Status

Dieses Dokument ist die kanonische (normative) Quelle fuer Manifest-, Runtime- und Guard-Regeln des Modul-Systems. /docs/reference-extension-readiness.md referenziert diesen Contract und dupliziert keine Felddefinitionen.

Aktivierung (APP_ENABLED_MODULES)

  • nicht gesetzt: config/modules.php gilt.
  • gesetzt und leer (APP_ENABLED_MODULES=''): keine Module.
  • gesetzt mit Liste (APP_ENABLED_MODULES='a,b'): exakt diese Module.

permissions Contract

permissions ist eine Objektliste:

'permissions' => [
    [
        'key' => 'module.permission',
        'description' => 'Human readable text',
        'active' => true,      // optional, default true
        'is_system' => true,   // optional, default true
    ],
],
  • key und description sind Pflichtfelder.
  • Runtime-Sync erfolgt ueber php bin/module-permissions-sync.php.
  • module-runtime-sync fuehrt diesen Sync automatisch aus.

scheduler_jobs Contract

scheduler_jobs ist eine Objektliste mit vollem Default-Contract:

'scheduler_jobs' => [
    [
        'job_key' => 'module.job',
        'handler' => App\\Scheduler\\MyJobHandler::class,
        'label' => 'Job label',
        'description' => 'Job description',
        'default_enabled' => true,
        'default_timezone' => 'Europe/Berlin',
        'default_schedule_type' => 'daily', // hourly|daily|weekly
        'default_schedule_interval' => 1,
        'default_schedule_time' => '02:00', // required for daily/weekly
        'default_schedule_weekdays_csv' => null, // weekly: e.g. '1,3,5'
        'default_catchup_once' => true,
        'allowed_schedule_types' => ['daily', 'weekly'],
    ],
],
  • Manifest ist Source of Truth fuer Job-Metadaten und Defaults.
  • Handler werden zur Laufzeit container-resolvable fuer execute(...) geladen.

ui_slots Contract (V1.2)

Neue generische Slot-Typen:

  • topbar.right_item: { key, template, permission?, order }
  • layout.body_end_template: { key, template, permission?, order }
  • layout.head_style: { key, path, permission?, order }
  • runtime.component: { key, script, export?, selector?, scope?, config_path?, default_config?, phase?, permission?, order }

runtime.component.phase ist early|default|late (Default: late).

Abgrenzung CSS:

  • layout.head_style = global auf allen Seiten.
  • asset_groups = seiten-/kontextbezogen ueber style_groups.

Guard-Regeln

  • Route-Kollisionen sind fail-fast:
    • Modul vs Modul auf target und path.
    • Modul vs Core auf path beim Router-Boot.
  • Layout-Provider duerfen reservierte Core-Keys nicht ueberschreiben (moduleSlots, csrfKey, currentTenant, ...).
  • Layout-Provider-Top-Level-Keys muessen namespaced sein (<module_id>.<key>).

Standard-Runbook

php bin/module-runtime-sync.php fuehrt in fester Reihenfolge aus:

  1. module-migrate
  2. module-permissions-sync
  3. module-build
  4. module-assets-sync

Der Output enthaelt eine deterministische Step-Summary (migrate, permissions-sync, build, assets-sync) inklusive vendor_warnings_ignored=<n>. First-party Warnings/Notices/Deprecations gelten als Fehler (fail-fast).