Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM, PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source files covering clients, berths, interests/pipeline, documents/EOI, expenses/invoices, email, notifications, dashboard, admin, and client portal. CI/CD via Gitea Actions with Docker builds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
53
src/lib/validators/custom-fields.ts
Normal file
53
src/lib/validators/custom-fields.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
const CUSTOM_FIELD_TYPES = ['text', 'number', 'date', 'boolean', 'select'] as const;
|
||||
const CUSTOM_FIELD_ENTITIES = ['client', 'interest', 'berth'] as const;
|
||||
|
||||
export const createFieldSchema = z
|
||||
.object({
|
||||
entityType: z.enum(CUSTOM_FIELD_ENTITIES),
|
||||
fieldName: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(50)
|
||||
.regex(/^[a-z_][a-z0-9_]*$/, 'Must be snake_case'),
|
||||
fieldLabel: z.string().min(1).max(100),
|
||||
fieldType: z.enum(CUSTOM_FIELD_TYPES),
|
||||
selectOptions: z
|
||||
.array(z.string().min(1).max(100))
|
||||
.min(1)
|
||||
.max(50)
|
||||
.optional(),
|
||||
isRequired: z.boolean().default(false),
|
||||
sortOrder: z.number().int().min(0).default(0),
|
||||
})
|
||||
.refine(
|
||||
(data) =>
|
||||
data.fieldType !== 'select' ||
|
||||
(data.selectOptions && data.selectOptions.length > 0),
|
||||
{
|
||||
message: 'Select fields must have at least one option',
|
||||
path: ['selectOptions'],
|
||||
},
|
||||
);
|
||||
|
||||
export const updateFieldSchema = z.object({
|
||||
fieldLabel: z.string().min(1).max(100).optional(),
|
||||
selectOptions: z.array(z.string().min(1).max(100)).optional(),
|
||||
isRequired: z.boolean().optional(),
|
||||
sortOrder: z.number().int().min(0).optional(),
|
||||
// fieldType intentionally omitted — cannot be changed after creation
|
||||
});
|
||||
|
||||
export const setValuesSchema = z.object({
|
||||
values: z.array(
|
||||
z.object({
|
||||
fieldId: z.string().uuid(),
|
||||
value: z.unknown(),
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
export type CreateFieldInput = z.infer<typeof createFieldSchema>;
|
||||
export type UpdateFieldInput = z.infer<typeof updateFieldSchema>;
|
||||
export type SetValuesInput = z.infer<typeof setValuesSchema>;
|
||||
Reference in New Issue
Block a user