mirror of
https://github.com/morluto/rea.git
synced 2026-11-07 07:16:13 +00:00
Move shared request parsing into its application owner, migrate all consumers, and remove six duplicated admission blocks while preserving cancellation and validation policy. Keep operator-selected JavaScript paths in verifier parent Evidence while retaining canonical comparison guards. Validated with 204 passing tests, 3 Linux-x64-only skips, typecheck, lint, and test discovery.
78 lines
2.6 KiB
TypeScript
78 lines
2.6 KiB
TypeScript
import { parseAnalysisInput } from "./AnalysisInput.js";
|
|
import { z } from "zod";
|
|
|
|
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
|
import type { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
import type { Evidence } from "../domain/evidence.js";
|
|
import {
|
|
readEvidenceBundle,
|
|
type EvidenceBundle,
|
|
} from "../domain/evidenceBundle.js";
|
|
import {
|
|
reconstructionObligationLedgerInputSchema,
|
|
type ReviewedReconstructionObligation,
|
|
type ReconstructionObligationManifest,
|
|
} from "../domain/reconstructionObligationLedgerSchemas.js";
|
|
import { err, ok, type Result } from "../domain/result.js";
|
|
|
|
const OPERATION = "build_reconstruction_obligation_ledger";
|
|
const requestSchema = reconstructionObligationLedgerInputSchema.extend({
|
|
evidence_bundle: z.unknown(),
|
|
});
|
|
|
|
/** Authenticated bundle and its single request-owned record index. */
|
|
export interface ReconstructionObligationSources {
|
|
readonly bundle: EvidenceBundle;
|
|
readonly records: ReadonlyMap<string, Evidence>;
|
|
}
|
|
|
|
export interface ResolvedReconstructionObligationRequest {
|
|
readonly sources: ReconstructionObligationSources;
|
|
readonly reviewedObligations: readonly ReviewedReconstructionObligation[];
|
|
readonly manifest: ReconstructionObligationManifest;
|
|
}
|
|
|
|
/** Authenticate the source bundle and bind every selected review reference. */
|
|
export const resolveReconstructionObligationLedgerRequest = (
|
|
input: unknown,
|
|
): Result<ResolvedReconstructionObligationRequest, AnalysisError> => {
|
|
const frame = parseAnalysisInput(OPERATION, input, requestSchema);
|
|
if (!frame.ok) return frame;
|
|
const bundle = readEvidenceBundle(frame.value.evidence_bundle);
|
|
if (!bundle.ok) return bundle;
|
|
const records = new Map(
|
|
bundle.value.records.map((record) => [record.evidence_id, record]),
|
|
);
|
|
for (const [
|
|
index,
|
|
obligation,
|
|
] of frame.value.reviewed_obligations.entries()) {
|
|
for (const [
|
|
referenceIndex,
|
|
id,
|
|
] of obligation.review_evidence_ids.entries()) {
|
|
if (records.has(id)) continue;
|
|
const message = `Reviewed obligation Evidence is missing: ${id}`;
|
|
return err(
|
|
new AnalysisInputError(OPERATION, { userMessage: message }, [
|
|
{
|
|
path: [
|
|
"reviewed_obligations",
|
|
index,
|
|
"review_evidence_ids",
|
|
referenceIndex,
|
|
],
|
|
reason: "invalid_value",
|
|
message,
|
|
},
|
|
]),
|
|
);
|
|
}
|
|
}
|
|
return ok({
|
|
sources: { bundle: bundle.value, records },
|
|
reviewedObligations: frame.value.reviewed_obligations,
|
|
manifest: frame.value.manifest,
|
|
});
|
|
};
|