M5 abschliessen: Schreibseiten aufs Ledger umstellen, Storno statt Delete

- stricheintragen.php und einzahlung.php erhielten bisher gar keine
  Zugriffskontrolle (nur CSRF), jetzt Rollen-/Legacy-Fallback wie in
  kaffeeliste.php; Sammeleintraege spiegeln transaktional ins Ledger
  (ledger_mirror_legacy_payment neu ergaenzt).
- letzteneintraege.php war rein ueber Legacy-Admin gesperrt und haette
  neue SaaS-Mandanten ausgeschlossen; Loeschen markiert den gespiegelten
  Ledger-Eintrag jetzt per voided_at statt ihn zu entfernen
  (ledger_void_entry_by_legacy_id).
- check-m4-ledger-migration.php an das Storno-Modell angepasst: verwaiste
  Ledger-Zeilen sind nur noch ein Fehler, wenn sie nicht voided sind.
- Nebenbei: PHP-Warning bei Sammelerfassung behoben, toten Code entfernt,
  veraltete README (verwies auf nicht existierende saas-app/-Struktur)
  korrigiert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 23:43:39 +02:00
co-authored by Claude Sonnet 5
parent aa9444f076
commit 968a55f442
7 changed files with 344 additions and 120 deletions
+10 -4
View File
@@ -101,12 +101,13 @@ $stmt = $pdo->prepare(
"SELECT COUNT(*)
FROM ledger_entries
WHERE tenant_id = ?
AND legacy_table IN ('kl_Einzahlungen', 'kl_Kaffeeverbrauch')"
AND legacy_table IN ('kl_Einzahlungen', 'kl_Kaffeeverbrauch')
AND voided_at IS NULL"
);
$stmt->execute([$tenantId]);
$ledgerLegacyCount = (int)$stmt->fetchColumn();
m4_check_assert_equal(
'legacy ledger row count matches source rows',
'active legacy ledger row count matches source rows',
$legacyPaymentCount + $legacyConsumptionCount,
$ledgerLegacyCount,
$failures,
@@ -131,16 +132,20 @@ m4_check_assert_equal(
$passes
);
// Ledger rows without a matching legacy row are only expected when they were
// voided through the storno flow in letzteneintraege.php. A missing legacy row
// on a non-voided ledger entry indicates real drift between the tables.
$stmt = $pdo->prepare(
"SELECT COUNT(*)
FROM ledger_entries le
LEFT JOIN kl_Einzahlungen e ON e.EinzahlungsID = le.legacy_id
WHERE le.tenant_id = ?
AND le.legacy_table = 'kl_Einzahlungen'
AND le.voided_at IS NULL
AND e.EinzahlungsID IS NULL"
);
$stmt->execute([$tenantId]);
m4_check_assert_equal('no stale payment ledger rows', 0, (int)$stmt->fetchColumn(), $failures, $passes);
m4_check_assert_equal('no stale non-voided payment ledger rows', 0, (int)$stmt->fetchColumn(), $failures, $passes);
$stmt = $pdo->prepare(
"SELECT COUNT(*)
@@ -148,10 +153,11 @@ $stmt = $pdo->prepare(
LEFT JOIN kl_Kaffeeverbrauch v ON v.VerbrauchID = le.legacy_id
WHERE le.tenant_id = ?
AND le.legacy_table = 'kl_Kaffeeverbrauch'
AND le.voided_at IS NULL
AND v.VerbrauchID IS NULL"
);
$stmt->execute([$tenantId]);
m4_check_assert_equal('no stale consumption ledger rows', 0, (int)$stmt->fetchColumn(), $failures, $passes);
m4_check_assert_equal('no stale non-voided consumption ledger rows', 0, (int)$stmt->fetchColumn(), $failures, $passes);
$stmt = $pdo->prepare("SELECT COUNT(*) FROM ledger_entries WHERE tenant_id = ? AND type = 'payment' AND amount_cents <= 0");
$stmt->execute([$tenantId]);