fix: allow claims without appointment + support post/core multi-tooth input

- Make appointmentId nullable/optional in Prisma Zod schema via @zod rich
  comment so claims can be submitted without an existing appointment
- Convert undefined appointmentId to null in all claim form handlers and
  the backend claim creation endpoint
- Add AI classifier rule for expanding one procedure across multiple
  comma-separated tooth numbers (e.g. "post/core on #23, 24, 25, 26")
- Add "post/core" (slash) alias to CDT lookup maps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-28 22:57:24 -04:00
parent c9d08028a9
commit e1fe4862d5
1613 changed files with 59200 additions and 422 deletions

View File

@@ -105,6 +105,7 @@ const ALIAS_MAP: Record<string, string> = {
"recement": "re-cement",
"post core": "post and core",
"post and core": "post and core",
"post/core": "post and core",
// Root canal (endodontic)
"root canal": "endodontic therapy",
"rct": "endodontic therapy",
@@ -178,6 +179,7 @@ const DIRECT_CODE_MAP: Record<string, string> = {
"post": "D2954",
"pos": "D2954",
"post core": "D2954",
"post/core": "D2954",
// Crowns
"recement": "D2920",
"re cement": "D2920",

View File

@@ -152,6 +152,12 @@ Rules:
e.g. "#20 rct, post, crown" → ["#20 rct", "#20 post", "#20 crown"]
e.g. "preauth #20 rct, pos, crown" → ["#20 rct", "#20 pos", "#20 crown"]
e.g. "#14 rct, buildup, crown" → ["#14 rct", "#14 buildup", "#14 crown"]
- When a procedure is followed by MULTIPLE tooth numbers (comma-separated, with or without # on each), apply the procedure to EVERY tooth number as separate entries.
e.g. "post/core on #23, 24, 25, 26" → ["post/core #23", "post/core #24", "post/core #25", "post/core #26"]
e.g. "crown #3, #5, #12" → ["crown #3", "crown #5", "crown #12"]
e.g. "extraction #1, 16, 17, 32" → ["extraction #1", "extraction #16", "extraction #17", "extraction #32"]
e.g. "rct #23, 24, 25" → ["rct #23", "rct #24", "rct #25"]
"post/core" is the same as "post core" — a combined post and core procedure
- For RCT/root canal with a tooth number, preserve the tooth# in the entry:
e.g. "rct #29", "#14 root canal", "rct #6", "#20 rct" — keep the #number with the procedure so the correct code can be selected
- For a CDT code (D####) followed by a tooth number (# NN or #NN), keep them together as ONE entry and do NOT spread the tooth# to other procedures:

View File

@@ -1152,7 +1152,7 @@ router.post("/", async (req: Request, res: Response): Promise<any> => {
// Strip unknown keys so strict() doesn't reject any extra properties the frontend may send
const parsedClaim = (ExtendedClaimSchema as unknown as z.ZodObject<any>).strip().parse({
patientId: req.body.patientId,
appointmentId: req.body.appointmentId,
appointmentId: req.body.appointmentId ?? null,
staffId: req.body.staffId,
patientName: req.body.patientName,
memberId: req.body.memberId,