fix(insuranceId space issue)

This commit is contained in:
2025-10-04 01:31:14 +05:30
parent f0657e78f2
commit 7920f40eb2
4 changed files with 95 additions and 10 deletions

View File

@@ -3,6 +3,7 @@ import type { Request, Response } from "express";
import { storage } from "../storage"; import { storage } from "../storage";
import { z } from "zod"; import { z } from "zod";
import { insertPatientSchema, updatePatientSchema } from "@repo/db/types"; import { insertPatientSchema, updatePatientSchema } from "@repo/db/types";
import { normalizeInsuranceId } from "../utils/helpers";
const router = Router(); const router = Router();
@@ -160,6 +161,18 @@ router.get(
// Create a new patient // Create a new patient
router.post("/", async (req: Request, res: Response): Promise<any> => { router.post("/", async (req: Request, res: Response): Promise<any> => {
try { try {
const body: any = { ...req.body, userId: req.user!.id };
// Normalize insuranceId early and return clear error if invalid
try {
const normalized = normalizeInsuranceId(body.insuranceId);
body.insuranceId = normalized;
} catch (err: any) {
return res.status(400).json({
message: "Invalid insuranceId",
details: err?.message ?? "Invalid insuranceId format",
});
}
// Validate request body // Validate request body
const patientData = insertPatientSchema.parse({ const patientData = insertPatientSchema.parse({
...req.body, ...req.body,
@@ -169,7 +182,7 @@ router.post("/", async (req: Request, res: Response): Promise<any> => {
// Check for duplicate insuranceId if it's provided // Check for duplicate insuranceId if it's provided
if (patientData.insuranceId) { if (patientData.insuranceId) {
const existingPatient = await storage.getPatientByInsuranceId( const existingPatient = await storage.getPatientByInsuranceId(
patientData.insuranceId patientData.insuranceId as string
); );
if (existingPatient) { if (existingPatient) {
@@ -201,6 +214,18 @@ router.put(
try { try {
const patientIdParam = req.params.id; const patientIdParam = req.params.id;
// Normalize incoming insuranceId (if present)
try {
if (req.body.insuranceId !== undefined) {
req.body.insuranceId = normalizeInsuranceId(req.body.insuranceId);
}
} catch (err: any) {
return res.status(400).json({
message: "Invalid insuranceId",
details: err?.message ?? "Invalid insuranceId format",
});
}
// Ensure that patientIdParam exists and is a valid number // Ensure that patientIdParam exists and is a valid number
if (!patientIdParam) { if (!patientIdParam) {
return res.status(400).json({ message: "Patient ID is required" }); return res.status(400).json({ message: "Patient ID is required" });
@@ -223,7 +248,7 @@ router.put(
patientData.insuranceId !== existingPatient.insuranceId patientData.insuranceId !== existingPatient.insuranceId
) { ) {
const duplicatePatient = await storage.getPatientByInsuranceId( const duplicatePatient = await storage.getPatientByInsuranceId(
patientData.insuranceId patientData.insuranceId as string
); );
if (duplicatePatient && duplicatePatient.id !== patientId) { if (duplicatePatient && duplicatePatient.id !== patientId) {
return res.status(409).json({ return res.status(409).json({

View File

@@ -87,7 +87,7 @@ export const patientsStorage: IStorage = {
try { try {
return await db.patient.update({ return await db.patient.update({
where: { id }, where: { id },
data: updateData, data: updateData as Patient,
}); });
} catch (err) { } catch (err) {
throw new Error(`Patient with ID ${id} not found`); throw new Error(`Patient with ID ${id} not found`);

View File

@@ -0,0 +1,27 @@
export function normalizeInsuranceId(raw: unknown): string | undefined {
if (raw === undefined || raw === null) return undefined;
// Accept numbers too (e.g. 12345), but prefer strings
let s: string;
if (typeof raw === "number") {
s = String(raw);
} else if (typeof raw === "string") {
s = raw;
} else {
// Not acceptable type
throw new Error("Insurance ID must be a numeric string.");
}
// Remove all whitespace
const cleaned = s.replace(/\s+/g, "");
// If empty after cleaning, treat as undefined
if (cleaned === "") return undefined;
// Only digits allowed (since you said it's numeric)
if (!/^\d+$/.test(cleaned)) {
throw new Error("Insurance ID must contain only digits.");
}
return cleaned;
}

View File

@@ -1,14 +1,44 @@
import { PatientUncheckedCreateInputObjectSchema } from "@repo/db/usedSchemas"; import { PatientUncheckedCreateInputObjectSchema } from "@repo/db/usedSchemas";
import {z} from "zod"; import { z } from "zod";
export type Patient = z.infer<typeof PatientUncheckedCreateInputObjectSchema>; export type Patient = z.infer<typeof PatientUncheckedCreateInputObjectSchema>;
export const insuranceIdSchema = z.preprocess(
(val) => {
if (val === undefined || val === null) return undefined;
// Accept numbers and strings
if (typeof val === "number") {
return String(val).replace(/\s+/g, "");
}
if (typeof val === "string") {
const cleaned = val.replace(/\s+/g, "");
if (cleaned === "") return undefined;
return cleaned;
}
return val;
},
// After preprocess, require digits-only string (or optional nullable)
z
.string()
.regex(/^\d+$/, { message: "Insurance ID must contain only digits" })
.min(1)
.max(32)
.optional()
.nullable()
);
export const insertPatientSchema = ( export const insertPatientSchema = (
PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject<any> PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject<any>
).omit({ )
id: true, .omit({
createdAt: true, id: true,
}); createdAt: true,
})
.extend({
insuranceId: insuranceIdSchema, // enforce numeric insuranceId
});
export type InsertPatient = z.infer<typeof insertPatientSchema>; export type InsertPatient = z.infer<typeof insertPatientSchema>;
export const updatePatientSchema = ( export const updatePatientSchema = (
@@ -19,6 +49,9 @@ export const updatePatientSchema = (
createdAt: true, createdAt: true,
userId: true, userId: true,
}) })
.partial(); .partial()
.extend({
insuranceId: insuranceIdSchema, // enforce numeric insuranceId
});
export type UpdatePatient = z.infer<typeof updatePatientSchema>; export type UpdatePatient = z.infer<typeof updatePatientSchema>;