Files
govoplan-cases/webui/src/api/cases.ts
T

181 lines
4.3 KiB
TypeScript

import {
apiFetch,
apiPath,
apiReferenceOptionProvider,
type ApiSettings,
type ReferenceOptionProvider
} from "@govoplan/core-webui";
export type InstitutionalReference = {
kind: string;
owner_module: string;
object_id: string;
tenant_id: string;
version?: string | null;
};
export type EvidenceReference = {
kind: string;
owner_module: string;
evidence_id: string;
tenant_id: string;
version?: string | null;
};
export type CaseRecord = {
reference: InstitutionalReference;
revision: number;
case_number: string;
case_type_key: string;
status_key: string;
title: string;
access_mode: "tenant" | "restricted";
access_grants: CaseGrant[];
context: Record<string, unknown>;
service_ref?: InstitutionalReference | null;
party_refs: InstitutionalReference[];
assignment_refs: InstitutionalReference[];
evidence_refs: EvidenceReference[];
decision_refs: InstitutionalReference[];
record_refs: InstitutionalReference[];
opened_at: string;
recorded_at: string;
deadline_at?: string | null;
closed_at?: string | null;
change_reason: string;
metadata: Record<string, unknown>;
};
export type CaseGrant = {
subject_kind: "account" | "identity" | "group" | "role" | "function" | "function_assignment" | "organization_unit" | "service_account";
subject_id: string;
permissions: Array<"read" | "update" | "share" | "admin">;
};
export type CaseStatusDefinition = {
status_key: string;
label: string;
category: string;
terminal: boolean;
sort_order: number;
active: boolean;
revision: number;
};
export type CaseTypeDefinition = {
type_key: string;
label: string;
description?: string | null;
initial_status_key: string;
allowed_status_keys: string[];
active: boolean;
revision: number;
};
export type CaseCatalog = {
statuses: CaseStatusDefinition[];
types: CaseTypeDefinition[];
};
export type CaseListResponse = {
cases: CaseRecord[];
total: number;
offset: number;
limit: number;
};
export type CaseTimelineEntry = {
event_id: string;
event_type: string;
case_revision: number;
summary: string;
actor_id?: string | null;
occurred_at: string;
audit_event_id?: string | null;
payload: Record<string, unknown>;
};
export function listCases(
settings: ApiSettings,
options: {
query?: string;
statuses?: string[];
caseTypes?: string[];
offset?: number;
limit?: number;
},
signal?: AbortSignal
): Promise<CaseListResponse> {
return apiFetch<CaseListResponse>(settings, apiPath("/api/v1/cases", {
query: options.query,
status_key: options.statuses,
case_type_key: options.caseTypes,
offset: options.offset,
limit: options.limit
}), { signal });
}
export function getCase(
settings: ApiSettings,
caseId: string,
signal?: AbortSignal
): Promise<CaseRecord> {
return apiFetch<CaseRecord>(settings, `/api/v1/cases/${encodeURIComponent(caseId)}`, { signal });
}
export function listCaseCatalog(
settings: ApiSettings,
signal?: AbortSignal
): Promise<CaseCatalog> {
return apiFetch<CaseCatalog>(settings, "/api/v1/cases/catalog", { signal });
}
export function caseHistory(
settings: ApiSettings,
caseId: string,
signal?: AbortSignal
): Promise<{ revisions: CaseRecord[] }> {
return apiFetch(settings, `/api/v1/cases/${encodeURIComponent(caseId)}/history`, { signal });
}
export function caseTimeline(
settings: ApiSettings,
caseId: string,
signal?: AbortSignal
): Promise<{ entries: CaseTimelineEntry[] }> {
return apiFetch(settings, `/api/v1/cases/${encodeURIComponent(caseId)}/timeline`, { signal });
}
export function updateCase(
settings: ApiSettings,
caseId: string,
payload: {
expected_revision: number;
recorded_at: string;
change_reason: string;
idempotency_key: string;
title?: string;
status_key?: string;
access_mode?: "tenant" | "restricted";
access_grants?: CaseGrant[];
}
): Promise<CaseRecord> {
return apiFetch<CaseRecord>(settings, `/api/v1/cases/${encodeURIComponent(caseId)}`, {
method: "PATCH",
body: JSON.stringify(payload)
});
}
export function caseShareTargetProvider(
settings: ApiSettings,
caseId: string,
targetType: "user" | "group"
): ReferenceOptionProvider {
return apiReferenceOptionProvider(
settings,
`/api/v1/cases/${encodeURIComponent(caseId)}/share-target-options`,
{ target_type: targetType }
);
}