Phase 9
This commit is contained in:
parent
e396f5088c
commit
a1801af63b
36 changed files with 4783 additions and 31 deletions
118
packages/shared/src/validation/price-record.schemas.ts
Normal file
118
packages/shared/src/validation/price-record.schemas.ts
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
import { z } from 'zod/v4';
|
||||
import { ServingUnit } from '../enums/product.enums.js';
|
||||
|
||||
export const CreatePriceRecordSchema = z.object({
|
||||
productId: z.string().min(1),
|
||||
storeId: z.string().min(1),
|
||||
price: z.number().positive(),
|
||||
currency: z.string().min(1).max(10).default('USD'),
|
||||
quantity: z.number().positive(),
|
||||
unit: z.nativeEnum(ServingUnit),
|
||||
date: z.iso.datetime().optional(),
|
||||
notes: z.string().max(1000).trim().optional(),
|
||||
receiptImageUrl: z.string().url().optional(),
|
||||
});
|
||||
|
||||
export const BulkPriceRecordInputSchema = z.object({
|
||||
storeId: z.string().min(1),
|
||||
date: z.iso.datetime().optional(),
|
||||
items: z.array(
|
||||
z.object({
|
||||
productId: z.string().min(1),
|
||||
price: z.number().positive(),
|
||||
quantity: z.number().positive(),
|
||||
unit: z.nativeEnum(ServingUnit),
|
||||
notes: z.string().max(1000).trim().optional(),
|
||||
})
|
||||
).min(1),
|
||||
});
|
||||
|
||||
export const PriceHistoryQuerySchema = z.object({
|
||||
storeId: z.string().optional(),
|
||||
startDate: z.iso.datetime().optional(),
|
||||
endDate: z.iso.datetime().optional(),
|
||||
cursor: z.string().optional(),
|
||||
limit: z.coerce.number().int().min(1).max(100).default(20),
|
||||
});
|
||||
|
||||
export const PriceRecordResponseSchema = z.object({
|
||||
_id: z.string(),
|
||||
householdId: z.string(),
|
||||
productId: z.string(),
|
||||
productName: z.string(),
|
||||
storeId: z.string(),
|
||||
storeName: z.string(),
|
||||
price: z.number(),
|
||||
currency: z.string(),
|
||||
quantity: z.number(),
|
||||
unit: z.nativeEnum(ServingUnit),
|
||||
pricePerUnit: z.number(),
|
||||
date: z.string(),
|
||||
receiptImageUrl: z.string().optional(),
|
||||
notes: z.string().optional(),
|
||||
createdBy: z.string(),
|
||||
createdAt: z.string(),
|
||||
});
|
||||
|
||||
export const StorePriceComparisonSchema = z.object({
|
||||
storeId: z.string(),
|
||||
storeName: z.string(),
|
||||
latestPrice: z.number(),
|
||||
latestPricePerUnit: z.number(),
|
||||
currency: z.string(),
|
||||
date: z.string(),
|
||||
});
|
||||
|
||||
export const PriceAnalyticsResponseSchema = z.object({
|
||||
averageBasketByStore: z.array(
|
||||
z.object({
|
||||
storeId: z.string(),
|
||||
storeName: z.string(),
|
||||
avgTotal: z.number(),
|
||||
tripCount: z.number(),
|
||||
})
|
||||
),
|
||||
priceAlerts: z.array(
|
||||
z.object({
|
||||
productId: z.string(),
|
||||
productName: z.string(),
|
||||
storeId: z.string(),
|
||||
storeName: z.string(),
|
||||
previousPrice: z.number(),
|
||||
currentPrice: z.number(),
|
||||
changePercent: z.number(),
|
||||
date: z.string(),
|
||||
})
|
||||
),
|
||||
spendingOverTime: z.array(
|
||||
z.object({
|
||||
period: z.string(),
|
||||
total: z.number(),
|
||||
})
|
||||
),
|
||||
spendingByCategory: z.array(
|
||||
z.object({
|
||||
category: z.string(),
|
||||
total: z.number(),
|
||||
avgPerItem: z.number(),
|
||||
})
|
||||
),
|
||||
});
|
||||
|
||||
export const PriceHistoryResponseSchema = z.object({
|
||||
data: z.array(PriceRecordResponseSchema),
|
||||
pagination: z.object({
|
||||
cursor: z.string().nullable(),
|
||||
hasMore: z.boolean(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const FoodStoreComparisonResponseSchema = z.object({
|
||||
data: z.array(StorePriceComparisonSchema),
|
||||
});
|
||||
|
||||
export const FoodSpendingAnalyticsResponseSchema = PriceAnalyticsResponseSchema;
|
||||
|
||||
export type CreatePriceRecordInput = z.infer<typeof CreatePriceRecordSchema>;
|
||||
export type BulkPriceRecordInput = z.infer<typeof BulkPriceRecordInputSchema>;
|
||||
export type PriceHistoryQueryInput = z.infer<typeof PriceHistoryQuerySchema>;
|
||||
Loading…
Add table
Add a link
Reference in a new issue