310 lines
7.8 KiB
TypeScript
310 lines
7.8 KiB
TypeScript
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<string, unknown>;
|
|
};
|
|
|
|
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<string, unknown>;
|
|
};
|
|
|
|
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<string, unknown>;
|
|
source_fingerprints: Array<Record<string, unknown>>;
|
|
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<string, unknown>;
|
|
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<string, unknown>;
|
|
entries: DistributionListEntryInput[];
|
|
metadata: Record<string, unknown>;
|
|
};
|
|
|
|
export type DistributionExplanation = {
|
|
code: string;
|
|
message: string;
|
|
severity: "info" | "warning" | "error";
|
|
provider?: string | null;
|
|
source?: SourceReference | null;
|
|
provenance: Record<string, unknown>;
|
|
};
|
|
|
|
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<string, unknown>;
|
|
};
|
|
|
|
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<string, unknown>;
|
|
provenance: Record<string, unknown>;
|
|
};
|
|
|
|
export type ProviderEvidence = {
|
|
provider: string;
|
|
source: SourceReference;
|
|
actual_revision?: string | null;
|
|
actual_fingerprint?: string | null;
|
|
stale: boolean;
|
|
generated_at?: string | null;
|
|
details: Record<string, unknown>;
|
|
};
|
|
|
|
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<string, unknown>;
|
|
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<string, unknown>;
|
|
};
|
|
|
|
export type ProviderCatalogue = {
|
|
items: ProviderOption[];
|
|
unavailable_providers: DistributionExplanation[];
|
|
};
|
|
|
|
export async function listDistributionLists(
|
|
settings: ApiSettings,
|
|
query = ""
|
|
): Promise<DistributionList[]> {
|
|
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<DistributionList> {
|
|
return apiFetch(settings, "/api/v1/dist-lists/lists", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export function updateDistributionList(
|
|
settings: ApiSettings,
|
|
item: DistributionList,
|
|
payload: DistributionListPayload
|
|
): Promise<DistributionList> {
|
|
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<void> {
|
|
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<ExpansionResult> {
|
|
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<DistributionSnapshot[]> {
|
|
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<ProviderCatalogue> {
|
|
return apiFetch(
|
|
settings,
|
|
apiPath("/api/v1/dist-lists/providers", { query, limit }),
|
|
{ signal }
|
|
);
|
|
}
|