Files
Jyotisha/frontend/src/lib/birth-time-guided-draft-revision.ts
T
732642856 4ceb3a5157 feat: enforce commercial rectification evidence contracts
* feat: enforce precise timing output contract

* fix: recognize package imports in fragment audit

* test: make workflow stream contract formatting-independent

* fix: preserve VedAstro evidence across async workflows

* feat: enforce commercial technique truth contract

* feat: add rectification technique receipt

* feat: extend rectification event evidence

* feat: score rectification arudha evidence

* feat: gate high rigor rectification confirmation

* feat: add controlled transit to rectification

* feat: include d11 in rectification finance scoring

* feat: add ashtakavarga rectification auxiliary

* feat: show rectification technique receipt

* feat: use verified shadbala components in rectification

* fix: trace transitive script references in fragment audit

* feat: run request-level rectification parity packet
2026-07-19 22:23:29 +08:00

57 lines
2.5 KiB
TypeScript

import { lifeEventSchema } from "./birth-time-evidence.ts";
import { assertNotDynamicJourneyMutation } from "./birth-time-evidence-service.ts";
import { currentJourneyTurn, storedJourneyResponse } from "./birth-time-journey-response.ts";
import type { VersionedJourneyResponse } from "./birth-time-journey-service.ts";
import type { JourneyTurnPersistencePorts } from "./birth-time-scoring-job-persistence.ts";
import { BirthTimeJourneyActionError } from "./birth-time-journey-actions.ts";
import { StaleJourneyTurnError } from "./birth-time-journey-turn-persistence.ts";
import type { EvidenceDatePrecision } from "./birth-time-question-planner.ts";
type ProposeDraft = (
userId: string,
caseId: string,
actionId: string,
expectedVersion: number,
proposal: { readonly domain: "education" | "relocation" | "relationship" | "career" | "finance" | "health_pressure"; readonly precision: EvidenceDatePrecision; readonly date: string },
) => Promise<VersionedJourneyResponse>;
type DraftRevision = {
readonly userId: string;
readonly caseId: string;
readonly actionId: string;
readonly expectedVersion: number;
readonly precision: EvidenceDatePrecision;
readonly date: string;
};
export function createGuidedDraftRevisionActions(
ports: JourneyTurnPersistencePorts,
proposeDraft: ProposeDraft,
) {
return {
async revise(input: DraftRevision) {
const stored = await ports.store.loadCase(input.userId, input.caseId);
if (!stored) throw new BirthTimeJourneyActionError("case_not_found", input.caseId);
assertNotDynamicJourneyMutation(stored);
if (stored.processedActionIds?.includes(input.actionId.toLowerCase())) {
return storedJourneyResponse(stored);
}
const currentVersion = stored.turnVersion ?? 0;
if (currentVersion !== input.expectedVersion) {
throw new StaleJourneyTurnError(stored.id, input.expectedVersion, currentVersion);
}
const current = currentJourneyTurn(stored);
const draft = stored.evidenceDraft ?? current.evidenceDraft;
if (
current.nextAction.kind !== "review_evidence_draft"
|| current.nextAction.draftId !== draft?.draftId
) throw new BirthTimeJourneyActionError("invalid_turn", input.caseId);
lifeEventSchema.parse({ id: draft.draftId, domain: draft.domain, precision: input.precision, date: input.date });
return proposeDraft(input.userId, input.caseId, input.actionId, input.expectedVersion, {
domain: draft.domain,
precision: input.precision,
date: input.date,
});
},
};
}