patient creation done
This commit is contained in:
@@ -201,6 +201,18 @@ router.post("/", async (req: Request, res: Response): Promise<any> => {
|
||||
userId: req.user!.id,
|
||||
});
|
||||
|
||||
// Check for duplicate insuranceId if it's provided
|
||||
if (patientData.insuranceId) {
|
||||
const existingPatient = await storage.getPatientByInsuranceId(
|
||||
patientData.insuranceId
|
||||
);
|
||||
|
||||
if (existingPatient) {
|
||||
return res.status(409).json({
|
||||
message: "A patient with this insurance ID already exists.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const patient = await storage.createPatient(patientData);
|
||||
|
||||
@@ -244,8 +256,26 @@ router.put(
|
||||
// Validate request body
|
||||
const patientData = updatePatientSchema.parse(req.body);
|
||||
|
||||
// If updating insuranceId, check for uniqueness (excluding self)
|
||||
if (
|
||||
patientData.insuranceId &&
|
||||
patientData.insuranceId !== existingPatient.insuranceId
|
||||
) {
|
||||
const duplicatePatient = await storage.getPatientByInsuranceId(
|
||||
patientData.insuranceId
|
||||
);
|
||||
if (duplicatePatient && duplicatePatient.id !== patientId) {
|
||||
return res.status(409).json({
|
||||
message: "Another patient with this insurance ID already exists.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Update patient
|
||||
const updatedPatient = await storage.updatePatient(patientId, patientData);
|
||||
const updatedPatient = await storage.updatePatient(
|
||||
patientId,
|
||||
patientData
|
||||
);
|
||||
res.json(updatedPatient);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
|
||||
@@ -165,6 +165,7 @@ export interface IStorage {
|
||||
|
||||
// Patient methods
|
||||
getPatient(id: number): Promise<Patient | undefined>;
|
||||
getPatientByInsuranceId(insuranceId: string): Promise<Patient | null>;
|
||||
getPatientsByUserId(userId: number): Promise<Patient[]>;
|
||||
getRecentPatients(limit: number, offset: number): Promise<Patient[]>;
|
||||
getTotalPatientCount(): Promise<number>;
|
||||
@@ -315,6 +316,12 @@ export const storage: IStorage = {
|
||||
return await db.patient.findMany({ where: { userId } });
|
||||
},
|
||||
|
||||
async getPatientByInsuranceId(insuranceId: string): Promise<Patient | null> {
|
||||
return db.patient.findFirst({
|
||||
where: { insuranceId },
|
||||
});
|
||||
},
|
||||
|
||||
async getRecentPatients(limit: number, offset: number): Promise<Patient[]> {
|
||||
return db.patient.findMany({
|
||||
skip: offset,
|
||||
|
||||
@@ -4,7 +4,6 @@ const API_BASE_URL = import.meta.env.VITE_API_BASE_URL_BACKEND ?? "";
|
||||
|
||||
async function throwIfResNotOk(res: Response) {
|
||||
if (!res.ok) {
|
||||
|
||||
if (res.status === 401 || res.status === 403) {
|
||||
localStorage.removeItem("token");
|
||||
if (!window.location.pathname.startsWith("/auth")) {
|
||||
@@ -13,7 +12,19 @@ async function throwIfResNotOk(res: Response) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw new Error(`${res.status}: ${res.statusText}`);
|
||||
|
||||
// Try to parse the response as JSON for a more meaningful error message
|
||||
let message = `${res.status}: ${res.statusText}`;
|
||||
try {
|
||||
const errorBody = await res.json();
|
||||
if (errorBody?.message) {
|
||||
message = errorBody.message;
|
||||
}
|
||||
} catch {
|
||||
// ignore JSON parse errors, keep default message
|
||||
}
|
||||
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { apiRequest, queryClient } from "@/lib/queryClient";
|
||||
|
||||
const PatientSchema = (
|
||||
PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject<any>
|
||||
@@ -34,6 +35,15 @@ const PatientSchema = (
|
||||
});
|
||||
type Patient = z.infer<typeof PatientSchema>;
|
||||
|
||||
const insertPatientSchema = (
|
||||
PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject<any>
|
||||
).omit({
|
||||
id: true,
|
||||
createdAt: true,
|
||||
userId: true,
|
||||
});
|
||||
type InsertPatient = z.infer<typeof insertPatientSchema>;
|
||||
|
||||
export default function InsuranceEligibilityPage() {
|
||||
const { user } = useAuth();
|
||||
const { toast } = useToast();
|
||||
@@ -53,23 +63,55 @@ export default function InsuranceEligibilityPage() {
|
||||
|
||||
// Populate fields from selected patient
|
||||
useEffect(() => {
|
||||
if (selectedPatient) {
|
||||
setMemberId(selectedPatient.insuranceId ?? "");
|
||||
setFirstName(selectedPatient.firstName ?? "");
|
||||
setLastName(selectedPatient.lastName ?? "");
|
||||
if (selectedPatient) {
|
||||
setMemberId(selectedPatient.insuranceId ?? "");
|
||||
setFirstName(selectedPatient.firstName ?? "");
|
||||
setLastName(selectedPatient.lastName ?? "");
|
||||
|
||||
const dob = selectedPatient.dateOfBirth
|
||||
? new Date(selectedPatient.dateOfBirth)
|
||||
: undefined;
|
||||
setDateOfBirth(dob);
|
||||
} else {
|
||||
setMemberId("");
|
||||
setFirstName("");
|
||||
setLastName("");
|
||||
setDateOfBirth(undefined);
|
||||
}
|
||||
}, [selectedPatient]);
|
||||
const dob = selectedPatient.dateOfBirth
|
||||
? new Date(selectedPatient.dateOfBirth)
|
||||
: undefined;
|
||||
setDateOfBirth(dob);
|
||||
} else {
|
||||
setMemberId("");
|
||||
setFirstName("");
|
||||
setLastName("");
|
||||
setDateOfBirth(undefined);
|
||||
}
|
||||
}, [selectedPatient]);
|
||||
|
||||
// Add patient mutation
|
||||
const addPatientMutation = useMutation({
|
||||
mutationFn: async (patient: InsertPatient) => {
|
||||
const res = await apiRequest("POST", "/api/patients/", patient);
|
||||
return res.json();
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["patients"] });
|
||||
toast({
|
||||
title: "Success",
|
||||
description: "Patient added successfully!",
|
||||
variant: "default",
|
||||
});
|
||||
},
|
||||
onError: (error: any) => {
|
||||
const msg = error.message;
|
||||
|
||||
if (msg === "A patient with this insurance ID already exists.") {
|
||||
toast({
|
||||
title: "Patient already exists",
|
||||
description: msg,
|
||||
variant: "default",
|
||||
});
|
||||
} else {
|
||||
toast({
|
||||
title: "Error",
|
||||
description: `Failed to add patient: ${msg}`,
|
||||
variant: "destructive",
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Insurance eligibility check mutation
|
||||
const checkInsuranceMutation = useMutation({
|
||||
@@ -114,16 +156,34 @@ export default function InsuranceEligibilityPage() {
|
||||
});
|
||||
|
||||
// Handle insurance provider button clicks
|
||||
const handleMHButton= () => {
|
||||
const handleMHButton = () => {
|
||||
// Form Fields check
|
||||
if (!memberId || !dateOfBirth || !firstName) {
|
||||
toast({
|
||||
title: "Missing Fields",
|
||||
description:
|
||||
"Please fill in all the required fields: Member ID, Date of Birth, First Name.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
toast({
|
||||
title: "Missing Fields",
|
||||
description:
|
||||
"Please fill in all the required fields: Member ID, Date of Birth, First Name.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Adding patient if same patient exists then it will skip.
|
||||
const newPatient: InsertPatient = {
|
||||
firstName,
|
||||
lastName,
|
||||
dateOfBirth: dateOfBirth,
|
||||
gender: "",
|
||||
phone: "",
|
||||
userId: user?.id ?? 1,
|
||||
status: "active",
|
||||
insuranceId: memberId,
|
||||
};
|
||||
addPatientMutation.mutate(newPatient);
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user