fix(rectification): label declared birth time as record or estimate (BUG-690)
Independent Staging Quality Gate / validate (push) Failing after 8m55s
Independent Staging Quality Gate / publish (push) Skipped

Hospital records, family estimates and period-only windows now keep distinct copy on the board and range card. Scoring still uses the reported clock as the search-window centre. Hospital minutes outside the current range are stated with the offset and no preference.
This commit is contained in:
jesse-ux
2026-09-14 23:20:15 +08:00
parent a266b6b727
commit c5fbee56a6
25 changed files with 531 additions and 35 deletions
@@ -73,6 +73,7 @@ import {
persistedQuestionSurface,
interviewStopReasonFromSnapshot,
interviewSessionOutcomeFromSnapshot,
birthTimeSourceFromSnapshot,
type RectificationCaseSnapshotPayload,
} from "@/lib/rectification-surface-state";
import { RectificationTimeline } from "@/components/rectification-timeline";
@@ -394,6 +395,7 @@ type CaseSnapshotState = Readonly<{
stage: RectificationTimelineStage | null;
interviewStopReason: string | null;
interviewSessionOutcome: string | null;
birthTimeSource: ReturnType<typeof birthTimeSourceFromSnapshot>;
}>;
function nextUserActionIdFromSnapshot(payload: RectificationCaseSnapshotPayload | null): string | null {
@@ -419,6 +421,7 @@ function caseSnapshotState(payload: RectificationCaseSnapshotPayload | null): Ca
stage: caseStageFromSnapshot(payload.case?.stage),
interviewStopReason: interviewStopReasonFromSnapshot(payload),
interviewSessionOutcome: interviewSessionOutcomeFromSnapshot(payload),
birthTimeSource: birthTimeSourceFromSnapshot(payload),
};
}
@@ -464,6 +467,7 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
const [nextUserActionId, setNextUserActionId] = useState<string | null>(() => caseSnapshotState(initialSnapshot)?.nextUserActionId ?? null);
const [interviewStopReason, setInterviewStopReason] = useState<string | null>(() => caseSnapshotState(initialSnapshot)?.interviewStopReason ?? null);
const [interviewSessionOutcome, setInterviewSessionOutcome] = useState<string | null>(() => caseSnapshotState(initialSnapshot)?.interviewSessionOutcome ?? null);
const [birthTimeSource, setBirthTimeSource] = useState(() => caseSnapshotState(initialSnapshot)?.birthTimeSource ?? birthTimeSourceFromSnapshot(initialSnapshot));
const [caseSnapshotLoaded, setCaseSnapshotLoaded] = useState(initialSnapshot !== null);
const [questionRetryAttempts, setQuestionRetryAttempts] = useState(0);
const [questionRepairAttempts, setQuestionRepairAttempts] = useState(0);
@@ -637,6 +641,7 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
setNextUserActionId(nextActionId || null);
setInterviewStopReason(interviewStopReasonFromSnapshot(snapshot));
setInterviewSessionOutcome(interviewSessionOutcomeFromSnapshot(snapshot));
setBirthTimeSource(birthTimeSourceFromSnapshot(snapshot));
setCaseSnapshotLoaded(true);
if (nextQuestion || nextChoice || acceptedTime || confirmedTime) {
setQuestionRepairAttempts(0);
@@ -1683,6 +1688,7 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
<RectificationBoardPeek
result={candidateResult}
declaredTime={declaredTime}
birthTimeSource={birthTimeSource}
expanded={boardOpen}
boardId={boardId}
onOpen={toggleBoard}
@@ -1988,6 +1994,7 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
<RectificationBoard
result={candidateResult}
declaredTime={declaredTime}
birthTimeSource={birthTimeSource}
savedStatus={savedStatus}
diff={boardDiff}
compact={compactBoard}