merge: synchronize remote main

This commit is contained in:
Jesse_Chen
2026-07-21 22:57:50 +08:00
130 changed files with 10441 additions and 553 deletions
@@ -3,7 +3,6 @@
import { useCallback, useEffect, useRef, useState } from "react";
import {
answerDynamicBirthTimeChoice,
confirmDynamicBirthTimeCandidate,
confirmBirthTimeEvidenceDraft,
draftBirthTimeEvidence,
finishBirthTimeRectification,
@@ -15,7 +14,6 @@ import {
} from "@/lib/birth-time-journey-client";
import type { JourneyClientResponse } from "@/lib/birth-time-journey-client";
import {
completeGuidedBirthTimeCandidate,
confirmGuidedBirthTimeCandidate,
reviseBirthTimeEvidenceDraft,
saveGuidedBirthTimeCandidate,
@@ -38,7 +36,6 @@ type GuidedJourneyInput = {
readonly preview: boolean;
readonly onJourney: (journey: JourneyClientResponse) => void;
readonly onReady: (journey: JourneyClientResponse) => void;
readonly onCandidateComplete: (journey: JourneyClientResponse, time: string) => void;
readonly onEditBirthTimeDetails: () => void;
};
@@ -54,7 +51,6 @@ export type BirthTimeGuidedController = {
readonly resume: () => void;
readonly editBirthTimeDetails: () => void;
readonly acknowledgeReady: () => void;
readonly completeCandidate: (time: string) => void;
readonly retryScoring: () => void;
readonly saveCandidate: (resultId: string) => void;
readonly confirmCandidate: (resultId: string, time: string) => void;
@@ -71,7 +67,7 @@ function previewAction(turn: JourneyClientResponse, command: DynamicPreviewComma
}
export function useBirthTimeGuidedJourney(input: GuidedJourneyInput): BirthTimeGuidedController {
const { journey, onJourney, onReady, onCandidateComplete, onEditBirthTimeDetails, preview } = input;
const { journey, onJourney, onReady, onEditBirthTimeDetails, preview } = input;
const latest = useRef(journey);
const busy = useRef(false);
const [actionRegistry] = useState(() => createStableActionIdentityRegistry());
@@ -186,27 +182,6 @@ export function useBirthTimeGuidedJourney(input: GuidedJourneyInput): BirthTimeG
const acknowledgeReady = () => {
if (journey?.nextAction.kind === "ready") onReady(journey);
};
const completeCandidate = (time: string) => {
const turn = journey;
const resultId = turn?.candidateResult?.resultId;
const winner = turn?.candidateResult?.winningSegment;
if (!turn || !resultId || winner?.representativeTime !== time) return;
if (turn.journeyProtocol === "dynamic-choice-v2") return;
const release = claimMutation(busy);
if (release === null) return;
setPending(true);
setError("");
const completion = preview
? Promise.resolve()
: completeGuidedBirthTimeCandidate({ caseId: turn.caseId, resultId, time });
void completion
.then(() => onCandidateComplete(turn, time))
.catch((caught) => setError(birthTimeUserError(caught)))
.finally(() => {
release();
setPending(false);
});
};
const retryScoring = () => {
const turn = journey;
if (preview && turn?.journeyProtocol === "dynamic-choice-v2"
@@ -228,10 +203,8 @@ export function useBirthTimeGuidedJourney(input: GuidedJourneyInput): BirthTimeG
(actionId) => saveGuidedBirthTimeCandidate({ caseId: turn.caseId, actionId, turnVersion: turn.turnVersion, resultId }),
));
const confirmCandidate = (resultId: string, time: string) => operate((turn) => preview ? Promise.resolve(turn) : stableAction(
turn, turn.journeyProtocol === "dynamic-choice-v2" ? "confirm_dynamic_candidate" : "confirm_guided_candidate", [resultId, time],
(actionId) => turn.journeyProtocol === "dynamic-choice-v2"
? confirmDynamicBirthTimeCandidate({ caseId: turn.caseId, actionId, turnVersion: turn.turnVersion, resultId, time })
: confirmGuidedBirthTimeCandidate({ caseId: turn.caseId, actionId, turnVersion: turn.turnVersion, resultId, time }),
turn, "confirm_guided_candidate", [resultId, time],
(actionId) => confirmGuidedBirthTimeCandidate({ caseId: turn.caseId, actionId, turnVersion: turn.turnVersion, resultId, time }),
));
const selectOption = (optionId: string) => operate((turn) => {
if (turn.journeyProtocol !== "dynamic-choice-v2"
@@ -281,7 +254,6 @@ export function useBirthTimeGuidedJourney(input: GuidedJourneyInput): BirthTimeG
resume,
editBirthTimeDetails: onEditBirthTimeDetails,
acknowledgeReady,
completeCandidate,
retryScoring,
saveCandidate,
confirmCandidate,