fix: AI claim queue restart from first patient; recognize D7210 # 32 in notes
- appointments-page: save full queue from current patient on confirm so that
cancelling the claim form resumes at the same patient instead of skipping it
- claims-page: advance ai_claim_queue only after successful submission (CCA,
MH selenium PDF download, or direct non-draft submit) via new advanceAiClaimQueue()
- cdt-lookup: fix extractToothSurface regex to allow space between # and digit
(e.g. "# 32") so tooth number is correctly captured
- cdt-lookup: silently skip bare tooth-number tokens ("# 32", "#32") that the
LLM may emit as standalone items, preventing false "unrecognized procedure" errors
- internal-chat-graph: add explicit rule that a CDT code followed by # NN
(e.g. "D7210 # 32") must stay as one entry and not spread to other procedures
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1577,11 +1577,11 @@ export default function AppointmentsPage() {
|
||||
const handleAiClaimConfirm = () => {
|
||||
if (!aiClaimCurrentData) return;
|
||||
const { matchedCodes, siteKey, serviceDate, appointmentId } = aiClaimCurrentData;
|
||||
const nextIndex = aiClaimCurrentIndex + 1;
|
||||
const remaining = aiClaimQueue.slice(nextIndex);
|
||||
if (remaining.length > 0) {
|
||||
// Include current patient in queue; claims-page advances it only on successful submit.
|
||||
const fromCurrent = aiClaimQueue.slice(aiClaimCurrentIndex);
|
||||
if (fromCurrent.length > 0) {
|
||||
sessionStorage.setItem("ai_claim_queue", JSON.stringify({
|
||||
appointments: remaining,
|
||||
appointments: fromCurrent,
|
||||
date: formattedSelectedDate,
|
||||
pendingResume: true,
|
||||
}));
|
||||
|
||||
@@ -142,6 +142,7 @@ export default function ClaimsPage() {
|
||||
|
||||
// CCA result: pdfFileId is already saved by the processor — open preview directly
|
||||
if (jobResult.pdfFileId) {
|
||||
advanceAiClaimQueue();
|
||||
setPreviewPdfId(jobResult.pdfFileId);
|
||||
setPreviewFallbackFilename(jobResult.pdfFilename ?? `cca_claim_${jobResult.claimNumber ?? "unknown"}.pdf`);
|
||||
setPreviewOpen(true);
|
||||
@@ -332,6 +333,23 @@ export default function ClaimsPage() {
|
||||
}
|
||||
};
|
||||
|
||||
// Advance the ai_claim_queue by removing the first item (current patient).
|
||||
// Called only on successful submission so that cancel leaves the queue intact.
|
||||
const advanceAiClaimQueue = () => {
|
||||
try {
|
||||
const raw = sessionStorage.getItem("ai_claim_queue");
|
||||
if (!raw) return;
|
||||
const parsed = JSON.parse(raw);
|
||||
if (!parsed?.pendingResume || !Array.isArray(parsed.appointments)) return;
|
||||
const [, ...rest] = parsed.appointments;
|
||||
if (rest.length > 0) {
|
||||
sessionStorage.setItem("ai_claim_queue", JSON.stringify({ ...parsed, appointments: rest }));
|
||||
} else {
|
||||
sessionStorage.removeItem("ai_claim_queue");
|
||||
}
|
||||
} catch {}
|
||||
};
|
||||
|
||||
// 3. create or update claim (update when claimId is present)
|
||||
const handleClaimSubmit = async (claimData: any): Promise<Claim> => {
|
||||
const { isDraft, claimId, uploadedFiles: _uf, ...cleanData } = claimData;
|
||||
@@ -352,6 +370,7 @@ export default function ClaimsPage() {
|
||||
const data = await res.json();
|
||||
if (!res.ok) throw new Error(data?.message || "Failed to save claim");
|
||||
queryClient.invalidateQueries({ queryKey: QK_CLAIMS_BASE });
|
||||
if (!isDraft) advanceAiClaimQueue();
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -865,6 +884,8 @@ export default function ClaimsPage() {
|
||||
duration: isPreAuth ? 10000 : 5000,
|
||||
});
|
||||
|
||||
if (!isPreAuth) advanceAiClaimQueue();
|
||||
|
||||
// Pop up the final PDF so the user doesn't need to navigate to Documents
|
||||
if (result.pdfFileId) {
|
||||
setPreviewPdfId(result.pdfFileId);
|
||||
|
||||
Reference in New Issue
Block a user