fix: Abgleich der Firmenrechte entzieht Bestandskonten ohne E-Mail-Bestätigung nicht mehr pauschal alle Rechte — memberships:resync-auto mit Probelauf und Notbremse

Auf Live meldete memberships:resync-auto nach v1.4.0 „vorher 19607, nachher 9":
syncMembershipsForEmail() entzog Konten ohne email_verified_at alle
automatischen Rechte, und 19.597 davon gehören Bestandskonten aus dem
Altsystem. Jetzt wird nur entzogen, was keine E-Mail-Grundlage mehr hat —
unabhängig vom Kontostatus (S-03 bleibt wirksam); neue Rechte weiterhin nur
für aktive, verifizierte Konten (F01).

memberships:resync-auto läuft in einer Transaktion, kennt --dry-run und rollt
zurück, wenn mehr als 5 % (mindestens 50) der Rechte wegfallen würden
(--force zum Erzwingen). Probelauf gegen die Live-Kopie: 19.607 → 19.316.
Wiederherstellung: storage/app/private/restore-company-user-auto-2026-10-07.sql
(nicht versioniert, INSERT IGNORE, idempotent).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-10-07 16:22:25 +00:00
parent 8045ef18cc
commit af72810296
4 changed files with 136 additions and 24 deletions

View file

@ -129,12 +129,7 @@ class ContactAccessService
{
$email = mb_strtolower(trim((string) $user->email));
// Ohne nachgewiesene Adresse gibt es keine Grundlage für automatische
// Rechte — vorhandene fallen weg (Sicherheitsaudit 07.10.2026, S-03:
// der Abgleich läuft jetzt auch außerhalb des Logins).
if (! $user->is_active || ! $user->hasVerifiedEmail() || $email === '') {
$this->revokeStaleAutomaticGrants($user, collect());
if ($email === '') {
return;
}
@ -142,9 +137,15 @@ class ContactAccessService
$companies = $this->companiesFor($email);
$companyIds = $this->companyIdsFrom($contacts, $companies);
// Entzogen wird nur, was keine E-Mail-Grundlage mehr hat — unabhängig
// vom Kontostatus (S-03). Bestandskonten aus dem Altsystem haben kein
// `email_verified_at`; ihre noch begründeten Rechte bleiben. Eine
// erste Fassung entzog Unverifizierten pauschal alles und nahm beim
// Abgleich am 07.10.2026 so 19.598 begründete Rechte weg (v1.4.1).
$this->revokeStaleAutomaticGrants($user, $companyIds);
if ($companyIds->isEmpty()) {
// Neue Rechte nur für aktive Konten mit nachgewiesener Adresse (F01).
if (! $user->is_active || ! $user->hasVerifiedEmail() || $companyIds->isEmpty()) {
return;
}