# MOSAIC Composite Primary Keys

## Grundsatz

MOSAIC speichert `primary_key` ab sofort immer als Array.

Beispiele:

```php
'primary_key' => ['id']
```

```php
'primary_key' => ['mandant_id', 'beleg_nr']
```

Ein einfacher Schluessel ist damit nur noch der Spezialfall eines Arrays mit genau einem Feld.

## Betroffene Bereiche

- `_pgm/form.php`
- `_pgm/grid.php`
- `_pgm/egrid.php`
- `_pgm/show_egrid.php`
- `_pgm/set_pkey.php`
- `_pgm/set_marker.php`
- `_pgm/pdf_export.php`
- `_pgm/xls_export.php`
- `_pgm/show_v_menu.php`
- Generatoren `create_form.php` und `create_grid.php`
- Scriptcase-Converter `sc_convert_02_grid.php` und `sc_convert_03_form.php`

## Transportmodell

Fuer einen einfachen Primary Key bleibt der Transportwert ein Skalar, zum Beispiel `42`.

Fuer zusammengesetzte Primary Keys verwendet MOSAIC einen transportierbaren Token:

- Prefix `pk:`
- Inhalt: Base64URL-kodiertes JSON mit allen PK-Feldern

Zusatzlich werden bei internen Links weiterhin `pk_<feldname>`-Parameter aufgebaut, wenn die Feldnamen bekannt sind.

## Laufzeitverhalten

### Form

- Session-speicher fuer den aktuellen Datensatz enthaelt immer ein PK-Array.
- Hooks erhalten bei einfachem Schluessel weiter den Skalarwert in `id`.
- Bei zusammengesetztem Schluessel erhalten Hooks in `id` ein assoziatives Array.
- `context['primary_key_fields']` enthaelt die PK-Feldliste.
- `context['primary_key_values']` enthaelt die aktuellen PK-Werte.

### Grid

- Marker speichern keine Integer-IDs mehr, sondern allgemeine Transportwerte.
- BLOB-Download, Edit-Link und `v_menu` koennen zusammengesetzte Keys verarbeiten.
- Exporte loesen markierte Zeilen ueber dynamische `WHERE (a = :a AND b = :b) OR ...`-Bedingungen auf.

### easyGrid

- Insert, Update und Delete verwenden dieselbe PK-Normalisierung wie Form und Grid.
- Bei Insert duerfen Primary-Key-Felder Teil der Eingabedaten sein.
- Bei zusammengesetzten Keys zeigt easyGrid im Badge eine kompakte Feldliste an.

## Hinweise fuer SQL und Konfiguration

- Eigene `sql`-Statements muessen alle Primary-Key-Felder im Resultset enthalten.
- Bei `grid` und `egrid` duerfen PK-Felder in der Anzeige verborgen sein, muessen aber technisch im Select verfuegbar bleiben.
- Generatoren akzeptieren im UI weiterhin eine Texteingabe; mehrere Felder werden mit `;` oder `,` getrennt und intern als Array gespeichert.

## Hook-Empfehlung

Wenn Hook-Code mit dem aktuellen Datensatz arbeitet, sollte er kuenftig nicht mehr von `int $id` ausgehen.
Empfohlen ist:

```php
function onBeforeUpdate(array &$context, array &$postData, $id): ?string
{
    if (is_array($id)) {
        // Composite Key
    } else {
        // Einfacher Key
    }

    return null;
}
```
## Runner-Stand im Kern

Stand April 2026 gilt im MOSAIC-Kern ein einheitliches Runner-Schema:

- `grid.php` und `form.php` bleiben direkte generische CRUD-Runner
- `show_egrid.php` ist der kanonische eGrid-Einstieg und delegiert intern an `egrid.php`
- alle anderen fachlichen Runner verwenden konsequent das Praefix `show_`
- typische Beispiele sind `show_menu.php`, `show_dashboard.php`, `show_report.php`, `show_chart.php`, `show_login.php` und `show_v_menu.php`
- fruehere Alt-Namen sind nicht mehr Bestandteil des aktiven Kernbereichs
