# MOSAIC Config Spezifikation

## Zweck

Dieses Dokument ist die oeffentliche und verbindliche Konfigurations-Spezifikation fuer MOSAIC-Module, wenn kein Zugriff auf den geschuetzten Kerncode besteht.

Die Datei ist fuer Menschen und KI-Systeme gedacht, die Konfigurationsdateien korrekt erzeugen muessen.

Stand:

- Kernstand April 2026

Diese Spezifikation deckt verbindlich ab:

- `*_form.cfg`
- `*_grid.cfg`
- `*_egrid.cfg`

Weitere Modultypen werden ueber eigene Entwicklerdokumentationen im MOSAIC-Ordner beschrieben.

Wichtige Abgrenzung:

- projektweite Security und projektweites Logging werden in `mosaic_config.lic` gesteuert
- einzelne Runner koennen zusaetzlich `security => false` setzen, um die Rechtepruefung fuer genau diesen Runner gezielt auszuschalten
- der Login setzt nur Benutzer-, Rollen- und Projektkontext; die verbindliche Modulpruefung erfolgt beim Aufruf des jeweiligen Runners
- die zentrale Runner-Pruefung gilt fuer Grid, Form, eGrid, Menue, Forum, Dashboard, Report, Chart, Calendar, Connector, PayPal und API
- `xls_export.php` und `pdf_export.php` pruefen das Export- beziehungsweise Druckrecht des zugehoerigen Grids

## 1. Allgemeine Regeln

### 1.1 Dateiformat

MOSAIC-Konfigurationen sind PHP-Dateien, die ein Array zurueckgeben:

```php
<?php

return [
    // Konfiguration
];
```

### 1.2 Dateinamen und Runner

- `*_form.cfg` -> `_pgm/form.php`
- `*_grid.cfg` -> `_pgm/grid.php`
- `*_egrid.cfg` -> `_pgm/show_egrid.php`
- `*_report.cfg` -> `_pgm/show_report.php`
- `*_forum.cfg` -> `_pgm/show_forum.php`
- `*_chart.cfg` -> `_pgm/show_chart.php`
- `*_connector.cfg` -> `_pgm/show_connector.php`
- `*_paypal.cfg` -> `_pgm/show_paypal.php`
- `*_menu.cfg` -> `_pgm/show_menu.php`
- `*_v_menu.cfg` -> `_pgm/show_v_menu.php`

Legacy-Runner duerfen fuer neue Module nicht mehr verwendet werden.

### 1.3 Hook-Dateien

Wenn zu einer Konfigurationsdatei Programmlogik gehoert, lautet der Dateiname:

- `xyz_form.cfg` -> `xyz_form_function.php`
- `xyz_grid.cfg` -> `xyz_grid_function.php`
- `xyz_egrid.cfg` -> `xyz_egrid_function.php`

### 1.4 Primary Key

`primary_key` wird in MOSAIC immer als Array gepflegt, auch bei einem einzelnen Feld.

Richtig:

```php
'primary_key' => ['kunde_id'],
```

Nicht bevorzugt:

```php
'primary_key' => 'kunde_id',
```

### 1.5 Datenbankdialekte

Fuer `form` und `grid` sind diese Dialekte vorgesehen:

- `mysql`
- `pgsql`
- `oracle`
- `sqlite`

Wichtige Regel:

- PostgreSQL wird nur noch als `pgsql` konfiguriert
- Oracle wird nur noch als `oracle` konfiguriert
- Versionsangaben wie `postgresql_16`, `postgresql_18`, `oracle 12c` oder aehnliche Varianten duerfen in neuen Konfigurationen nicht mehr verwendet werden

Fuer `egrid` wird statt `db_typ` die Verbindung ueber `connection` angegeben.

## 1.3 Gemeinsame Titel-Darstellung

Die Runner `grid`, `form`, `egrid` und `show_chart` unterstuetzen eine gemeinsame Titel-Darstellung.
Ohne Angabe werden Standards gesetzt:

- Schriftart: `inherit`
- Schriftgroesse: runnerabhaengiger Standard
- Schriftgewicht: `600`
- Vordergrundfarbe: Bootstrap-Body-Farbe
- Hintergrundfarbe: `transparent`

Zulaessige Konfiguration:

```php
'title_size' => 'sm', // xs | sm | md | lg | xl
'title_style' => [
    'font-family' => 'Arial, sans-serif',
    'font-size' => '1.1rem',
    'font-weight' => '700',
    'color' => '#0d6efd',
    'background-color' => 'transparent',
],
```

Alternativ sind diese direkten Schluessel erlaubt:

- `title_font_family`
- `title_font_size`
- `title_font_weight`
- `title_color` oder `title_foreground`
- `title_background` oder `title_background_color`
- `title_padding`
- `title_margin`

Die direkten Schluessel duerfen alternativ auch deutsch benannt werden:

- `title_schriftart`
- `title_schriftgroesse` oder `title_schriftgröße`
- `title_schriftgewicht`
- `title_vordergrundfarbe`
- `title_hintergrundfarbe`

Die Style-Werte laufen durch eine Whitelist. Nicht erlaubte CSS-Eigenschaften, `url(...)`, `javascript:` und `expression(...)` werden ignoriert.

## 2. Verbindliche Spezifikation fuer `*_form.cfg`

### 2.1 Standard-Top-Level

Der verbindliche Standard fuer neue Form-Module ist:

- `limit`
- `width`
- `title`
- `db_typ`
- `table`
- `query`
- `marker`
- `primary_key`
- `autoincrement`
- `transaction`
- `sequence_name`
- `tabs`
- `permissions`

Optional ist auf Runner-Ebene ebenfalls zulaessig:

- `security`

Davon sind fuer ein normales CRUD-Formular praktisch erforderlich:

- `title`
- `db_typ`
- `table`
- `primary_key`
- `tabs`

Hinweise:

- `query` ist das Lese-SQL fuer die Formularanzeige
- Schreiboperationen laufen weiterhin gegen `table`
- `transaction` ist optional
- `sequence_name` ist optional und vor allem fuer Oracle relevant
- `permissions` verwendet im Standard die Schluessel `add`, `view`, `update`, `delete`, `copy`
- `security => false` schaltet die Rechtepruefung fuer genau dieses Formular aus, falls das Projekt global Security aktiviert hat

### 2.2 Standardstruktur

```php
<?php

return [
    'limit' => 100,
    'width' => '85%',
    'title' => 'Beispiel',
    'db_typ' => 'mysql',
    'table' => 'beispiel',
    'query' => 'SELECT `beispiel_id`, `bezeichnung` FROM `beispiel`',
    'marker' => true,
    'primary_key' => ['beispiel_id'],
    'autoincrement' => true,
    'transaction' => false,
    'security' => true,
    'tabs' => [
        'TAB_1' => [
            'label' => 'Stammdaten',
            'title_display' => true,
            'label_display' => true,
            'position' => 'beside',
            'columns' => 2,
            'next' => 'tabs',
            'width' => '100%',
            'collapse' => 'expanded',
            'fields' => [
                'bezeichnung' => [
                    'label' => 'Bezeichnung',
                    'type' => 'text',
                    'required' => true,
                    'input_length' => 100,
                ],
            ],
        ],
    ],
    'permissions' => [
        'add' => true,
        'view' => true,
        'update' => true,
        'delete' => true,
        'copy' => true,
    ],
];
```

### 2.3 Tab-Schluessel

Jeder Eintrag in `tabs` ist ein Array mit diesen Standardschluesseln:

- `label`
- `title_display`
- `label_display`
- `position`
- `columns`
- `next`
- `width`
- `collapse`
- `fields`

Optional zulaessig:

- `hidden`
- `label_position`

Empfohlener Standard:

- `position` = `beside`
- `columns` = `1`, `2` oder `3`
- `width` = `100%`
- `collapse` = `expanded`

### 2.4 Feldtypen und erlaubte Feldparameter

Jedes Feld unter `tabs[*]['fields']` verwendet mindestens:

- `label`
- `type`

Unterstuetzte Feldtypen:

- `text`
- `text_multiline`
- `integer`
- `decimal`
- `date`
- `datetime`
- `checkbox`
- `select`
- `radio`
- `file_upload_to_path`

Erlaubte Zusatzparameter pro Typ:

- `text`
  - `tooltip`, `input_length`, `required`, `hidden_on_insert`, `hidden_on_update`, `readonly_on_insert`, `readonly_on_update`, `default_on_insert`
- `text_multiline`
  - `tooltip`, `input_length`, `required`, `hidden_on_insert`, `hidden_on_update`, `readonly_on_insert`, `readonly_on_update`, `default_on_insert`
- `integer`
  - `tooltip`, `input_length`, `required`, `hidden_on_insert`, `hidden_on_update`, `readonly_on_insert`, `readonly_on_update`, `default_on_insert`
- `decimal`
  - `tooltip`, `input_length`, `required`, `hidden_on_insert`, `hidden_on_update`, `readonly_on_insert`, `readonly_on_update`, `default_on_insert`
- `date`
  - `tooltip`, `input_length`, `required`, `show_calendar`, `hidden_on_insert`, `hidden_on_update`, `readonly_on_insert`, `readonly_on_update`, `default_on_insert`
- `datetime`
  - `tooltip`, `input_length`, `required`, `show_calendar`, `hidden_on_insert`, `hidden_on_update`, `readonly_on_insert`, `readonly_on_update`, `default_on_insert`
- `checkbox`
  - `tooltip`, `required`, `hidden_on_insert`, `hidden_on_update`, `readonly_on_insert`, `readonly_on_update`, `default_on_insert`, `input_length`
- `select`
  - `tooltip`, `input_length`, `required`, `hidden_on_insert`, `hidden_on_update`, `readonly_on_insert`, `readonly_on_update`, `default_on_insert`, `lookup_method`, `lookup_label`, `lookup_value`, `delimiter`, `lookup_sql`, `lookup_conn`, `multiple_values`, `db_rows`
- `radio`
  - `tooltip`, `required`, `hidden_on_insert`, `hidden_on_update`, `readonly_on_insert`, `readonly_on_update`, `default_on_insert`, `lookup_method`, `lookup_label`, `lookup_value`, `delimiter`, `lookup_sql`, `lookup_conn`, `radio_layout`, `radio_empty`, `radio_empty_label`
- `file_upload_to_path`
  - `tooltip`, `required`, `hidden_on_insert`, `hidden_on_update`, `path_to_store`, `allowed_extension`, `max_size_in_kb`

Feld-AJAX:

- Jedes Feld darf optional einen `ajax`-Block definieren.
- `handler` ist der Name der Hook-Funktion in der `*_function.php`.
- `trigger` ist optional und kann `change`, `blur` oder `input` sein. Standard ist `change`.
- `ajax_message` ist optional. Wenn gesetzt, wird der Text waehrend des laufenden AJAX-Requests neben dem Feld angezeigt und automatisch mit `deepl_translate()` behandelt.
- Bei jedem Feld-AJAX zeigt der Runner immer einen Spinner. Fehlt `ajax_message`, wird nur der Spinner angezeigt.
- Es gibt keine alternativen Schluessel fuer `ajax_message`.

Beispiel:

```php
'ajax' => [
    'handler' => 'example_ajax_handler',
    'trigger' => 'change',
    'ajax_message' => 'Daten werden geprueft',
],
```

### 2.5 Lookup-Regeln fuer `select` und `radio`

`select`- und `radio`-Felder verwenden in der Praxis zwei Modi:

- `lookup_method` = `manual`
- `lookup_method` = `automatic`

Bei `manual` werden `lookup_label` und `lookup_value` verwendet.

Bei `automatic` wird `lookup_sql` verwendet.

Optional:

- `lookup_conn` fuer eine alternative Verbindung
- `multiple_values` fuer Mehrfachauswahl bei `select`
- `delimiter` fuer die Speicherung mehrerer Werte in einem Feld
- `db_rows` fuer die sichtbare Hoehe der Mehrfachauswahl
- `radio_layout` = `vertical` fuer vertikale Radio-Listen
- `radio_empty` und `radio_empty_label` fuer eine optionale Leerauswahl bei `radio`

### 2.6 Transaktionen

`transaction` ist ein boolescher Konfigurationsschluessel.

### 2.7 Runner-Security

Fuer `form` und `grid` ist optional dieser Schluessel zulaessig:

```php
'security' => false,
```

Bedeutung:

- `true` oder nicht gesetzt:
  Runner folgt der projektweiten Security aus `mosaic_config.lic`
- `false`:
  dieser Runner ignoriert die Rollenrechte bewusst

Der Schluessel ist nur fuer gezielte Sonderfaelle gedacht, zum Beispiel:

- oeffentliche Einstiegsseiten
- technische Hilfsseiten
- bewusst freigegebene Menuezielseiten

Aktueller Kernstand:

- `mysql` aktiviert Formular-Transaktionen nur bei InnoDB
- `pgsql` aktiviert Formular-Transaktionen direkt
- `oracle` aktiviert Formular-Transaktionen direkt
- `sqlite` ist in diesem Bereich nicht der freigegebene Standardpfad

### 2.7 Primary-Key-Erzeugung bei Oracle

Fuer Oracle gibt es zwei vorgesehene Wege:

- `sequence_name` als einfacher Komfortpfad fuer `SELECT <sequence>.NEXTVAL FROM dual`
- eigene PK-Logik in `onBeforeInsert`

Wenn ein Projekt eine Oracle-spezifische Funktion oder ein Package fuer die PK-Erzeugung verwenden will, soll dies ueber `onBeforeInsert` erfolgen.

### 2.8 Form-Hooks

Moegliche Hook-Namen in `*_form_function.php`:

- `onApplicationInit(&$context)`
- `onCheckSecurity(&$context, &$formConfig)`
- `onLoad(&$context, &$formConfig)`
- `onValidate(&$context, &$postData, $currentId)`
- `onValidateSuccess(&$context, &$postData, $currentId)`
- `onValidateFailure(&$context, &$postData, $currentId, &$invalid, &$message)`
- `onBeforeInsert(&$context, &$postData, $currentId)`
- `onAfterInsert(&$context, &$postData, $newId)`
- `onBeforeUpdate(&$context, &$postData, $currentId)`
- `onAfterUpdate(&$context, &$postData, $currentId)`
- `onBeforeDelete(&$context, &$postData, $currentId)`
- `onAfterDelete(&$context, &$postData, $currentId)`
- `onBeforeRender(&$context, &$renderPayload)`
- `onAfterRender(&$context, &$renderPayload)`

`onValidateSuccess` laeuft nach Pflichtfeld-/Formatpruefung und nach `onValidate`, aber vor Insert/Update/Copy. Der Hook darf `false` oder einen Fehlertext zurueckgeben, um das Speichern noch abzubrechen. `onValidateFailure` laeuft bei fehlgeschlagener Validierung und darf die Feldfehler in `$invalid` sowie die Anzeige in `$message` anpassen.

Fuer `onValidate`, `onValidateSuccess`, `onBeforeInsert`, `onBeforeUpdate` und `onBeforeDelete` darf ein Hook `false` oder einen Fehlertext zurueckgeben, um eine Aktion abzubrechen.

## 3. Verbindliche Spezifikation fuer `*_grid.cfg`

### 3.1 Standard-Top-Level

Der verbindliche Standard fuer neue Grid-Module ist:

- `limit`
- `check_security`
- `width`
- `db_typ`
- `table`
- `title`
- `sql`
- `marker`
- `primary_key`
- `show_new_button`
- `autoincrement`
- `edit_link`
- `advanced_search`
- `debug`
- `move_records`
- `mobile`
- `button_menus`
- `columns`
- `permissions`

Regel:

- `permissions` ist die verbindliche Schreibweise fuer Berechtigungen
- alte Konfigurationen mit `permission` muessen auf `permissions` migriert werden

### 3.2 Standardstruktur

```php
<?php

return [
    'limit' => '10,20,50,100,500',
    'check_security' => 1,
    'width' => '90%',
    'db_typ' => 'mysql',
    'table' => 'beispiel',
    'title' => 'Beispiel',
    'sql' => 'SELECT `beispiel_id`, `bezeichnung`, `active` FROM `beispiel` ORDER BY `bezeichnung`',
    'marker' => true,
    'primary_key' => ['beispiel_id'],
    'show_new_button' => true,
    'autoincrement' => true,
    'edit_link' => 'beispiel',
    'mobile' => [
        'record orientation' => 'vertical',
    ],
    'columns' => [
        'bezeichnung' => [
            'label' => 'Bezeichnung',
            'type' => 'text',
            'quicksearch' => true,
            'sort' => true,
        ],
    ],
    'permissions' => [
        'view' => true,
        'edit' => true,
        'add' => true,
        'copy' => true,
        'delete' => false,
        'xls_export' => true,
        'select_xls_fields' => true,
        'pdf_export' => true,
        'select_pdf_fields' => true,
    ],
];
```

### 3.2.1 Mobile-Ansicht

Fuer Grid-Module kann eine mobile Darstellung konfiguriert werden:

Die vollstaendige Beschreibung der mobilen Ansichten fuer `GRID` und `FORM` steht in:

- `MOSAIC_Mobile_Ansichten.md`
- `MOSAIC_Mobile_Ansichten.docx`

```php
'mobile' => [
    'record orientation' => 'vertical',
],
```

Bedeutung:

- `record orientation = vertical` stellt Datensaetze in der Handyansicht untereinander mit Trennlinie dar
- im Entwicklermodus kann diese Ansicht im Grid ueber das Handy-Symbol oben rechts simuliert werden
- wird aus dieser Handyansicht `Bearbeiten` oder `Neueingabe` geoeffnet, rendert das zugehoerige Formular die Felder ebenfalls einspaltig mit Labels oberhalb der Eingaben

### 3.3 Spaltentypen und erlaubte Spaltenparameter

Jede Spalte unter `columns` verwendet mindestens:

- `label`
- `type`

Unterstuetzte Spaltentypen:

- `text`
- `number`
- `checkbox`
- `date`
- `datetime`
- `html`
- `select`
- `choose_manual`
- `file_upload_to_path`
- `file_blob`
- `image`
- `computed`
- `v_menu`

### 3.3.1 Drag-and-drop-Grids mit `move_records`

Ein Grid kann als Drag-and-drop-Grid betrieben werden, wenn die fachliche Reihenfolge in einem Tabellenfeld gespeichert wird.

Der verbindliche Konfigurationsblock ist:

```php
'move_records' => [
    'enabled' => true,
    'move_table' => 'frage_antworten_formular_nn',
    'move_field' => 'an_reihe',
    'step' => 10,
    'only_within_group' => true,
],
```

Regeln:

- `move_field` ist das verbindliche Reihenfolgefeld.
- Das SQL des Grids darf fuer Drag-and-drop-Grids keine feste Sortierung enthalten, die der Bewegungslogik widerspricht.
- Die Anzeige wird im Grid-Kern automatisch nach `move_field ASC` sortiert.
- Eine andere Sortierung durch URL-Parameter oder Spaltenkopf wird zentral verhindert.
- Wenn eine andere Sortierung angefordert wird, setzt der Grid-Kern automatisch auf das Reihenfolgefeld zurueck und zeigt einen Hinweis an.
- Normale Spaltensortierungen (`sort => true`) gehoeren bei aktivem `move_records` nicht in die Konfiguration.
- Findet der Grid-Kern dennoch sortierbare Spalten, deaktiviert er diese fuer die Anzeige und zeigt einen Hinweis an, damit die Konfigurationsdatei bereinigt werden kann.
- Ist die Konfiguration bereits sauber, erscheint kein allgemeiner Drag-and-drop-Hinweis.
- Der Drag-and-drop-Handle wird aus dem `move_field` erzeugt; eine eigene virtuelle Spalte wie `sort_handle` ist dafuer nicht erforderlich.

Damit ist sichergestellt, dass die sichtbare Reihenfolge immer der gespeicherten fachlichen Reihenfolge entspricht und Verschiebungen sofort nachvollziehbar bleiben.

### 3.3.2 Automatischer Zurueck-Button bei Grid-zu-Grid-Links

Wenn ein Grid ueber einen MOSAIC-/Scriptcase-Link ein anderes Grid oeffnet, kann der Zielaufruf einen expliziten Ruecksprungparameter enthalten:

```text
iss_back_url=<APP_ROOT_URL>_pgm/grid.php?modul=hauptgrid&modul_path=...
```

Der Grid-Kern wertet diesen Parameter zentral aus.

Verhalten:

- Bei Grid-zu-Grid-Links wird `iss_back_url` automatisch durch die Link-Erzeugung gesetzt.
- Im Zielgrid erscheint ein Zurueck-Button mit Tuer-Symbol (`fa-door-open`).
- Der Button steht rechts in der Toolbar direkt vor den Blaetter-Icons.
- Der Parameter wird bei Suche, Paging und Limitwechsel im Zielgrid mitgefuehrt.
- Beim Ruecksprung wird automatisch ein Refresh-Parameter an die Back-URL angehaengt, damit das Hauptgrid frisch geladen wird:

```text
_refresh=<zeitwert>
```

Sicherheitsregeln:

- Es werden nur interne bzw. relative Ruecksprung-URLs akzeptiert.
- Absolute externe URLs, Protokoll-URLs und URLs mit Steuerzeichen werden verworfen.
- Ohne gueltigen `iss_back_url` wird kein Zurueck-Button angezeigt.

Damit bleiben Detailgrids rueckwaerts navigierbar, ohne pro Grid einen manuellen Zurueck-Button konfigurieren zu muessen.

### 3.3.3 User-defined Grid-Buttons mit AJAX-Spinner

Grid-Buttons unter `button_menus` koennen normal per POST oder optional per AJAX ausgefuehrt werden. Fuer laengere Aktionen wie Berechnungen, PDF-Erzeugung, Mailversand, Import, Export oder Buchungslaufe kann der Grid-Kern einen zentralen Spinner anzeigen.

Beispiel:

```php
'button_menus' => [
    'aktionen' => [
        'label' => 'Aktionen',
        'buttons' => [
            'berechnung' => [
                'label' => 'Berechnung starten',
                'call_function' => 'beispiel_berechnung_starten',
                'confirm' => 'Berechnung jetzt starten?',
                'ajax' => true,
                'spinner_text' => 'Bitte warten .. Berechnung laeuft',
                'spinner_reload' => true,
                'spinner_block_ui' => true,
                'timeout_seconds' => 300,
            ],
        ],
    ],
],
```

Parameter:

- `ajax`: Wenn `true`, ruft der Button die `call_function` per AJAX auf. Ohne `ajax` bleibt das bisherige POST-Verhalten unveraendert.
- `spinner_text`: Text im zentralen Spinner-Overlay. Ohne Angabe wird `Bitte warten ...` verwendet.
- `spinner_reload`: Wenn `true`, laedt der Grid-Kern nach erfolgreicher AJAX-Aktion das Grid neu.
- `spinner_block_ui`: Wenn `true`, blockiert das Overlay die Oberflaeche waehrend der Aktion. Bei `false` bleibt die Seite trotz sichtbarem Spinner anklickbar.
- `timeout_seconds`: Setzt fuer genau diesen Button-Request temporaer `set_time_limit()` und `max_execution_time`. Ohne Angabe bleibt das normale PHP-Timeout gueltig.

Die `call_function` bleibt eine normale Funktion in `*_grid_function.php` und kann weiterhin `$_POST['ids']`, `$_POST['modul']` oder andere Request-Werte auswerten. Die Zugriffspruefung fuer konfigurierte Grid-Buttons laeuft vor der Ausfuehrung auch bei AJAX.

### 3.3.4 Dashboard-Master-Detail mit `dashboard_select`

Ein Grid kann als Quell-Widget in einem Dashboard verwendet werden.
Wenn `dashboard_select` aktiv ist, sendet der Grid-Kern beim Klick auf eine Datenzeile ein Dashboard-Event an `show_dashboard.php`.
Das Dashboard kann damit ueber seinen `interactions`-Block andere Widgets aktualisieren.

Beispiel im Master-Grid:

```php
'dashboard_select' => [
    'enabled' => true,
    'event' => 'select',
    'id_field' => 'customer_id',
    'payload_fields' => [
        'customer_no' => 'customer_no',
        'company_name' => 'company_name',
    ],
],
```

Parameter:

- `enabled`: aktiviert das Zeilen-Event.
- `event`: Name des Dashboard-Events; Standard ist `select`.
- `id_field`: Feld aus der aktuellen Zeile, das als Payload-Wert `id` gesendet wird. Fehlt der Wert, wird der primaere Schluessel verwendet.
- `payload_fields`: optionale Zusatzwerte. Bei numerischen Schluesseln wird der Feldname auch als Payload-Name verwendet; bei assoziativen Eintraegen gilt `payload_name => feldname`.

Automatisch gesendete Payload-Felder:

- `id`: fachlicher Auswahlwert aus `id_field`
- `pkey`: transportfaehiger Primaerschluesselwert des Datensatzes, bei Composite Keys als MOSAIC-PKey-Token

Klicks auf Links, Buttons, Checkboxen, Eingabefelder und Drag-and-drop-Handles loesen kein Dashboard-Select aus.

Beispiel im Dashboard:

```php
'interactions' => [
    [
        'source_widget_id' => 'customers',
        'event' => 'select',
        'targets' => [
            [
                'widget_id' => 'invoices',
                'action' => 'refresh',
                'param_map' => [
                    'customer_id' => 'id',
                ],
                'required_payload' => ['id'],
                'clear_missing' => true,
                'options' => [
                    'quicksearch' => true,
                    'advanced_search' => false,
                    'limit' => 25,
                ],
            ],
        ],
    ],
],
```

Das Zielgrid liest den URL-Parameter, zum Beispiel `$_GET['customer_id']`, und filtert damit seine Daten.
In der Demo ist das Muster in `demo/dashboard/master_detail_dboard.cfg` umgesetzt.

`options` ist fuer Dashboard-Zielgrids eine Whitelist fuer reine Anzeigeoptionen.
Erlaubt sind nur:

- `quicksearch`: Schnellsuche ein- oder ausschalten.
- `advanced_search`: erweiterte Suche ein- oder ausschalten.
- `limit`: Anzahl der angezeigten Zeilen setzen.

SQL, Tabellen, Rechte, Hooks und Datenbankverbindungen duerfen darueber nicht gesteuert werden.

Alle sichtbaren Grid-Spaltentypen duerfen zusaetzlich diese Anzeigeparameter verwenden:

- `style`
  - statisches CSS fuer alle Datenzellen dieser Spalte
- `header_style`
  - statisches CSS fuer die Kopfzelle dieser Spalte
- `value_styles`
  - CSS je Rohwert der Spalte, wird nach `style` angewendet
- `class` oder `cell_class`
  - CSS-Klasse fuer alle Datenzellen dieser Spalte
- `header_class`
  - CSS-Klasse fuer die Kopfzelle dieser Spalte
- `value_classes`
  - CSS-Klasse je Rohwert der Spalte

Erlaubte CSS-Eigenschaften fuer Inline-Styles:

- `background`, `background-color`, `color`
- `font-family`, `font-size`, `font-weight`, `font-style`
- `text-decoration`, `text-align`, `vertical-align`, `white-space`
- `width`, `min-width`, `max-width`

Beispiel:

```php
'columns' => [
    'status' => [
        'label' => 'Status',
        'type' => 'text',
        'style' => [
            'background-color' => '#fff3cd',
            'color' => '#7a4b00',
        ],
        'header_style' => [
            'background-color' => '#7a4b00',
            'color' => '#ffffff',
            'font-weight' => '700',
        ],
        'value_styles' => [
            'kritisch' => [
                'background-color' => '#f8d7da',
                'color' => '#842029',
                'font-weight' => '700',
            ],
        ],
    ],
]
```

Fuer zeilenabhaengige Styles kann `onRecord` pro Datensatz setzen:

```php
$row['_cell_style']['status'] = [
    'background-color' => '#d1e7dd',
    'color' => '#0f5132',
];

$row['_cell_class']['status'] = 'status-ok';
```

Erlaubte Zusatzparameter pro Typ:

- `text`
  - `tooltip`, `input_length`, `quicksearch`, `sort`, `row_display`, `orientation`
- `number`
  - `tooltip`, `input_length`, `quicksearch`, `sort`, `row_display`, `orientation`, `number_format`, `SUM`, `SUM_function`, `SUM_format`
- `checkbox`
  - `tooltip`, `sort`, `row_display`
- `date`
  - `tooltip`, `quicksearch`, `sort`, `row_display`, `orientation`
- `datetime`
  - `tooltip`, `quicksearch`, `sort`, `row_display`, `orientation`
- `html`
  - `tooltip`, `row_display`
- `select`
  - `tooltip`, `quicksearch`, `sort`, `row_display`, `orientation`, `lookup_method`, `lookup_label`, `lookup_value`, `delimiter`, `lookup_sql`, `multiple_values`
- `choose_manual`
  - `tooltip`, `quicksearch`, `sort`, `row_display`, `orientation`, `values`, `store`
- `file_upload_to_path`
  - `tooltip`, `path_to_store`, `allowed_extension`, `max_size_in_kb`, `show`
- `file_blob`
  - `tooltip`, `filename_field`, `show`
- `image`
  - `tooltip`, `width`, `height`, `mime`

Hinweis zu Summen:

`SUM => true` erzeugt im Grid-Fuss automatisch eine Summenzeile fuer das Feld. Das ist nur fuer fachliche Zahlenfelder sinnvoll, etwa Betraege, Mengen oder Punkte. Technische Schluessel, Fremdschluessel und Reihenfolgefelder sollten keine Summen bekommen. Fuer Durchschnittswerte kann `SUM_function => 'AVG'` verwendet werden. Die Anzeige nutzt im Kern HTML-Entities fuer die Symbole `&Sigma;` und `&Oslash;`, damit die Symbole unabhaengig vom Datei-Encoding korrekt dargestellt werden.
- `computed`
  - `tooltip`, `function`, `orientation`
- `v_menu`
  - `tooltip`, `link`

### 3.4 Berechtigungen

Verbindliche Standard-Berechtigungen fuer `permissions`:

- `view`
- `edit`
- `add`
- `copy`
- `delete`
- `xls_export`
- `select_xls_fields`
- `pdf_export`
- `select_pdf_fields`

### 3.5 Grid-Hooks

Moegliche Hook-Namen in `*_grid_function.php`:

- `onApplicationInit(&$context)`
- `onCheckSecurity(&$context, &$modulConfig)`
- `onLoad(&$context, &$modulConfig)`
- `onBeforeQuery(&$context, &$query)`
- `onRecord(&$context, &$row)`
- `onFooter(&$context, &$footer)`
- `onBeforeRender(&$context, &$renderPayload)`
- `onAfterRender(&$context, &$renderPayload)`

## 4. Verbindliche Spezifikation fuer `*_egrid.cfg`

`easyGrid` hat ein bewusst eigenes und kleineres Schema.

Pflichtschluessel:

- `title`
- `table`
- `primary_key`
- `connection`
- `columns`

Optionale Konfigbereiche:

- `sql`
- `search`
- `groups`
- `permissions`
- `check_security`
- `sql_where`

Wichtige Regeln:

- `db_typ` wird in `egrid` nicht verwendet
- die Verbindung wird ueber `connection` angegeben
- Berechtigungen werden ausschliesslich ueber `permissions` beschrieben
- `sql_where` ist als statischer Zusatzfilter erlaubt und wird wie bei `grid.php` mit `AND` an die Suche angehaengt
- `sql_where` enthaelt eine Bedingung gegen die sichtbaren Quellspalten; ein fuehrendes `WHERE` oder `AND` wird toleriert, aber nicht benoetigt

Unterstuetzte Feldtypen:

- `text`
- `textarea`
- `number`
- `date`
- `datetime`
- `datetime-local`
- `select`
- `radio`
- `checkbox`

Alle eGrid-Spalten duerfen dieselben Anzeigeparameter wie Grid-Spalten verwenden:

- `style`
- `header_style`
- `value_styles`
- `class` oder `cell_class`
- `header_class`
- `value_classes`

Diese Styles wirken auf die Tabellenzelle (`td`) bzw. Kopfzelle (`th`), nicht nur auf den Eingabeinhalt.
Zulaessige CSS-Eigenschaften sind identisch zu `grid.php`.
Zeilenabhaengige Styles koennen in `onRecord` ueber `$row['_cell_style'][$field]` und `$row['_cell_class'][$field]` gesetzt werden.

Nicht mehr erlaubt:

- `advanced_search`
- `filters`
- `marker`
- `user_buttons`
- `show_new_button`
- `sequence_name`
- `db_typ`
- `debug`

Die vollstaendige Detailbeschreibung fuer `egrid` steht in:

- `MOSAIC_egrid_Entwicklerdokumentation.md`

## 5. Weitere Modultypen

Diese Datei ist der zentrale Einstieg fuer oeffentliche Konfigurationsregeln.

Fuer weitere Modultypen gelten die jeweils gleichnamigen Entwicklerdokumentationen im MOSAIC-Ordner, insbesondere:

- `MOSAIC_show_report_Entwicklerdokumentation.md`
- `MOSAIC_show_forum_Entwicklerdokumentation.md`
- `MOSAIC_show_dashboard_Entwicklerdokumentation.md`
- `MOSAIC_show_calendar_Entwicklerdokumentation.md`
- `MOSAIC_show_connector_Entwicklerdokumentation.md`
- `MOSAIC_show_paypal_Entwicklerdokumentation.md`
- `MOSAIC_show_api_Entwicklerdokumentation.md`

## 6. Verbindliche Arbeitsregel fuer KI

Wenn eine KI neue MOSAIC-Konfigurationen erzeugt, gilt:

- zuerst diese Datei lesen
- danach die modulspezifische Detaildokumentation lesen
- `primary_key` immer als Array schreiben
- fuer PostgreSQL immer `pgsql` verwenden
- fuer Oracle immer `oracle` verwenden
- fuer `egrid` immer `connection`, nicht `db_typ`, verwenden
- keine Legacy-Konfigschluessel neu einfuehren

Damit ist diese Datei die oeffentliche Basisspezifikation fuer die Erzeugung neuer MOSAIC-Konfigurationsdateien ohne Einsicht in den internen Generatorcode.
