import { z } from 'zod'; import { baseListQuerySchema } from '@/lib/api/list-query'; export const ownerRefSchema = z.object({ type: z.enum(['client', 'company']), id: z.string().min(1), }); // Numeric columns on the yachts table accept a stringified decimal or // null. The form posts empty strings for unfilled fields, which Postgres // rejects with `invalid input syntax for type numeric: ""`. Strip empty // strings here so the service can confidently `?? null` them. const optionalNumericString = z .string() .optional() .transform((v) => (v === '' || v === undefined ? undefined : v)); export const createYachtSchema = z.object({ name: z.string().min(1).max(200), hullNumber: z.string().optional(), registration: z.string().optional(), flag: z.string().optional(), yearBuilt: z.number().int().min(1800).max(2100).optional(), builder: z.string().optional(), model: z.string().optional(), hullMaterial: z.string().optional(), lengthFt: optionalNumericString, widthFt: optionalNumericString, draftFt: optionalNumericString, lengthM: optionalNumericString, widthM: optionalNumericString, draftM: optionalNumericString, owner: ownerRefSchema, // required; yacht must have an owner status: z.enum(['active', 'retired', 'sold_away']).optional().default('active'), notes: z.string().optional(), tagIds: z.array(z.string()).optional().default([]), // Phase 3c — origin tracking. Defaults to 'manual'; the EOI spawn flow // sends 'eoi-generated' and the migration-0073 CHECK enforces the // values at the DB level. source: z.enum(['manual', 'imported', 'eoi-generated']).optional(), sourceDocumentId: z.string().uuid().optional(), }); export const updateYachtSchema = createYachtSchema.partial().omit({ owner: true }); // Owner changes go through /transfer, not PATCH. export const transferOwnershipSchema = z.object({ newOwner: ownerRefSchema, effectiveDate: z.coerce.date(), transferReason: z .enum(['sale', 'inheritance', 'gift', 'company_restructure', 'other']) .optional(), transferNotes: z.string().optional(), }); export const listYachtsSchema = baseListQuerySchema.extend({ ownerType: z.enum(['client', 'company']).optional(), ownerId: z.string().optional(), status: z.enum(['active', 'retired', 'sold_away']).optional(), search: z.string().optional(), }); export type CreateYachtInput = z.infer; export type UpdateYachtInput = z.infer; export type TransferOwnershipInput = z.infer; export type ListYachtsInput = z.infer;