import { apiFetch, apiPath, type ApiSettings } from "@govoplan/core-webui"; export type InstitutionalReference = { kind: string; owner_module: string; object_id: string; tenant_id: string; version?: string | null; valid_at?: string | null; label?: string | null; }; export type EvidenceReference = { kind: string; owner_module: string; evidence_id: string; tenant_id: string; 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; value_type: "text" | "multiline_text" | "integer" | "number" | "boolean" | "date" | "datetime" | "email" | "choice" | "multi_choice" | "object" | "list"; required: boolean; help_text?: string | null; options: string[]; constraints: Record; default_value?: unknown; visibility_condition?: FormCondition | null; }; export type FormDefinition = { reference: InstitutionalReference; key: string; temporal: { revision: string; recorded_at?: string | null }; title: string; description?: string | null; fields: FormFieldDefinition[]; publication_state: "draft" | "published" | "retired"; allow_drafts: boolean; max_attachments: number; 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; field_help_texts: Record; option_labels: Record>; page_titles: Record; section_titles: Record; }>; }; export type ValidationResult = { field?: string | null; severity: "warning" | "error"; code: string; message: string; }; export type FormInstance = { reference: InstitutionalReference; tenant_id: string; instance_id: string; revision: number; status: string; definition_ref: InstitutionalReference; values: Record; validation_results: ValidationResult[]; attachment_refs: EvidenceReference[]; signature_refs: EvidenceReference[]; handoff_refs: InstitutionalReference[]; service_ref?: InstitutionalReference | null; receipt_id?: string | null; recorded_at: string; change_reason: string; created_by: string; changed_by: string; replayed: boolean; }; export type FormInstanceEvent = { event_id: string; event_type: string; instance_revision: number; status: string; occurred_at: string; actor_id: string; payload: Record; }; 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; }; export function listFormInstances( settings: ApiSettings, options: { statuses?: string[]; definitionId?: string; offset?: number; limit?: number } = {}, signal?: AbortSignal ): Promise<{ instances: FormInstance[]; total: number; offset: number; limit: number }> { return apiFetch(settings, apiPath("/api/v1/forms-runtime/instances", { status: options.statuses, definition_id: options.definitionId, offset: options.offset ?? 0, limit: options.limit ?? 100 }), { signal }); } export function getFormInstance( settings: ApiSettings, instanceId: string, signal?: AbortSignal ): Promise { return apiFetch(settings, `/api/v1/forms-runtime/instances/${encodeURIComponent(instanceId)}`, { signal }); } export function getFormDefinition( settings: ApiSettings, instanceId: string, signal?: AbortSignal ): Promise { return apiFetch( settings, `/api/v1/forms-runtime/instances/${encodeURIComponent(instanceId)}/definition`, { signal } ); } export function getFormInstanceHistory( settings: ApiSettings, instanceId: string, signal?: AbortSignal ): Promise<{ revisions: FormInstance[] }> { return apiFetch(settings, `/api/v1/forms-runtime/instances/${encodeURIComponent(instanceId)}/history`, { signal }); } export function getFormInstanceEvents( settings: ApiSettings, instanceId: string, signal?: AbortSignal ): Promise<{ events: FormInstanceEvent[] }> { return apiFetch(settings, `/api/v1/forms-runtime/instances/${encodeURIComponent(instanceId)}/events`, { signal }); } export function saveFormDraft( settings: ApiSettings, instance: FormInstance, values: Record, changeReason: string ): Promise { return apiFetch(settings, `/api/v1/forms-runtime/instances/${encodeURIComponent(instance.instance_id)}`, { method: "PATCH", body: JSON.stringify({ expected_revision: instance.revision, values, attachment_refs: instance.attachment_refs, signature_refs: instance.signature_refs, idempotency_key: crypto.randomUUID(), recorded_at: new Date().toISOString(), change_reason: changeReason }) }); } export function submitFormInstance( settings: ApiSettings, instance: FormInstance, values: Record ): Promise { return apiFetch(settings, `/api/v1/forms-runtime/instances/${encodeURIComponent(instance.instance_id)}/submit`, { method: "POST", body: JSON.stringify({ expected_revision: instance.revision, values, attachment_refs: instance.attachment_refs, signature_refs: instance.signature_refs, idempotency_key: crypto.randomUUID(), recorded_at: new Date().toISOString() }) }); } 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 }) }); }