import type { Connector, ConnectorBinding, ConnectorCandidate } from "@/types/appops"; import { buildConnectorConfigLink } from "./connectorConfigLink.ts"; export type ConnectorDrillSeverity = "healthy" | "warning" | "critical" | "neutral"; export interface ConnectorDrillView { healthLabel: string; severity: ConnectorDrillSeverity; operatorHint: string; primaryActionLabel: string; configHref: string; missingConfig: string[]; counts: { candidates: number; openCandidates: number; bindings: number; capabilities: number; }; } const unique = (items: string[]) => Array.from(new Set(items.filter(Boolean))); export const buildConnectorDrillView = ( connector: Connector, candidates: ConnectorCandidate[], bindings: ConnectorBinding[], ): ConnectorDrillView => { const boundAppIds = new Set(bindings.map(binding => binding.appId)); const openCandidates = candidates.filter(candidate => ( !boundAppIds.has(candidate.suggestedAppId) && candidate.lifecycleState !== "managed" )); const missingConfig = unique([ ...(connector.status === "missing_config" && connector.secretRef ? [connector.secretRef] : []), ...candidates.flatMap(candidate => candidate.missingSecrets || []), ...bindings.flatMap(binding => binding.missingSecrets || []), ]); if (missingConfig.length > 0 || connector.status === "missing_config") { return { healthLabel: "Configuratie mist", severity: "critical", operatorHint: `${missingConfig.length || 1} ontbrekende configuratievelden blokkeren volledige connectorcoverage.`, primaryActionLabel: "Open setup", configHref: buildConnectorConfigLink(connector.id), missingConfig, counts: { candidates: candidates.length, openCandidates: openCandidates.length, bindings: bindings.length, capabilities: connector.capabilities.length, }, }; } if (openCandidates.length > 0) { return { healthLabel: "Binding review", severity: "warning", operatorHint: `${openCandidates.length} open candidate${openCandidates.length === 1 ? "" : "s"} klaar voor review.`, primaryActionLabel: "Review binding", configHref: buildConnectorConfigLink(connector.id), missingConfig, counts: { candidates: candidates.length, openCandidates: openCandidates.length, bindings: bindings.length, capabilities: connector.capabilities.length, }, }; } if (connector.status === "connected" || connector.status === "configured") { return { healthLabel: "Live gekoppeld", severity: "healthy", operatorHint: `${bindings.length} app${bindings.length === 1 ? "" : "s"} gekoppeld; connector is klaar voor veilige reads.`, primaryActionLabel: "Bekijk configuratie", configHref: buildConnectorConfigLink(connector.id), missingConfig, counts: { candidates: candidates.length, openCandidates: openCandidates.length, bindings: bindings.length, capabilities: connector.capabilities.length, }, }; } return { healthLabel: "Niet verbonden", severity: "neutral", operatorHint: "Geen actieve connectorcoverage bekend. Test of configureer deze connector.", primaryActionLabel: "Configureer", configHref: buildConnectorConfigLink(connector.id), missingConfig, counts: { candidates: candidates.length, openCandidates: openCandidates.length, bindings: bindings.length, capabilities: connector.capabilities.length, }, }; };