M3 SaaS-Basis mit Default-Tenant vorbereiten

- Tenant/User/Membership/Participant-Tabellen additiv migrieren
- Default-Tenant-Backfill fuer Legacy-Mitarbeiter und Admins ergaenzen
- M3-Kontrollskript und Plan-Dokumentation aktualisieren
This commit is contained in:
2026-07-12 19:40:28 +02:00
parent 8511b876f3
commit eef0338e31
5 changed files with 465 additions and 22 deletions
+111
View File
@@ -0,0 +1,111 @@
<?php
declare(strict_types=1);
require __DIR__ . '/dev-db.php';
function m3_check_assert(string $label, bool $condition, array &$failures, int &$passes): void
{
if ($condition) {
$passes++;
echo "PASS {$label}\n";
return;
}
$failures[] = $label;
echo "FAIL {$label}\n";
}
$pdo = dev_pdo();
dev_apply_schema($pdo);
$tenantSlug = getenv('M3_DEFAULT_TENANT_SLUG');
$tenantSlug = $tenantSlug !== false && trim($tenantSlug) !== '' ? trim($tenantSlug) : 'default';
$failures = [];
$passes = 0;
$stmt = $pdo->prepare('SELECT * FROM tenants WHERE slug = ?');
$stmt->execute([$tenantSlug]);
$tenants = $stmt->fetchAll();
m3_check_assert('default tenant exists exactly once', count($tenants) === 1, $failures, $passes);
if (count($tenants) !== 1) {
echo "\nM3 SaaS basis check failed: tenant '{$tenantSlug}' is missing or duplicated.\n";
exit(1);
}
$tenantId = (int)$tenants[0]['id'];
$legacyMemberCount = (int)$pdo->query('SELECT COUNT(*) FROM kl_Mitarbeiter')->fetchColumn();
$stmt = $pdo->prepare('SELECT COUNT(*) FROM tenant_settings WHERE tenant_id = ?');
$stmt->execute([$tenantId]);
m3_check_assert('tenant settings exist exactly once', (int)$stmt->fetchColumn() === 1, $failures, $passes);
$stmt = $pdo->prepare('SELECT COUNT(*) FROM participants WHERE tenant_id = ?');
$stmt->execute([$tenantId]);
m3_check_assert('participant count matches legacy members', (int)$stmt->fetchColumn() === $legacyMemberCount, $failures, $passes);
$stmt = $pdo->prepare(
'SELECT COUNT(DISTINCT legacy_mitarbeiter_id)
FROM participants
WHERE tenant_id = ?
AND legacy_mitarbeiter_id IS NOT NULL'
);
$stmt->execute([$tenantId]);
m3_check_assert('legacy member ids are mapped one-to-one', (int)$stmt->fetchColumn() === $legacyMemberCount, $failures, $passes);
$stmt = $pdo->prepare(
'SELECT COUNT(*)
FROM kl_Mitarbeiter m
LEFT JOIN participants p
ON p.tenant_id = ?
AND p.legacy_mitarbeiter_id = m.MitarbeiterID
WHERE p.id IS NULL'
);
$stmt->execute([$tenantId]);
m3_check_assert('no legacy member is missing a participant', (int)$stmt->fetchColumn() === 0, $failures, $passes);
$stmt = $pdo->prepare(
'SELECT COUNT(*)
FROM kl_Mitarbeiter m
LEFT JOIN users u
ON u.email_norm = LOWER(TRIM(m.Email))
LEFT JOIN tenant_memberships tm
ON tm.tenant_id = ?
AND tm.user_id = u.id
WHERE m.aktiv = 1
AND m.admin = 1
AND (tm.id IS NULL OR tm.role NOT IN (\'admin\', \'owner\'))'
);
$stmt->execute([$tenantId]);
m3_check_assert('active legacy admins have tenant memberships', (int)$stmt->fetchColumn() === 0, $failures, $passes);
$stmt = $pdo->prepare(
'SELECT COUNT(*)
FROM kl_Mitarbeiter m
JOIN users u
ON u.email_norm = LOWER(TRIM(m.Email))
JOIN tenant_memberships tm
ON tm.tenant_id = ?
AND tm.user_id = u.id
JOIN participants p
ON p.tenant_id = tm.tenant_id
AND p.legacy_mitarbeiter_id = m.MitarbeiterID
WHERE m.aktiv = 1
AND m.admin = 1
AND p.user_id <> u.id'
);
$stmt->execute([$tenantId]);
m3_check_assert('admin participants link to their login users', (int)$stmt->fetchColumn() === 0, $failures, $passes);
if ($failures !== []) {
echo "\nM3 SaaS basis check failed with " . count($failures) . " failure(s):\n";
foreach ($failures as $failure) {
echo "- {$failure}\n";
}
exit(1);
}
echo "\nM3 SaaS basis check passed with {$passes} assertions.\n";