import { apiFetch, apiPath, type ApiSettings } from "@govoplan/core-webui"; export type CommitteeObjectKind = "body" | "meeting" | "agenda_item" | "vote" | "minute"; export type CommitteeRecord = { tenant_id: string; object_kind: CommitteeObjectKind; object_id: string; revision: number; state: string; title: string; parent_id?: string | null; recorded_at: string; change_reason: string; attributes: Record; context?: Record | null; evidence: Array>; record_refs: Array>; }; export type CommitteeRecordList = { records: CommitteeRecord[]; total: number; offset: number; limit: number; }; export function listCommitteeRecords( settings: ApiSettings, kind: CommitteeObjectKind, options: { parentId?: string; query?: string; states?: string[]; limit?: number; } = {}, signal?: AbortSignal ): Promise { return apiFetch( settings, apiPath(`/api/v1/committee/workspace/${kind}`, { parent_id: options.parentId, query: options.query, state: options.states, limit: options.limit ?? 200 }), { signal } ); } export function saveCommitteeRecord( settings: ApiSettings, record: CommitteeRecord, expectedRevision?: number ): Promise { return apiFetch( settings, `/api/v1/committee/workspace/${record.object_kind}`, { method: "POST", body: JSON.stringify({ record, idempotency_key: crypto.randomUUID(), expected_revision: expectedRevision }) } ); } export function committeeRecordHistory( settings: ApiSettings, record: CommitteeRecord, signal?: AbortSignal ): Promise<{ revisions: CommitteeRecord[] }> { return apiFetch( settings, `/api/v1/committee/workspace/${record.object_kind}/${encodeURIComponent(record.object_id)}/history`, { signal } ); } export function finalizeProviderBallot( settings: ApiSettings, record: CommitteeRecord, input: { providerBallotRef: string; approvalId: string; changeReason: string; } ): Promise { const providerId = String(record.attributes.provider_id ?? "").trim(); return apiFetch( settings, `/api/v1/committee/workspace/vote/${encodeURIComponent(record.object_id)}/finalize-provider`, { method: "POST", body: JSON.stringify({ provider_id: providerId, provider_ballot_ref: input.providerBallotRef.trim(), approval_ref: { kind: "approval", owner_module: "approvals", object_id: input.approvalId.trim(), tenant_id: record.tenant_id, version: "1" }, expected_revision: record.revision, recorded_at: new Date().toISOString(), change_reason: input.changeReason.trim(), idempotency_key: crypto.randomUUID() }) } ); } export async function finalizeVotingBallot( settings: ApiSettings, record: CommitteeRecord, input: { approvalId: string; changeReason: string; } ): Promise { const ballotId = String(record.attributes.voting_ballot_id ?? "").trim(); const ballot = await apiFetch<{ revision: number }>( settings, `/api/v1/voting/${encodeURIComponent(ballotId)}` ); return apiFetch( settings, `/api/v1/committee/workspace/vote/${encodeURIComponent(record.object_id)}/finalize-voting`, { method: "POST", body: JSON.stringify({ voting_ballot_id: ballotId, voting_expected_revision: ballot.revision, approval_ref: { kind: "approval", owner_module: "approvals", object_id: input.approvalId.trim(), tenant_id: record.tenant_id, version: "1" }, expected_revision: record.revision, recorded_at: new Date().toISOString(), change_reason: input.changeReason.trim(), idempotency_key: crypto.randomUUID() }) } ); }