feat(25-01): Zod schemas, upsert service functions, passing tests
- Add upsertGlobalItemSchema and bulkUpsertGlobalItemsSchema to schemas.ts - Add UpsertGlobalItemInput and BulkUpsertGlobalItemsInput types to types.ts - Implement upsertGlobalItem with onConflictDoUpdate and tag sync - Implement bulkUpsertGlobalItems processing array in single transaction - Fix migration 0003 to only add new columns + unique constraint - All 21 tests pass including 8 new upsert operation tests
This commit is contained in:
@@ -102,6 +102,25 @@ export const searchGlobalItemsSchema = z.object({
|
||||
tags: z.string().optional(),
|
||||
});
|
||||
|
||||
// Catalog upsert schemas
|
||||
export const upsertGlobalItemSchema = z.object({
|
||||
brand: z.string().min(1, "Brand is required"),
|
||||
model: z.string().min(1, "Model is required"),
|
||||
category: z.string().optional(),
|
||||
weightGrams: z.number().nonnegative().optional(),
|
||||
priceCents: z.number().int().nonnegative().optional(),
|
||||
imageUrl: z.string().url().optional().or(z.literal("")),
|
||||
description: z.string().optional(),
|
||||
sourceUrl: z.string().url().optional().or(z.literal("")),
|
||||
imageCredit: z.string().optional(),
|
||||
imageSourceUrl: z.string().url().optional().or(z.literal("")),
|
||||
tags: z.array(z.string().min(1).max(100)).max(20).optional(),
|
||||
});
|
||||
|
||||
export const bulkUpsertGlobalItemsSchema = z.object({
|
||||
items: z.array(upsertGlobalItemSchema).min(1).max(100),
|
||||
});
|
||||
|
||||
// Profile schemas
|
||||
export const updateProfileSchema = z.object({
|
||||
displayName: z.string().max(100).optional(),
|
||||
|
||||
@@ -11,6 +11,7 @@ import type {
|
||||
threads,
|
||||
} from "../db/schema.ts";
|
||||
import type {
|
||||
bulkUpsertGlobalItemsSchema,
|
||||
createCandidateSchema,
|
||||
createCategorySchema,
|
||||
createItemSchema,
|
||||
@@ -27,6 +28,7 @@ import type {
|
||||
updateProfileSchema,
|
||||
updateSetupSchema,
|
||||
updateThreadSchema,
|
||||
upsertGlobalItemSchema,
|
||||
} from "./schemas.ts";
|
||||
|
||||
// Types inferred from Zod schemas
|
||||
@@ -50,6 +52,10 @@ export type UpdateClassification = z.infer<typeof updateClassificationSchema>;
|
||||
// Global item types
|
||||
export type SearchGlobalItems = z.infer<typeof searchGlobalItemsSchema>;
|
||||
export type UpdateProfile = z.infer<typeof updateProfileSchema>;
|
||||
export type UpsertGlobalItemInput = z.infer<typeof upsertGlobalItemSchema>;
|
||||
export type BulkUpsertGlobalItemsInput = z.infer<
|
||||
typeof bulkUpsertGlobalItemsSchema
|
||||
>;
|
||||
|
||||
// Types inferred from Drizzle schema
|
||||
export type Item = typeof items.$inferSelect;
|
||||
|
||||
Reference in New Issue
Block a user