Files
pn-new-crm/src/lib/validators/search.ts

57 lines
1.4 KiB
TypeScript
Raw Normal View History

import { z } from 'zod';
const BUCKET_TYPES = [
'clients',
'residentialClients',
'yachts',
'companies',
'interests',
'residentialInterests',
'berths',
'invoices',
'expenses',
'documents',
'files',
'reminders',
'brochures',
'tags',
'navigation',
] as const;
export const searchQuerySchema = z.object({
// 2-char minimum keeps `to_tsquery('a:*')` from returning every word
// starting with "a" — short queries return overwhelming match sets.
q: z.string().min(2).max(200),
/** Restrict the result set to a single bucket. */
type: z.enum(BUCKET_TYPES).optional(),
/** Per-bucket cap. Defaults to 5 (dropdown). 25 is the typical /search-page value. */
limit: z.coerce.number().int().min(1).max(50).optional(),
/** Super-admin only — search ports beyond the current one. */
includeOtherPorts: z
.union([z.literal('true'), z.literal('1'), z.literal('false'), z.literal('0')])
.transform((v) => v === 'true' || v === '1')
.optional(),
});
export type SearchQuery = z.infer<typeof searchQuerySchema>;
const RECENTLY_VIEWED_TYPES = [
'client',
'residential-client',
'yacht',
'company',
'interest',
'residential-interest',
'berth',
'invoice',
'expense',
'document',
] as const;
export const trackViewSchema = z.object({
type: z.enum(RECENTLY_VIEWED_TYPES),
id: z.string().min(1).max(100),
});
export type TrackViewPayload = z.infer<typeof trackViewSchema>;