import { apiFetch, apiPath, type ApiSettings } from "@govoplan/core-webui"; export type DefinitionKind = "static" | "parameterized" | "dynamic" | "template"; export type EntryMode = "include" | "exclude" | "override"; export type EntryKind = | "address_contact" | "address_list" | "address_email" | "raw_email" | "raw_postal_address" | "internal_mail" | "portal" | "idm_identity" | "idm_group" | "organization_unit" | "function" | "effective_function_incumbent" | "dataflow_result" | "distribution_list"; export type DistributionChannel = "email" | "postal" | "internal_mail" | "portal"; export type DistributionOutcome = | "usable" | "unresolved" | "invalid" | "suppressed" | "ambiguous" | "duplicate" | "policy_blocked" | "provider_unavailable" | "stale"; export type SourceReference = { provider: string; resource_type: string; resource_id: string; revision?: string | null; fingerprint?: string | null; label?: string | null; metadata: Record; }; export type DistributionParameter = { key: string; value_type: "string" | "integer" | "number" | "boolean" | "date" | "datetime" | "string_list"; label?: string | null; required: boolean; default?: unknown; allowed_values: unknown[]; minimum?: number | null; maximum?: number | null; pattern?: string | null; description?: string | null; }; export type DistributionListEntryInput = { entry_key?: string | null; kind: EntryKind; mode: EntryMode; source: SourceReference; label?: string | null; purpose?: string | null; requested_channels: DistributionChannel[]; effective_from?: string | null; effective_until?: string | null; configuration: Record; }; export type DistributionListEntry = DistributionListEntryInput & { id: string; entry_key: string; order: number; }; export type DistributionListRevision = { id: string; revision: number; definition_kind: DefinitionKind; definition_hash: string; parameters: DistributionParameter[]; constraints: Record; source_fingerprints: Array>; entries: DistributionListEntry[]; created_by_account_id?: string | null; created_at: string; }; export type DistributionList = { id: string; tenant_id: string; scope_type: "tenant" | "group" | "user"; scope_id?: string | null; name: string; description?: string | null; status: string; current_revision: number; resource_revision: number; etag: string; metadata: Record; deleted_at?: string | null; created_at: string; updated_at: string; revision: DistributionListRevision; }; export type DistributionListPayload = { name: string; description?: string | null; scope_type: "tenant" | "group" | "user"; scope_id?: string | null; definition_kind: DefinitionKind; parameters: DistributionParameter[]; constraints: Record; entries: DistributionListEntryInput[]; metadata: Record; }; export type DistributionExplanation = { code: string; message: string; severity: "info" | "warning" | "error"; provider?: string | null; source?: SourceReference | null; provenance: Record; }; export type DistributionChannelCandidate = { channel: DistributionChannel; target: string; target_key: string; status: DistributionOutcome; contact_point_id?: string | null; locale?: string | null; preferred: boolean; reason_code?: string | null; explanation?: string | null; source?: SourceReference | null; decision_provenance: Record; }; export type DistributionRecipient = { recipient_key: string; display_name: string; status: DistributionOutcome; channels: DistributionChannelCandidate[]; identity_id?: string | null; account_id?: string | null; contact_id?: string | null; organization_unit_id?: string | null; function_id?: string | null; source_entry_ids: string[]; explanations: DistributionExplanation[]; attributes: Record; provenance: Record; }; export type ProviderEvidence = { provider: string; source: SourceReference; actual_revision?: string | null; actual_fingerprint?: string | null; stale: boolean; generated_at?: string | null; details: Record; }; export type ExpansionResult = { list_id: string; revision_id: string; revision: number; definition_hash: string; recipients: DistributionRecipient[]; excluded: DistributionRecipient[]; diagnostics: DistributionExplanation[]; provider_evidence: ProviderEvidence[]; expansion_hash: string; generated_at: string; snapshot_id?: string | null; stale: boolean; truncated: boolean; }; export type ExpansionPayload = { revision?: number | null; effective_at?: string | null; purpose?: string | null; requested_channels?: DistributionChannel[]; parameters?: Record; preview?: boolean; freeze?: boolean; idempotency_key?: string | null; max_entries?: number; max_results?: number; max_depth?: number; max_provider_results?: number; }; export type DistributionSnapshot = { id: string; list_id: string; revision_id: string; revision: number; expansion_hash: string; effective_at: string; recipient_count: number; excluded_count: number; stale: boolean; truncated: boolean; created_at: string; }; export type ProviderOption = { key: string; kind: EntryKind; label: string; description?: string | null; provider: string; source: SourceReference; available: boolean; reason?: string | null; metadata: Record; }; export type ProviderCatalogue = { items: ProviderOption[]; unavailable_providers: DistributionExplanation[]; }; export async function listDistributionLists( settings: ApiSettings, query = "" ): Promise { const result = await apiFetch<{ items: DistributionList[] }>( settings, apiPath("/api/v1/dist-lists/lists", { query, limit: 500 }) ); return result.items; } export function createDistributionList( settings: ApiSettings, payload: DistributionListPayload ): Promise { return apiFetch(settings, "/api/v1/dist-lists/lists", { method: "POST", body: JSON.stringify(payload) }); } export function updateDistributionList( settings: ApiSettings, item: DistributionList, payload: DistributionListPayload ): Promise { return apiFetch(settings, `/api/v1/dist-lists/lists/${encodeURIComponent(item.id)}`, { method: "PUT", headers: { "If-Match": item.etag }, body: JSON.stringify({ ...payload, base_revision: item.resource_revision }) }); } export function deleteDistributionList( settings: ApiSettings, item: DistributionList ): Promise { return apiFetch(settings, `/api/v1/dist-lists/lists/${encodeURIComponent(item.id)}`, { method: "DELETE", headers: { "If-Match": item.etag }, body: JSON.stringify({ base_revision: item.resource_revision }) }); } export function expandDistributionList( settings: ApiSettings, listId: string, payload: ExpansionPayload ): Promise { return apiFetch(settings, `/api/v1/dist-lists/lists/${encodeURIComponent(listId)}/expand`, { method: "POST", body: JSON.stringify(payload) }); } export async function listDistributionSnapshots( settings: ApiSettings, listId: string ): Promise { const result = await apiFetch<{ items: DistributionSnapshot[] }>( settings, `/api/v1/dist-lists/lists/${encodeURIComponent(listId)}/snapshots` ); return result.items; } export function listProviderOptions( settings: ApiSettings, query = "", limit = 50, signal?: AbortSignal ): Promise { return apiFetch( settings, apiPath("/api/v1/dist-lists/providers", { query, limit }), { signal } ); }