Legacy-Abbau Schritt 1: Dual-Write in die kl_*-Tabellen entfernt

Die Migration in participants/ledger_entries ist abgeschlossen: kein
Teilnehmer traegt noch eine legacy_mitarbeiter_id, kein Journaleintrag eine
legacy_table. Damit war der jeweils zweite Zweig ("Default-Mandant schreibt
zusaetzlich nach kl_Einzahlungen/kl_Kaffeeverbrauch/kl_Mitarbeiter") in
sechs Dateien nicht mehr erreichbar - er musste aber bei jeder Aenderung
mitgepflegt werden, zuletzt bei der Bemerkung fuer Einzahlungen.

Entfernt:
- Dual-Write beim Buchen: einzahlung.php, stricheintragen.php, index.php,
  jahresauswertung.php, app/imports.php, app/paypal-inbox.php
- Dual-Write in der Mitgliederverwaltung: ledger_create_participant,
  ledger_update_participant, ledger_set_participant_active,
  ledger_anonymize_participant
- die verwaisten Spiegelfunktionen ledger_mirror_legacy_payment,
  ledger_mirror_legacy_consumption und ledger_void_entry_by_legacy_id

Nebenbei behoben: kaffeeliste.php hat die Teilnehmer-Detailseite nur fuer
Mitglieder mit legacy_mitarbeiter_id verlinkt - die hat seit der Migration
niemand mehr, die Seite war also fuer alle unerreichbar. Verlinkt und
adressiert wird jetzt ueber participant_id; "user_id" bleibt als Alias
erhalten. Der Mandanten-Isolationstest prueft jetzt ledger_void_entry, also
den Pfad, den letzteneintraege.php tatsaechlich nutzt.

Pruefskripte unveraendert gegenueber der Baseline vor dem Umbau
(http-smoke 27/6, role-matrix 55/0); die Isolationspruefung steigt von
9 auf 11 PASS bei gleichem vorbestehendem Fehler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 20:57:49 +02:00
co-authored by Claude Opus 4.8
parent dd6e1e77b0
commit eec7a2fef2
11 changed files with 98 additions and 482 deletions
+13 -8
View File
@@ -102,15 +102,20 @@ try {
m8_assert('Zugangsvergabe auf fremden Teilnehmer schlaegt fehl', $grantResult['ok'] === false, $failures, $passes);
// 7. Storno eines fremden Eintrags ueber den falschen Mandanten aendert nichts.
// ledger_void_entry_by_legacy_id() matcht ueber (tenant_id, legacy_table,
// legacy_id); dafuer braucht es einen Eintrag mit einer synthetischen
// Legacy-Referenz, unabhaengig von echten kl_*-Zeilen.
$pdo->prepare(
"UPDATE ledger_entries SET legacy_table = 'isolation_test', legacy_id = ? WHERE tenant_id = ? AND participant_id = ?"
)->execute([$participantA, $tenantA, $participantA]);
$voidedWrongTenant = ledger_void_entry_by_legacy_id($pdo, $tenantB, 'isolation_test', $participantA);
// Geprueft wird der echte Storno-Pfad ledger_void_entry(), den auch
// letzteneintraege.php nutzt.
$entryIdA = (int)$pdo->query(
"SELECT id FROM ledger_entries WHERE tenant_id = {$tenantA} AND participant_id = {$participantA} AND voided_at IS NULL LIMIT 1"
)->fetchColumn();
m8_assert('Testeintrag fuer Storno vorhanden', $entryIdA > 0, $failures, $passes);
$voidedWrongTenant = ledger_void_entry($pdo, $tenantB, $entryIdA);
m8_assert('Storno ueber falschen Mandanten aendert nichts', $voidedWrongTenant === false, $failures, $passes);
$voidedRightTenant = ledger_void_entry_by_legacy_id($pdo, $tenantA, 'isolation_test', $participantA);
$stillActive = (string)$pdo->query("SELECT COUNT(*) FROM ledger_entries WHERE id = {$entryIdA} AND voided_at IS NULL")->fetchColumn();
m8_assert('fremder Eintrag ist nach abgelehntem Storno unveraendert', $stillActive === '1', $failures, $passes);
$voidedRightTenant = ledger_void_entry($pdo, $tenantA, $entryIdA);
m8_assert('Storno ueber den richtigen Mandanten funktioniert', $voidedRightTenant === true, $failures, $passes);
// 8. Audit-Log ist mandantenscoped.
+1 -1
View File
@@ -51,7 +51,7 @@ $checks = [
'path' => 'kaffeeliste.php',
'contains' => [
'Aktive Mitarbeiter',
'teilnehmerauswertung.php?user_id=',
'teilnehmerauswertung.php?participant_id=',
'GM Negativ',
'gm-negative@test.local',
'-2,00 €',