auth: automatische Firmenzuordnung beim Wegfall der E-Mail-Grundlage entfernen statt senken (Block 7.13, U01, E7)
- Login-Sync löscht auto-Pivots ohne aktuellen Treffer; member wäre die Teamrolle mit Schreibrecht auf alle Firmen-PMs, keine Leserolle - hochgestufte manuelle Mitgliedschaften tragen granted_via=auto-upgrade und fallen auf member zurück; manual und owner bleiben unberührt - company-memberships:audit --classify stuft nur manual-Zeilen um - Plan: E2 revidiert, E7 entschieden, 1.5 und 7.13 nachgezogen Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
c26bdff681
commit
5122624687
4 changed files with 92 additions and 26 deletions
|
|
@ -83,7 +83,7 @@ class AuditCompanyMemberships extends Command
|
|||
$before = (string) $this->option('before');
|
||||
$candidates = $this->responsibleRows()
|
||||
->filter(fn (object $row): bool => isset($explained[$row->company_id.':'.$row->user_id]))
|
||||
->where('granted_via', '!=', 'auto')
|
||||
->where('granted_via', 'manual')
|
||||
->filter(fn (object $row): bool => $before === '' || (string) $row->created_at < $before)
|
||||
->values();
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ class AuditCompanyMemberships extends Command
|
|||
->where('company_id', $row->company_id)
|
||||
->where('user_id', $row->user_id)
|
||||
->where('role', 'responsible')
|
||||
->where('granted_via', '!=', 'auto')
|
||||
->where('granted_via', 'manual')
|
||||
->update(['granted_via' => 'auto']);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,10 +109,14 @@ class ContactAccessService
|
|||
* hat, ist unverifiziert und erhält nichts – der Login-Event feuert auch
|
||||
* vor der Verifizierungs-Weiche. Deaktivierte Konten ebenfalls nicht.
|
||||
*
|
||||
* Gegenrichtung (Audit F10, E2): automatisch vergebene `responsible`-Rechte,
|
||||
* Gegenrichtung (Audit F10/U01, E7): automatisch vergebene Zuordnungen,
|
||||
* deren E-Mail-Grundlage weggefallen ist (Adresse an Firma oder Kontakt
|
||||
* getauscht, Kontakt gelöscht), fallen auf `member` zurück. Manuell oder
|
||||
* aus dem Altbestand vergebene Rechte (`granted_via = manual`) bleiben.
|
||||
* getauscht, Kontakt gelöscht, eigene Adresse geändert), werden entfernt –
|
||||
* `member` wäre keine Leserolle, sondern die Teamrolle mit Schreibrecht
|
||||
* auf alle Firmen-PMs. Eigene PMs bleiben über die Autorenschaft. Eine
|
||||
* automatisch HOCHGESTUFTE manuelle Mitgliedschaft (`auto-upgrade`) fällt
|
||||
* auf `member` zurück. Manuell oder aus dem Altbestand vergebene Rechte
|
||||
* (`granted_via = manual`) bleiben.
|
||||
*/
|
||||
public function syncMembershipsForEmail(User $user): void
|
||||
{
|
||||
|
|
@ -140,19 +144,23 @@ class ContactAccessService
|
|||
}
|
||||
|
||||
/**
|
||||
* Senkt automatisch vergebene `responsible`-Pivots ohne aktuellen
|
||||
* E-Mail-Treffer auf `member`. Lesezugriff bleibt, Schreibzugriff geht.
|
||||
* Entfernt automatisch vergebene `responsible`-Pivots ohne aktuellen
|
||||
* E-Mail-Treffer (E7). Eine hochgestufte manuelle Mitgliedschaft geht auf
|
||||
* ihren vorherigen Stand `member` zurück und gilt wieder als manuell.
|
||||
*
|
||||
* @param Collection<int, int> $currentCompanyIds
|
||||
*/
|
||||
private function revokeStaleAutomaticGrants(User $user, Collection $currentCompanyIds): void
|
||||
{
|
||||
DB::table('company_user')
|
||||
$stale = DB::table('company_user')
|
||||
->where('user_id', $user->id)
|
||||
->where('role', 'responsible')
|
||||
->where('granted_via', 'auto')
|
||||
->whereNotIn('company_id', $currentCompanyIds->all())
|
||||
->update(['role' => 'member', 'updated_at' => now()]);
|
||||
->whereNotIn('company_id', $currentCompanyIds->all());
|
||||
|
||||
(clone $stale)->where('granted_via', 'auto')->delete();
|
||||
|
||||
(clone $stale)->where('granted_via', 'auto-upgrade')
|
||||
->update(['role' => 'member', 'granted_via' => 'manual', 'updated_at' => now()]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -282,9 +290,11 @@ class ContactAccessService
|
|||
if ($linked === null) {
|
||||
$user->companies()->attach($companyId, ['role' => 'responsible', 'granted_via' => 'auto']);
|
||||
} elseif ($linked->pivot->role === 'member') {
|
||||
// Nur den Read-only-Default hochstufen; owner/responsible bleiben.
|
||||
// Die Hochstufung ist automatisch und damit wieder rücknehmbar.
|
||||
$user->companies()->updateExistingPivot($companyId, ['role' => 'responsible', 'granted_via' => 'auto']);
|
||||
// Nur den Team-Default hochstufen; owner/responsible bleiben.
|
||||
// `auto-upgrade` merkt sich, dass darunter eine manuelle
|
||||
// Mitgliedschaft liegt – die Rücknahme führt dorthin zurück
|
||||
// statt die Zeile zu löschen.
|
||||
$user->companies()->updateExistingPivot($companyId, ['role' => 'responsible', 'granted_via' => 'auto-upgrade']);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue