mirror of
https://github.com/temetro/temetro.git
synced 2026-08-06 08:57:41 +00:00
0754ce96a4
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>
25 lines
948 B
TypeScript
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>;
|