Phases 6-7
This commit is contained in:
parent
76a516a417
commit
029940b079
111 changed files with 17247 additions and 447 deletions
75
packages/shared/src/validation/product.schemas.ts
Normal file
75
packages/shared/src/validation/product.schemas.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { z } from 'zod/v4';
|
||||
import { ProductCategory, ServingUnit, ProductSource } from '../enums/product.enums.js';
|
||||
|
||||
export const NutritionInfoSchema = z.object({
|
||||
calories: z.number().min(0),
|
||||
protein: z.number().min(0),
|
||||
carbs: z.number().min(0),
|
||||
fat: z.number().min(0),
|
||||
fiber: z.number().min(0).optional(),
|
||||
sugar: z.number().min(0).optional(),
|
||||
sodium: z.number().min(0).optional(),
|
||||
saturatedFat: z.number().min(0).optional(),
|
||||
cholesterol: z.number().min(0).optional(),
|
||||
});
|
||||
|
||||
export const CreateProductSchema = z.object({
|
||||
name: z.string().min(1).max(200).trim(),
|
||||
brand: z.string().max(200).trim().optional(),
|
||||
barcode: z
|
||||
.string()
|
||||
.regex(/^\d{8,14}$/, 'Barcode must be 8-14 digits')
|
||||
.optional(),
|
||||
category: z.nativeEnum(ProductCategory),
|
||||
servingSize: z.number().positive(),
|
||||
servingUnit: z.nativeEnum(ServingUnit),
|
||||
densityGPerMl: z.number().positive().optional(),
|
||||
nutrition: NutritionInfoSchema,
|
||||
tags: z.array(z.string().min(1).max(50).trim()).max(20).default([]),
|
||||
imageUrl: z.url().optional(),
|
||||
source: z.nativeEnum(ProductSource).default(ProductSource.MANUAL),
|
||||
});
|
||||
|
||||
export const UpdateProductSchema = CreateProductSchema.partial();
|
||||
|
||||
export const ProductQuerySchema = z.object({
|
||||
q: z.string().optional(),
|
||||
category: z.nativeEnum(ProductCategory).optional(),
|
||||
tags: z.string().optional(),
|
||||
barcode: z.string().optional(),
|
||||
cursor: z.string().optional(),
|
||||
limit: z.coerce.number().int().min(1).max(100).default(20),
|
||||
});
|
||||
|
||||
export const ProductResponseSchema = z.object({
|
||||
_id: z.string(),
|
||||
householdId: z.string(),
|
||||
name: z.string(),
|
||||
brand: z.string().optional(),
|
||||
barcode: z.string().optional(),
|
||||
category: z.string(),
|
||||
servingSize: z.number(),
|
||||
servingUnit: z.string(),
|
||||
densityGPerMl: z.number().optional(),
|
||||
nutrition: NutritionInfoSchema,
|
||||
tags: z.array(z.string()),
|
||||
imageUrl: z.string().optional(),
|
||||
source: z.string(),
|
||||
createdBy: z.string(),
|
||||
createdAt: z.string(),
|
||||
updatedAt: z.string(),
|
||||
deletedAt: z.string().optional(),
|
||||
});
|
||||
|
||||
export const ProductListResponseSchema = z.object({
|
||||
data: z.array(ProductResponseSchema),
|
||||
pagination: z.object({
|
||||
cursor: z.string().nullable(),
|
||||
hasMore: z.boolean(),
|
||||
total: z.number().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
export type CreateProductInput = z.infer<typeof CreateProductSchema>;
|
||||
export type UpdateProductInput = z.infer<typeof UpdateProductSchema>;
|
||||
export type ProductQueryInput = z.infer<typeof ProductQuerySchema>;
|
||||
Loading…
Add table
Add a link
Reference in a new issue