fix: prevent repeated birth-time assessment loops
This commit is contained in:
@@ -86,6 +86,19 @@ type Profile = BirthTimeDraft & {
|
||||
districtCode: string;
|
||||
rectificationCaseId: string;
|
||||
};
|
||||
|
||||
function birthTimeAssessmentSignature(value: BirthTimeDraft) {
|
||||
return [
|
||||
value.date,
|
||||
value.time,
|
||||
value.reportedTime,
|
||||
value.birthTimeSource,
|
||||
value.birthTimePeriod,
|
||||
value.birthTimeClue,
|
||||
value.uncertaintyBeforeMinutes,
|
||||
value.uncertaintyAfterMinutes,
|
||||
].join("|");
|
||||
}
|
||||
type ChartLibraryRecord = {
|
||||
id: string;
|
||||
role: "self" | "other";
|
||||
@@ -741,6 +754,7 @@ export default function Home() {
|
||||
const uiPreview = useRef(false);
|
||||
const uiPreviewMode = useRef<string | null>(null);
|
||||
const birthTimeRevisionPending = useRef(false);
|
||||
const lastBirthTimeAssessmentSignature = useRef("");
|
||||
const birthTimeGuided = useBirthTimeGuidedJourney({
|
||||
journey: birthTimeJourney,
|
||||
preview: process.env.NODE_ENV === "development" && uiPreview.current,
|
||||
@@ -1542,6 +1556,7 @@ export default function Home() {
|
||||
rectificationCaseId: result.caseId,
|
||||
};
|
||||
setBirthTimeJourney(result);
|
||||
lastBirthTimeAssessmentSignature.current = birthTimeAssessmentSignature(nextProfile);
|
||||
setBirthTimeError("");
|
||||
setProfile(assessedProfile);
|
||||
setProfileDraft(assessedProfile);
|
||||
@@ -1603,6 +1618,12 @@ export default function Home() {
|
||||
try {
|
||||
await persistProfile(profileDraft);
|
||||
if (birthTimeRevisionPending.current) {
|
||||
if (lastBirthTimeAssessmentSignature.current === birthTimeAssessmentSignature(profileDraft)) {
|
||||
birthTimeRevisionPending.current = false;
|
||||
setBirthTimeError("出生资料未变化,重新评估会重复同一结果。请补充不同领域且能注明年月的关键经历,再继续校时。");
|
||||
setOnboardingStep("rectification");
|
||||
return;
|
||||
}
|
||||
setBirthTimeAssessmentPhase("assessing");
|
||||
const assessedProfile = await assessSavedBirthTime(profileDraft);
|
||||
birthTimeRevisionPending.current = false;
|
||||
|
||||
@@ -124,8 +124,8 @@ function TerminalAction({ controller, error, path }: {
|
||||
return (
|
||||
<div className="birth-time-new-assessment">
|
||||
<b>尚未达到采用条件</b>
|
||||
<p>候选范围已保留,但当前证据不足以将具体分钟写入当前排盘时间。补充经历后可重新评估。</p>
|
||||
<button className="button-secondary birth-time-guided-action" disabled={controller.pending} onClick={controller.editBirthTimeDetails} type="button">开始新的评估</button>
|
||||
<p>候选范围已保留,但当前证据不足以将具体分钟写入当前排盘时间。请补充不同领域、可注明年月的关键经历;仅重复原出生资料不会生成新结果。</p>
|
||||
<button className="button-secondary birth-time-guided-action" disabled={controller.pending} onClick={controller.editBirthTimeDetails} type="button">修改出生资料后重新评估</button>
|
||||
{error ? <p className="form-error" role="alert">{error}</p> : null}
|
||||
<small>会建立新的记录,当前结果仍会保留。</small>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
} from "@/lib/birth-time-guided-effect-coordinator";
|
||||
import type { StableActionIdentityRegistry } from "@/lib/birth-time-guided-effect-coordinator";
|
||||
import { runBirthTimeScoringPoll, scoringPollDelay } from "@/lib/birth-time-guided-polling";
|
||||
import { birthTimeUserError } from "@/lib/birth-time-user-error";
|
||||
|
||||
type AutomaticEffectsInput = {
|
||||
readonly journey: JourneyClientResponse | null;
|
||||
@@ -82,7 +83,7 @@ export function useBirthTimeAutomaticJourneyEffects(input: AutomaticEffectsInput
|
||||
if (publishCurrentJourney({ expected, current: latest.current, next, publish: onJourney })) latest.current = next;
|
||||
}).catch((caught: unknown) => {
|
||||
if (latest.current?.caseId === expected.caseId && latest.current.turnVersion === expected.turnVersion) {
|
||||
setError(caught instanceof Error ? caught.message : "暂时无法生成下一题,请重试。");
|
||||
setError(birthTimeUserError(caught));
|
||||
}
|
||||
});
|
||||
}, [actionRegistry, generationIdentity, generationRequests, generationRun, latest, onJourney, preview, setError]);
|
||||
@@ -114,7 +115,7 @@ export function useBirthTimeAutomaticJourneyEffects(input: AutomaticEffectsInput
|
||||
latest.current = result.turn;
|
||||
if (result.kind === "exhausted") setError("评分仍在进行。你可以稍后继续,或重新检查状态。");
|
||||
}).catch((caught: unknown) => {
|
||||
if (!controller.signal.aborted) setError(caught instanceof Error ? caught.message : "暂时无法读取评分进度,请稍后重试。");
|
||||
if (!controller.signal.aborted) setError(birthTimeUserError(caught));
|
||||
});
|
||||
});
|
||||
return () => { cancelStart(); controller.abort(); };
|
||||
|
||||
@@ -18,4 +18,6 @@ test("all guided journey mutations normalize implementation errors", () => {
|
||||
const source = readFileSync(new URL("../src/hooks/use-birth-time-guided-journey.ts", import.meta.url), "utf8");
|
||||
assert.ok((source.match(/setError\(birthTimeUserError\(caught\)\)/g) ?? []).length >= 1);
|
||||
assert.equal(source.includes("setError(caught.message"), false);
|
||||
const automatic = readFileSync(new URL("../src/hooks/use-birth-time-automatic-journey-effects.ts", import.meta.url), "utf8");
|
||||
assert.equal((automatic.match(/setError\(birthTimeUserError\(caught\)\)/g) ?? []).length, 2);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user