import { apiFetch, apiPath, type ApiSettings } from "@govoplan/core-webui"; export type GovernedConnectorSpecification = { provider: string; protocol: string; capabilities: string[]; input_schema: Record; output_schema: Record; mapping: { version: string; rules: Array<{ source: string; target: string; required?: boolean; default?: unknown; }>; }; validation_rules: Array<{ kind: "required" | "one_of" | "unique"; field: string; values?: unknown[]; severity: "warning" | "error"; code: string; message: string; }>; dry_run: { supported: boolean; simulation_supported: boolean; sample_rows: Array>; max_items: number; redacted_fields: string[]; }; audit: { event_prefix: string; expected_events: string[]; evidence_fields: string[]; }; privacy_classification: "public" | "internal" | "confidential" | "restricted"; retention_class: string; operational_limits: Record; retry_policy: Record; }; export type ConnectorDefinition = { id: string; definition_key: string; name: string; description?: string | null; status: string; current_revision: number; source_package?: string | null; local_definition: boolean; definition_hash: string; specification: GovernedConnectorSpecification; updated_at: string; }; export type ConnectorConfiguration = { id: string; definition_id: string; definition_key: string; definition_name: string; name: string; status: "draft" | "active" | "disabled"; endpoint_url?: string | null; credential_ref?: string | null; base_definition_revision: number; latest_definition_revision: number; update_available: boolean; local_overrides: Record; protected_paths: string[]; effective_configuration: GovernedConnectorSpecification; effective_hash: string; resource_revision: number; ambiguity_policy: "manual_review" | "quarantine" | "reject"; updated_at: string; }; export type ConnectorRun = { id: string; configuration_id: string; mode: "dry_run" | "simulation"; idempotency_key: string; status: string; review_state: string; definition_revision: number; configuration_revision: number; configuration_hash: string; input_hash: string; summary: Record; effects: Array>; diagnostics: Array>; provenance: Record; reviewed_by?: string | null; reviewed_at?: string | null; review_reason?: string | null; created_at: string; }; export type ConnectorConfigurationDraft = { name: string; status: ConnectorConfiguration["status"]; endpoint_url: string; credential_ref: string; local_overrides: string; ambiguity_policy: ConnectorConfiguration["ambiguity_policy"]; }; const ROOT = "/api/v1/connectors/governed"; export async function listConnectorDefinitions( settings: ApiSettings ): Promise { const response = await apiFetch<{ items: ConnectorDefinition[] }>( settings, `${ROOT}/definitions` ); return response.items; } export async function upsertConnectorDefinition( settings: ApiSettings, payload: Record ): Promise { return apiFetch(settings, `${ROOT}/definitions`, { method: "POST", body: JSON.stringify(payload) }); } export async function listConnectorConfigurations( settings: ApiSettings ): Promise { const response = await apiFetch<{ items: ConnectorConfiguration[] }>( settings, `${ROOT}/configurations` ); return response.items; } export function createConnectorConfiguration( settings: ApiSettings, payload: Record ): Promise { return apiFetch(settings, `${ROOT}/configurations`, { method: "POST", body: JSON.stringify(payload) }); } export function updateConnectorConfiguration( settings: ApiSettings, configurationId: string, payload: Record ): Promise { return apiFetch( settings, `${ROOT}/configurations/${encodeURIComponent(configurationId)}`, { method: "PUT", body: JSON.stringify(payload) } ); } export async function listConnectorRuns( settings: ApiSettings, configurationId?: string ): Promise { const response = await apiFetch<{ items: ConnectorRun[] }>( settings, apiPath(`${ROOT}/runs`, { configuration_id: configurationId || undefined, limit: 100 }) ); return response.items; } export function executeConnectorRun( settings: ApiSettings, configurationId: string, mode: "dry-runs" | "simulations", payload: Record ): Promise { return apiFetch( settings, `${ROOT}/configurations/${encodeURIComponent(configurationId)}/${mode}`, { method: "POST", body: JSON.stringify(payload) } ); } export function reviewConnectorRun( settings: ApiSettings, runId: string, decision: "approved" | "rejected", reason: string ): Promise { return apiFetch( settings, `${ROOT}/runs/${encodeURIComponent(runId)}/review`, { method: "POST", body: JSON.stringify({ decision, reason }) } ); }