import type { IncidentCache } from '@/lib/api/incident-status' type BannerIncident = { id: string; cache?: IncidentCache | null } /** * Determines whether the incident status banner should be shown to a given user, * given all active incidents and the user's project state. * * Returns true if any incident matches the user's context. * * @param incidents - Active incidents from the incident-status endpoint * @param hasProjects - Whether the user has any projects at all * @param userRegions - Deduplicated set of regions of all databases (primary and read replicas) owned by the user * @param hasUnknownRegions - True when region data is incomplete (org has >100 projects). * When true, the region check is skipped and a match is assumed. */ export function shouldShowBanner({ incidents, hasProjects, userRegions, hasUnknownRegions = false, }: { incidents: Array hasProjects: boolean userRegions: Set hasUnknownRegions?: boolean }): boolean { return incidents.some((incident) => { // Forced incidents are shown unconditionally, regardless of regions or project state if (incident.cache?.force) return true const affectedRegions = incident.cache?.affected_regions ?? [] const affectsProjectCreation = incident.cache?.affects_project_creation ?? false // Users with no projects only see the banner if the incident affects project creation // and has no specific region targeting (inline notice in RegionSelector handles region-specific incidents) if (!hasProjects) return affectsProjectCreation && affectedRegions.length === 0 // User has projects: if no region restriction, always show if (affectedRegions.length === 0) return true // Region data is incomplete — assume the user has a database in an affected region if (hasUnknownRegions) return true // Region restriction: only show if the user has a database in an affected region return affectedRegions.some((region) => userRegions.has(region.toLowerCase())) }) } /** * Returns the IDs of incidents that are relevant to the given user. * * An incident is considered relevant if it would trigger banner visibility for * the user, per the same logic as shouldShowBanner. */ export function getRelevantIncidentIds({ incidents, hasProjects, userRegions, hasUnknownRegions = false, }: { incidents: Array hasProjects: boolean userRegions: Set hasUnknownRegions?: boolean }): Array { return incidents .filter((incident) => shouldShowBanner({ incidents: [incident], hasProjects, userRegions, hasUnknownRegions }) ) .map((incident) => incident.id) }