Add governed form handoffs
This commit is contained in:
@@ -19,6 +19,10 @@ export type EvidenceReference = {
|
||||
version?: string | null;
|
||||
};
|
||||
|
||||
export type FormCondition =
|
||||
| { kind: "predicate"; field_key: string; operator: string; value?: unknown }
|
||||
| { kind: "all" | "any" | "not"; conditions: FormCondition[] };
|
||||
|
||||
export type FormFieldDefinition = {
|
||||
key: string;
|
||||
label: string;
|
||||
@@ -28,6 +32,7 @@ export type FormFieldDefinition = {
|
||||
options: string[];
|
||||
constraints: Record<string, unknown>;
|
||||
default_value?: unknown;
|
||||
visibility_condition?: FormCondition | null;
|
||||
};
|
||||
|
||||
export type FormDefinition = {
|
||||
@@ -43,6 +48,30 @@ export type FormDefinition = {
|
||||
signature_requirement: "none" | "optional" | "required";
|
||||
policy_refs: string[];
|
||||
handoff_kinds: string[];
|
||||
pages?: Array<{
|
||||
key: string;
|
||||
title: string;
|
||||
description?: string | null;
|
||||
visibility_condition?: FormCondition | null;
|
||||
sections: Array<{
|
||||
key: string;
|
||||
title: string;
|
||||
description?: string | null;
|
||||
field_keys: string[];
|
||||
visibility_condition?: FormCondition | null;
|
||||
}>;
|
||||
}>;
|
||||
fallback_locale?: string | null;
|
||||
localizations?: Array<{
|
||||
locale: string;
|
||||
title?: string | null;
|
||||
description?: string | null;
|
||||
field_labels: Record<string, string>;
|
||||
field_help_texts: Record<string, string>;
|
||||
option_labels: Record<string, Record<string, string>>;
|
||||
page_titles: Record<string, string>;
|
||||
section_titles: Record<string, string>;
|
||||
}>;
|
||||
};
|
||||
|
||||
export type ValidationResult = {
|
||||
@@ -83,6 +112,24 @@ export type FormInstanceEvent = {
|
||||
payload: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type FormHandoff = {
|
||||
effect_id: string;
|
||||
instance_id: string;
|
||||
instance_revision: number;
|
||||
binding_kind: "case" | "workflow";
|
||||
binding_reference: string;
|
||||
provider_capability: string;
|
||||
state: "requested" | "accepted" | "rejected" | "outcome_unknown" | "reconciled" | "compensated";
|
||||
attempt_count: number;
|
||||
requested_at: string;
|
||||
resolved_at?: string | null;
|
||||
target_ref?: InstitutionalReference | null;
|
||||
href?: string | null;
|
||||
evidence: EvidenceReference[];
|
||||
last_error?: string | null;
|
||||
metadata: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export function listFormInstances(
|
||||
settings: ApiSettings,
|
||||
options: { statuses?: string[]; definitionId?: string; offset?: number; limit?: number } = {},
|
||||
@@ -169,3 +216,57 @@ export function submitFormInstance(
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
export function listFormHandoffs(
|
||||
settings: ApiSettings,
|
||||
instanceId: string,
|
||||
signal?: AbortSignal
|
||||
): Promise<{ handoffs: FormHandoff[] }> {
|
||||
return apiFetch(settings, `/api/v1/forms-runtime/instances/${encodeURIComponent(instanceId)}/handoffs`, { signal });
|
||||
}
|
||||
|
||||
export function startFormHandoff(
|
||||
settings: ApiSettings,
|
||||
instance: FormInstance,
|
||||
bindingKind: "case" | "workflow",
|
||||
bindingReference?: string
|
||||
): Promise<{ handoff: FormHandoff; instance?: FormInstance | null }> {
|
||||
return apiFetch(settings, `/api/v1/forms-runtime/instances/${encodeURIComponent(instance.instance_id)}/handoffs/native`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
expected_revision: instance.revision,
|
||||
binding_kind: bindingKind,
|
||||
binding_reference: bindingReference?.trim() || null,
|
||||
idempotency_key: crypto.randomUUID(),
|
||||
requested_at: new Date().toISOString()
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
export function actOnFormHandoff(
|
||||
settings: ApiSettings,
|
||||
instanceId: string,
|
||||
effectId: string,
|
||||
action: "retry" | "reconcile"
|
||||
): Promise<{ handoff: FormHandoff; instance?: FormInstance | null }> {
|
||||
return apiFetch(settings, `/api/v1/forms-runtime/instances/${encodeURIComponent(instanceId)}/handoffs/${encodeURIComponent(effectId)}/${action}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ recorded_at: new Date().toISOString() })
|
||||
});
|
||||
}
|
||||
|
||||
export function compensateFormHandoff(
|
||||
settings: ApiSettings,
|
||||
instanceId: string,
|
||||
effectId: string,
|
||||
changeReason: string
|
||||
): Promise<{ handoff: FormHandoff }> {
|
||||
return apiFetch(settings, `/api/v1/forms-runtime/instances/${encodeURIComponent(instanceId)}/handoffs/${encodeURIComponent(effectId)}/compensate`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
recorded_at: new Date().toISOString(),
|
||||
confirmed_absent: true,
|
||||
change_reason: changeReason
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user