Files
temetro/backend/src/lib/inventory-validation.ts
T
Khalid Abdi 0754ce96a4 inventory: barcode scanner in Add-item dialog
Add a camera barcode/QR scanner (components/scan/barcode-scanner.tsx,
@zxing/browser lazy-loaded) and a Barcode/NDC field to the pharmacy
Add-item dialog. Scanning a GS1 DataMatrix auto-fills expiry (AI 17) and
lot (AI 10 -> notes), with the GTIN (AI 01) as the barcode; plain 1D
barcodes drop straight into the field. Persists a nullable inventory
barcode column (migration 0036) through the type/validation/service, and
surfaces it on the item detail. i18n added to all locales.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 23:32:45 +03:00

25 lines
948 B
TypeScript

import { z } from "zod";
const nonEmpty = z.string().trim().min(1);
// Payload accepted by POST/PUT /api/inventory. Only the medication name is
// required; quantities default to 0 and the descriptive fields to empty strings
// so a quick add (name only) is valid.
export const inventoryInputSchema = z.object({
name: nonEmpty.max(200),
form: z.string().trim().max(120).default(""),
strength: z.string().trim().max(120).default(""),
unit: z.string().trim().max(60).default(""),
stockQuantity: z.number().int().min(0).max(1_000_000).default(0),
reorderThreshold: z.number().int().min(0).max(1_000_000).default(0),
location: z.string().trim().max(200).default(""),
barcode: z.string().trim().max(120).nullish(),
expiresAt: z
.string()
.regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be YYYY-MM-DD.")
.nullish(),
notes: z.string().max(5000).nullish(),
});
export type InventoryInput = z.infer<typeof inventoryInputSchema>;