dismiss 된 alertId 목록 */ public function getDismissedAlertIds(?int $userId): array { if (! $userId) { return []; } $cached = $this->cache->get(self::DISMISS_CACHE_PREFIX.$userId, []); if (! is_array($cached)) { return []; } return array_values(array_filter($cached, 'is_string')); } /** * 알림을 사용자별로 dismiss 합니다. * * 자동 비활성화 알림 (DB 영속) 은 다른 관리자에게는 계속 표시되고, * 재호환 알림 (캐시 기반) 은 캐시 만료/감지 갱신 시 재노출됩니다. * * @param string $alertId 알림 ID (compat_{type}_{identifier} 또는 recover_{type}_{identifier}) * @param int|null $userId 사용자 ID (null/0 이면 무시) */ public function dismissAlert(string $alertId, ?int $userId): void { if (! $userId) { return; } $key = self::DISMISS_CACHE_PREFIX.$userId; $dismissed = $this->cache->get($key, []); if (! is_array($dismissed)) { $dismissed = []; } if (! in_array($alertId, $dismissed, true)) { $dismissed[] = $alertId; $this->cache->put($key, $dismissed, self::DISMISS_CACHE_TTL); } } /** * 컨테이너 바인딩 실패 시의 fallback 인스턴스 (CacheInterface 미바인딩 환경 보호). * * @return self */ public static function fallback(): self { return new self(new CoreCacheDriver(config('cache.default', 'array'))); } }