Files
DentalManagement09/packages/db/usedSchemas/browser.ts
T
ff 55ce52f276 fix: patient language field silently dropped by stale browser-side validation schema
packages/db/usedSchemas/browser.ts (the browser-resolved copy of the Patient
zod schema, kept separate from the Node copy since it can't import
Prisma-generated code) was missing several fields added to the real schema
over time — preferredLanguage, gender, insuranceProvider, insuranceId,
groupNumber, policyHolder, and the PLAN_NOT_ACCEPTED status. Since the schema
isn't strict, those fields were silently stripped from every patient
create/update in the browser with no validation error, so edits to them
never reached the server.

Also fixes the AI call greeting always playing in English regardless of the
patient's preferred language — the greeting text was a single hardcoded
string, unlike every later turn in the conversation which already branched
by language.
2026-08-05 21:40:53 -04:00

279 lines
8.6 KiB
TypeScript

import * as z from "zod";
// ─── Enums ────────────────────────────────────────────────────────────────────
export const PatientStatusSchema = z.enum(["ACTIVE", "INACTIVE", "UNKNOWN", "PLAN_NOT_ACCEPTED"]);
export type PatientStatus = z.infer<typeof PatientStatusSchema>;
export const ClaimStatusSchema = z.enum([
"PENDING",
"APPROVED",
"CANCELLED",
"REVIEW",
"VOID",
]);
export type ClaimStatus = z.infer<typeof ClaimStatusSchema>;
export const PaymentMethodSchema = z.enum([
"EFT",
"CHECK",
"CASH",
"CARD",
"OTHER",
]);
export type PaymentMethod = z.infer<typeof PaymentMethodSchema>;
export const PaymentStatusSchema = z.enum([
"PENDING",
"PARTIALLY_PAID",
"PAID",
"OVERPAID",
"DENIED",
"VOID",
]);
export type PaymentStatus = z.infer<typeof PaymentStatusSchema>;
export const NotificationTypesSchema = z.enum([
"BACKUP",
"CLAIM",
"PAYMENT",
"ETC",
]);
export type NotificationTypes = z.infer<typeof NotificationTypesSchema>;
export const ProcedureSourceSchema = z.enum(["COMBO", "MANUAL"]);
export type ProcedureSource = z.infer<typeof ProcedureSourceSchema>;
export const PdfTitleKeySchema = z.enum([
"INSURANCE_CLAIM",
"INSURANCE_CLAIM_PREAUTH",
"ELIGIBILITY_STATUS",
"CLAIM_STATUS",
"OTHER",
]);
export type PdfTitleKey = z.infer<typeof PdfTitleKeySchema>;
export const CommunicationChannelSchema = z.enum(["sms", "voice"]);
export type CommunicationChannel = z.infer<typeof CommunicationChannelSchema>;
export const CommunicationDirectionSchema = z.enum(["outbound", "inbound"]);
export type CommunicationDirection = z.infer<
typeof CommunicationDirectionSchema
>;
export const CommunicationStatusSchema = z.enum([
"queued",
"sent",
"delivered",
"failed",
"completed",
"busy",
"no_answer",
]);
export type CommunicationStatus = z.infer<typeof CommunicationStatusSchema>;
// ─── Object Schemas ───────────────────────────────────────────────────────────
export const UserUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
username: z.string(),
password: z.string(),
});
export const PatientUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
firstName: z.string(),
lastName: z.string(),
dateOfBirth: z.string(),
gender: z.string().optional(),
phone: z.string().optional(),
email: z.string().optional(),
address: z.string().optional(),
city: z.string().optional(),
state: z.string().optional(),
zipCode: z.string().optional(),
insuranceProvider: z.string().optional().nullable(),
insuranceId: z.string().optional().nullable(),
groupNumber: z.string().optional().nullable(),
policyHolder: z.string().optional().nullable(),
allergies: z.string().optional().nullable(),
medicalConditions: z.string().optional().nullable(),
preferredLanguage: z.string().optional().nullable(),
status: PatientStatusSchema.optional(),
userId: z.number().int().optional(),
createdAt: z.coerce.date().optional(),
});
export const StaffUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
firstName: z.string(),
lastName: z.string(),
role: z.string(),
phone: z.string().optional(),
email: z.string().optional(),
userId: z.number().int().optional(),
});
export const AppointmentUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
patientId: z.number().int(),
userId: z.number().int().optional(),
staffId: z.number().int().optional(),
npiProviderId: z.number().int().optional().nullable(),
title: z.string().optional(),
date: z.coerce.date(),
startTime: z.string(),
endTime: z.string(),
type: z.string(),
status: z
.enum(["scheduled", "confirmed", "completed", "cancelled", "no-show"])
.optional(),
notes: z.string().optional(),
});
export const AppointmentProcedureUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
appointmentId: z.number().int(),
patientId: z.number().int(),
procedureCode: z.string(),
procedureLabel: z.string().optional().nullable(),
fee: z.number().optional().nullable(),
category: z.string().optional().nullable(),
toothNumber: z.string().optional().nullable(),
toothSurface: z.string().optional().nullable(),
oralCavityArea: z.string().optional().nullable(),
source: ProcedureSourceSchema.optional(),
comboKey: z.string().optional().nullable(),
createdAt: z.coerce.date().optional(),
});
export const NpiProviderUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
userId: z.number().int(),
npiNumber: z.string(),
providerName: z.string(),
createdAt: z.coerce.date().optional(),
});
export const ClaimUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
patientId: z.number().int(),
appointmentId: z.number().int().optional(),
status: ClaimStatusSchema.optional(),
submittedAt: z.string().optional(),
paidAt: z.string().optional(),
amount: z.number().optional(),
insuranceId: z.string().optional(),
});
export const InsuranceCredentialUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
userId: z.number().int(),
siteKey: z.string(),
username: z.string(),
password: z.string(),
});
export const PdfFileUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
filename: z.string(),
pdfData: z.instanceof(Uint8Array),
uploadedAt: z.coerce.date().optional(),
groupId: z.number().int(),
});
export const PdfGroupUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
title: z.string(),
titleKey: PdfTitleKeySchema.optional(),
createdAt: z.coerce.date().optional(),
patientId: z.number().int(),
});
export const PaymentUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
patientId: z.number().int(),
appointmentId: z.number().int().optional(),
amount: z.number(),
method: PaymentMethodSchema.optional(),
status: PaymentStatusSchema.optional(),
paymentDate: z.string().optional(),
updatedById: z.number().int().optional(),
});
export const ServiceLineTransactionCreateInputObjectSchema = z.object({
transactionId: z.string().optional().nullable(),
paidAmount: z.number(),
adjustedAmount: z.number().optional(),
method: PaymentMethodSchema,
receivedDate: z.coerce.date(),
payerName: z.string().optional().nullable(),
notes: z.string().optional().nullable(),
createdAt: z.coerce.date().optional(),
});
export const NotificationUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
userId: z.number().int(),
type: NotificationTypesSchema,
message: z.string(),
createdAt: z.coerce.date().optional(),
read: z.boolean().optional(),
});
export const DatabaseBackupUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
userId: z.number().int(),
createdAt: z.coerce.date().optional(),
});
export const BackupDestinationUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
userId: z.number().int(),
path: z.string(),
isActive: z.boolean().optional(),
createdAt: z.coerce.date().optional(),
});
export const CloudFolderUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
userId: z.number().int(),
name: z.string(),
parentId: z.number().int().optional().nullable(),
createdAt: z.coerce.date().optional(),
});
export const CloudFileUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
userId: z.number().int(),
name: z.string(),
mimeType: z.string().optional().nullable(),
fileSize: z.bigint(),
folderId: z.number().int().optional().nullable(),
isComplete: z.boolean().optional(),
totalChunks: z.number().int().optional().nullable(),
createdAt: z.coerce.date().optional(),
});
export const CommunicationUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
patientId: z.number().int(),
userId: z.number().int().optional().nullable(),
channel: CommunicationChannelSchema,
direction: CommunicationDirectionSchema,
status: CommunicationStatusSchema,
body: z.string().optional().nullable(),
callDuration: z.number().int().optional().nullable(),
twilioSid: z.string().optional().nullable(),
createdAt: z.coerce.date().optional(),
});
export const ShoppingVendorUncheckedCreateInputObjectSchema = z.object({
id: z.number().int().optional(),
userId: z.number().int(),
vendorName: z.string(),
websiteUrl: z.string(),
loginUsername: z.string(),
loginPassword: z.string(),
});