feat: Select Procedures flow, batch-column NPI provider fix, auto PDF save
- Add 'Select Procedures' right-click option on appointment page (separate from Claims/PreAuth) - Select Procedures form saves CDT codes + NPI provider to AppointmentProcedure storage - Remove Save button from insurance claim form; Claims/PreAuth opens for insurance submission only - Claims/PreAuth auto-prefills from saved procedures including NPI provider - Batch-column: procedures npiProviderId takes priority over stale claim npiProviderId - Batch-column: auto-save PDF to patient Documents after successful submission (no socket needed) - Add npiProviderId column to AppointmentProcedure table (prisma db push) - Fix 'invalid db creation invocation': guard staffId, npiProviderId, procedureDate as Date object, totalBilled NaN guard - Add full error logging to batch-column catch block Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
a279a3e7c1
commit
3e899376c3
@@ -54,6 +54,71 @@ router.get(
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* PUT /api/appointment-procedures/set-npi-provider/:appointmentId
|
||||
* Set the npiProviderId on all procedures for an appointment (lightweight update).
|
||||
*/
|
||||
router.put("/set-npi-provider/:appointmentId", async (req: Request, res: Response) => {
|
||||
try {
|
||||
const appointmentId = Number(req.params.appointmentId);
|
||||
if (isNaN(appointmentId)) return res.status(400).json({ message: "Invalid appointmentId" });
|
||||
|
||||
const npiProviderId = req.body.npiProviderId != null ? Number(req.body.npiProviderId) : null;
|
||||
|
||||
await prisma.appointmentProcedure.updateMany({
|
||||
where: { appointmentId },
|
||||
data: { npiProviderId: npiProviderId ?? null },
|
||||
});
|
||||
|
||||
return res.json({ success: true });
|
||||
} catch (err: any) {
|
||||
console.error("set-npi-provider error", err);
|
||||
return res.status(500).json({ message: err.message ?? "Server error" });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/appointment-procedures/save-for-appointment
|
||||
* Replace all procedures for an appointment (clear + insert).
|
||||
* Body: { appointmentId, patientId, npiProviderId?, procedures: [{procedureCode, fee?, toothNumber?, toothSurface?}] }
|
||||
*/
|
||||
router.post("/save-for-appointment", async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { appointmentId, patientId, npiProviderId, procedures } = req.body;
|
||||
|
||||
if (!appointmentId || isNaN(Number(appointmentId))) {
|
||||
return res.status(400).json({ message: "Invalid appointmentId" });
|
||||
}
|
||||
if (!patientId || isNaN(Number(patientId))) {
|
||||
return res.status(400).json({ message: "Invalid patientId" });
|
||||
}
|
||||
if (!Array.isArray(procedures)) {
|
||||
return res.status(400).json({ message: "procedures must be an array" });
|
||||
}
|
||||
|
||||
const filtered = (procedures as any[]).filter(
|
||||
(p) => String(p.procedureCode ?? "").trim() !== ""
|
||||
);
|
||||
|
||||
const count = await storage.saveForAppointment({
|
||||
appointmentId: Number(appointmentId),
|
||||
patientId: Number(patientId),
|
||||
npiProviderId: npiProviderId ? Number(npiProviderId) : null,
|
||||
procedures: filtered.map((p) => ({
|
||||
procedureCode: String(p.procedureCode).trim(),
|
||||
fee: p.fee != null ? Number(p.fee) : null,
|
||||
toothNumber: p.toothNumber || null,
|
||||
toothSurface: p.toothSurface || null,
|
||||
})),
|
||||
});
|
||||
|
||||
return res.json({ success: true, count });
|
||||
} catch (err: any) {
|
||||
console.error("save-for-appointment error", err);
|
||||
return res.status(500).json({ message: err.message ?? "Server error" });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/appointment-procedures
|
||||
* Add single manual procedure
|
||||
|
||||
Reference in New Issue
Block a user