tenantId()); $full = $request->boolean('full'); // Même verrou que la commande planifiée : jamais deux synchros en parallèle. $lock = Cache::lock("signature-sync:{$tenant->id}", 600); if (! $lock->get()) { return back()->withErrors(['sync' => 'Une synchronisation est déjà en cours. Réessayez dans une minute.']); } @set_time_limit(300); try { $s = $sync->run($tenant, $full); } catch (Throwable $e) { return back()->withErrors(['sync' => 'Synchronisation en échec : '.mb_substr($e->getMessage(), 0, 300)]); } finally { $lock->release(); } AuditLog::record('admin', $this->actor(), $full ? 'sync.full' : 'sync.delta', $tenant, $s, $tenant->id); return back()->with('status', sprintf( 'Synchronisation %s terminée : %d agents mis à jour, %d retirés, %d groupes, %d appartenances.', $full ? 'complète' : 'incrémentale', $s['users'], $s['removed'], $s['groups'], $s['memberships'], )); } }