diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 1959c3cd..fb1dc796 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -747,7 +747,6 @@ export default function Home() { preview: process.env.NODE_ENV === "development" && uiPreview.current, onJourney: setBirthTimeJourney, onReady: completeGuidedBirthTime, - onCandidateComplete: completeCandidateBirthTime, onEditBirthTimeDetails: editDeclaredBirthTimeDetails, }); @@ -1019,7 +1018,7 @@ export default function Home() { setSessions(nextSessions); setActiveSessionId(nextSessions[0].id); if ((nextProfile.birthTimeStatus === "rectifying" - || (nextProfile.birthTimeStatus === "candidate" && !nextProfile.time)) + || nextProfile.birthTimeStatus === "candidate") && nextProfile.rectificationCaseId) { try { const resumed = await resumeBirthTimeJourney(nextProfile.rectificationCaseId); @@ -1657,21 +1656,6 @@ export default function Home() { setOnboardingJustCompleted(true); } - function completeCandidateBirthTime(result: JourneyClientResponse, time: string) { - const candidateProfile: Profile = { - ...profileDraft, - time, - birthTimeStatus: "candidate", - rectificationCaseId: result.caseId, - }; - setProfile(candidateProfile); - setProfileDraft(candidateProfile); - setBirthTimeJourney(null); - setPresetMessageLength(0); - setStartGreeting(createStartGreeting(candidateProfile.name)); - setOnboardingJustCompleted(true); - } - async function retryBirthTimeAssessment() { if (!account || profileSaving) return; setProfileSaving(true); diff --git a/frontend/src/hooks/use-birth-time-guided-journey.ts b/frontend/src/hooks/use-birth-time-guided-journey.ts index 8fac6fbb..7d005fa8 100644 --- a/frontend/src/hooks/use-birth-time-guided-journey.ts +++ b/frontend/src/hooks/use-birth-time-guided-journey.ts @@ -14,7 +14,6 @@ import { } from "@/lib/birth-time-journey-client"; import type { JourneyClientResponse } from "@/lib/birth-time-journey-client"; import { - completeGuidedBirthTimeCandidate, confirmGuidedBirthTimeCandidate, reviseBirthTimeEvidenceDraft, saveGuidedBirthTimeCandidate, @@ -37,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; }; @@ -53,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; @@ -70,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()); @@ -185,26 +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; - 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" @@ -277,7 +254,6 @@ export function useBirthTimeGuidedJourney(input: GuidedJourneyInput): BirthTimeG resume, editBirthTimeDetails: onEditBirthTimeDetails, acknowledgeReady, - completeCandidate, retryScoring, saveCandidate, confirmCandidate, diff --git a/frontend/src/lib/birth-time-guided-client.ts b/frontend/src/lib/birth-time-guided-client.ts index 89bd035c..48261848 100644 --- a/frontend/src/lib/birth-time-guided-client.ts +++ b/frontend/src/lib/birth-time-guided-client.ts @@ -16,7 +16,6 @@ type DraftRevision = GuidedMutation & { }; type CandidateSave = GuidedMutation & { readonly resultId: string }; type CandidateConfirmation = CandidateSave & { readonly time: string }; -type CandidateCompletion = Pick & { readonly time: string }; const errorPayloadSchema = z.object({ message: z.string().optional(), @@ -69,22 +68,3 @@ export function confirmGuidedBirthTimeCandidate( ) { return send({ type: "confirm_guided_candidate", ...input }); } - -export async function completeGuidedBirthTimeCandidate( - input: CandidateCompletion, -) { - const { response, payload } = await postJson({ - url: "/api/birth-time-candidate-completion", - body: JSON.stringify(input), - retryLostResponse: false, - }); - if (!response.ok) { - const parsed = errorPayloadSchema.safeParse(payload); - throw new GuidedBirthTimeRequestError( - response.status, - parsed.success - ? parsed.data.message ?? parsed.data.error ?? "候选时间暂时无法保存" - : "候选时间暂时无法保存", - ); - } -} diff --git a/frontend/src/lib/birth-time-intake-model.ts b/frontend/src/lib/birth-time-intake-model.ts index 5f8fd379..a79f2685 100644 --- a/frontend/src/lib/birth-time-intake-model.ts +++ b/frontend/src/lib/birth-time-intake-model.ts @@ -154,7 +154,7 @@ export function isBirthTimeDraftReady(draft: BirthTimeDraft) { export function isBirthTimeReadyForConsultation(draft: BirthTimeDraft) { return Boolean(draft.time) - && (draft.birthTimeStatus === "candidate" || draft.birthTimeStatus === "confirmed"); + && draft.birthTimeStatus === "confirmed"; } export function birthTimePersistenceValues(draft: BirthTimeDraft) { diff --git a/frontend/tests/birth-time-guided-review-fixes.test.ts b/frontend/tests/birth-time-guided-review-fixes.test.ts index 61c62405..50101679 100644 --- a/frontend/tests/birth-time-guided-review-fixes.test.ts +++ b/frontend/tests/birth-time-guided-review-fixes.test.ts @@ -118,6 +118,8 @@ test("ready completion is explicit and terminal low has no finish mutation", () assert.doesNotMatch(hookSource, /turn\.nextAction\.kind === "ready"\) onReady/); assert.match(candidateSource, /acknowledgeReady/); assert.doesNotMatch(candidateSource, /controller\.finish/); + assert.doesNotMatch(hookSource, /completeGuidedBirthTimeCandidate/); + assert.doesNotMatch(hookSource, /completeCandidate:/); }); test("unconfirmed terminal candidates preserve the range without offering direct adoption", () => { diff --git a/frontend/tests/birth-time-intake.test.ts b/frontend/tests/birth-time-intake.test.ts index 08ac8b03..65feb293 100644 --- a/frontend/tests/birth-time-intake.test.ts +++ b/frontend/tests/birth-time-intake.test.ts @@ -47,16 +47,17 @@ test("birth time intake requires only the fields selected by the source", () => assert.equal(isBirthTimeDraftReady({ ...emptyDraft, birthTimeSource: "unknown" }), true); }); -test("a persisted candidate working time can leave rectification onboarding", () => { +test("an unconfirmed candidate working time remains in rectification onboarding", () => { const candidate = { ...emptyDraft, time: "04:53", birthTimeStatus: "candidate", } satisfies BirthTimeDraft; - assert.equal(isBirthTimeReadyForConsultation(candidate), true); + assert.equal(isBirthTimeReadyForConsultation(candidate), false); assert.equal(isBirthTimeReadyForConsultation({ ...candidate, time: "" }), false); assert.equal(isBirthTimeReadyForConsultation({ ...candidate, birthTimeStatus: "rectifying" }), false); + assert.equal(isBirthTimeReadyForConsultation({ ...candidate, birthTimeStatus: "confirmed" }), true); }); test("a persisted candidate working time takes precedence over the reported range", () => {