This repository has been archived on 2026-02-01. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
synthetic-consumer-data/utils/purchases/types.ts

87 lines
2.4 KiB
TypeScript

import { consumerSchema } from '@utils/consumer/types';
import { z } from 'zod';
const isoDateTimeString = z.string().refine(
value => {
try {
return !isNaN(new Date(value).getTime());
} catch {
return false;
}
},
{ message: 'Invalid ISO 8601 datetime format' }
);
const reflectionSchema = z.object({
comment: z.string().min(1, 'Comment is required'),
satisfactionScore: z.number().min(1).max(10),
date: isoDateTimeString,
mood: z.string().nullable().optional(),
relatedTo: z.string().optional()
});
const weekContextSchema = z.object({
events: z.array(z.string()).optional(),
stressLevel: z.number().min(1).max(10).optional(),
notes: z.string().optional()
});
const purchaseSchema = z.object({
name: z.string().min(1, 'Name is required'),
amount: z.number().positive('Amount must be positive'),
datetime: isoDateTimeString,
location: z.string().min(1, 'Location is required'),
category: z.string().min(1, 'Category is required'),
isPlanned: z.boolean(),
context: z.string().optional(),
notes: z.string().optional(),
reflections: z.array(reflectionSchema).optional()
});
const weekSchema = z
.object({
weekNumber: z.number().positive().int(),
startDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Invalid date format'),
endDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Invalid date format'),
purchases: z
.array(purchaseSchema)
.min(7, 'Minimum 7 purchases required per week')
.max(21, 'Maximum 21 purchases allowed per week'),
weekContext: weekContextSchema.optional()
})
.refine(
data => {
const start = new Date(data.startDate);
const end = new Date(data.endDate);
return start <= end;
},
{
message: 'End date must be after or equal to start date',
path: ['endDate']
}
);
export const purchaseListSchema = z
.object({
weeks: z.array(weekSchema).min(1, 'At least one week is required')
})
.refine(
data => {
const weekNumbers = data.weeks
.map(w => w.weekNumber)
.sort((a, b) => a - b);
return weekNumbers.every((num, idx) => num === idx + 1);
},
{
message: 'Week numbers must be sequential starting from 1',
path: ['weeks']
}
);
export type PurchaseList = z.infer<typeof purchaseListSchema>;
export const purchasesRequestSchema = z.object({
id: z.number().optional(),
consumer: consumerSchema
});