feat(records): govern lifecycle recovery and transfer evidence
This commit is contained in:
@@ -12,6 +12,12 @@ export type FilePlanNode = {
|
||||
valid_from?: string | null;
|
||||
valid_to?: string | null;
|
||||
recorded_at: string;
|
||||
closed_at?: string | null;
|
||||
retention_started_at?: string | null;
|
||||
retention_due_at?: string | null;
|
||||
retention_rule: Record<string, unknown>;
|
||||
appraisal_state?: string | null;
|
||||
appraisal: Record<string, unknown>;
|
||||
institutional_context: Record<string, unknown>;
|
||||
};
|
||||
|
||||
@@ -99,11 +105,63 @@ export type RecordChronology = {
|
||||
payload: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type RecordHold = {
|
||||
hold_id: string;
|
||||
record_id: string;
|
||||
revision: number;
|
||||
status: string;
|
||||
reason: string;
|
||||
authority: string;
|
||||
scope: Record<string, unknown>;
|
||||
effective_from: string;
|
||||
effective_to?: string | null;
|
||||
released_at?: string | null;
|
||||
policy_refs: string[];
|
||||
recorded_at: string;
|
||||
};
|
||||
|
||||
export type RecordDisposition = {
|
||||
disposition_id: string;
|
||||
record_id: string;
|
||||
revision: number;
|
||||
action: "retain" | "transfer" | "destroy" | "reclassify";
|
||||
status: string;
|
||||
reason: string;
|
||||
subject_revision: number;
|
||||
subject_sha256: string;
|
||||
consequence_preview: Record<string, unknown>;
|
||||
policy_refs: string[];
|
||||
approval_request_id?: string | null;
|
||||
proposed_by?: string | null;
|
||||
reviewed_by?: string | null;
|
||||
reviewed_at?: string | null;
|
||||
recorded_at: string;
|
||||
};
|
||||
|
||||
export type RecordTransferPackage = {
|
||||
package_id: string;
|
||||
record_id: string;
|
||||
disposition_id: string;
|
||||
revision: number;
|
||||
record_revision: number;
|
||||
provider_id: string;
|
||||
profile: string;
|
||||
status: string;
|
||||
manifest_sha256: string;
|
||||
receipt_sha256?: string | null;
|
||||
external_reference?: string | null;
|
||||
simulated: boolean;
|
||||
recorded_at: string;
|
||||
};
|
||||
|
||||
export type RecordDetail = {
|
||||
record: RecordEntry;
|
||||
volumes: RecordVolume[];
|
||||
items: RecordItem[];
|
||||
chronology: RecordChronology[];
|
||||
holds: RecordHold[];
|
||||
dispositions: RecordDisposition[];
|
||||
transfer_packages: RecordTransferPackage[];
|
||||
access_explanation: {
|
||||
decision: string;
|
||||
reason: string;
|
||||
@@ -120,6 +178,19 @@ export type RecordSourceProvider = {
|
||||
resource_types: string[];
|
||||
};
|
||||
|
||||
export type RecordArchiveProvider = {
|
||||
id: string;
|
||||
label: string;
|
||||
profiles: string[];
|
||||
authority_modes: string[];
|
||||
healthy: boolean;
|
||||
checked_at: string;
|
||||
last_success_at?: string | null;
|
||||
freshness_seconds?: number | null;
|
||||
limitations: string[];
|
||||
simulated: boolean;
|
||||
};
|
||||
|
||||
export function listRecords(
|
||||
settings: ApiSettings,
|
||||
options: {
|
||||
@@ -154,6 +225,24 @@ export function getRecordSources(settings: ApiSettings, signal?: AbortSignal): P
|
||||
return apiFetch(settings, "/api/v1/records/sources", { signal });
|
||||
}
|
||||
|
||||
export function getRecordArchiveProviders(settings: ApiSettings, signal?: AbortSignal): Promise<{ providers: RecordArchiveProvider[] }> {
|
||||
return apiFetch(settings, "/api/v1/records/archive-providers", { signal });
|
||||
}
|
||||
|
||||
export function writeFilePlanNode(settings: ApiSettings, payload: Record<string, unknown>): Promise<FilePlanNode> {
|
||||
return apiFetch(settings, "/api/v1/records/catalog/file-plan", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
export function writeRecordClass(settings: ApiSettings, payload: Record<string, unknown>): Promise<RecordClass> {
|
||||
return apiFetch(settings, "/api/v1/records/catalog/classes", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
export function createRecord(settings: ApiSettings, payload: Record<string, unknown>): Promise<RecordEntry> {
|
||||
return apiFetch(settings, "/api/v1/records", {
|
||||
method: "POST",
|
||||
@@ -182,3 +271,99 @@ export function fileRecordItem(
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
export function createRecordVolume(
|
||||
settings: ApiSettings,
|
||||
recordId: string,
|
||||
payload: Record<string, unknown>
|
||||
): Promise<RecordVolume> {
|
||||
return recordMutation(settings, recordId, "volumes", payload);
|
||||
}
|
||||
|
||||
export function closeRecord(settings: ApiSettings, recordId: string, payload: Record<string, unknown>): Promise<RecordEntry> {
|
||||
return recordMutation(settings, recordId, "close", payload);
|
||||
}
|
||||
|
||||
export function reopenRecord(settings: ApiSettings, recordId: string, payload: Record<string, unknown>): Promise<RecordEntry> {
|
||||
return recordMutation(settings, recordId, "reopen", payload);
|
||||
}
|
||||
|
||||
export function appraiseRecord(settings: ApiSettings, recordId: string, payload: Record<string, unknown>): Promise<RecordEntry> {
|
||||
return recordMutation(settings, recordId, "appraise", payload);
|
||||
}
|
||||
|
||||
export function applyRecordHold(settings: ApiSettings, recordId: string, payload: Record<string, unknown>): Promise<RecordHold> {
|
||||
return recordMutation(settings, recordId, "holds", payload);
|
||||
}
|
||||
|
||||
export function releaseRecordHold(
|
||||
settings: ApiSettings,
|
||||
recordId: string,
|
||||
holdId: string,
|
||||
payload: Record<string, unknown>
|
||||
): Promise<RecordHold> {
|
||||
return recordMutation(settings, recordId, `holds/${encodeURIComponent(holdId)}/release`, payload);
|
||||
}
|
||||
|
||||
export function proposeRecordDisposition(
|
||||
settings: ApiSettings,
|
||||
recordId: string,
|
||||
payload: Record<string, unknown>
|
||||
): Promise<RecordDisposition> {
|
||||
return recordMutation(settings, recordId, "dispositions", payload);
|
||||
}
|
||||
|
||||
export function finalizeRecordDisposition(
|
||||
settings: ApiSettings,
|
||||
recordId: string,
|
||||
dispositionId: string,
|
||||
payload: Record<string, unknown>
|
||||
): Promise<{ disposition: RecordDisposition; record: RecordEntry }> {
|
||||
return recordMutation(settings, recordId, `dispositions/${encodeURIComponent(dispositionId)}/finalize`, payload);
|
||||
}
|
||||
|
||||
export function withdrawRecordDisposition(
|
||||
settings: ApiSettings,
|
||||
recordId: string,
|
||||
dispositionId: string,
|
||||
payload: Record<string, unknown>
|
||||
): Promise<RecordDisposition> {
|
||||
return recordMutation(settings, recordId, `dispositions/${encodeURIComponent(dispositionId)}/withdraw`, payload);
|
||||
}
|
||||
|
||||
export function prepareRecordTransfer(
|
||||
settings: ApiSettings,
|
||||
recordId: string,
|
||||
payload: Record<string, unknown>
|
||||
): Promise<RecordTransferPackage> {
|
||||
return recordMutation(settings, recordId, "transfer-packages", payload);
|
||||
}
|
||||
|
||||
export function dispatchRecordTransfer(
|
||||
settings: ApiSettings,
|
||||
recordId: string,
|
||||
packageId: string,
|
||||
payload: Record<string, unknown>
|
||||
): Promise<RecordTransferPackage> {
|
||||
return recordMutation(settings, recordId, `transfer-packages/${encodeURIComponent(packageId)}/dispatch`, payload);
|
||||
}
|
||||
|
||||
export function getRecordRecoveryStatus(
|
||||
settings: ApiSettings,
|
||||
recordId: string,
|
||||
signal?: AbortSignal
|
||||
): Promise<Record<string, unknown>> {
|
||||
return apiFetch(settings, `/api/v1/records/${encodeURIComponent(recordId)}/recovery`, { signal });
|
||||
}
|
||||
|
||||
function recordMutation<T>(
|
||||
settings: ApiSettings,
|
||||
recordId: string,
|
||||
path: string,
|
||||
payload: Record<string, unknown>
|
||||
): Promise<T> {
|
||||
return apiFetch(settings, `/api/v1/records/${encodeURIComponent(recordId)}/${path}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user