/**
* Zod schemas for Contact endpoints
*/
import { z } from 'zod';
import { PaginationSchema, ResponseFormatSchema, SortDirectionSchema, IdSchema, OrganizationIdFilterSchema } from './common.js';
/**
* List contacts input schema
*/
export const ListContactsSchema = z.object({
...PaginationSchema.shape,
response_format: ResponseFormatSchema,
organization_id: OrganizationIdFilterSchema,
first_name: z.string().max(255).optional()
.describe('Filter by first name (partial match)'),
last_name: z.string().max(255).optional()
.describe('Filter by last name (partial match)'),
contact_type_id: z.number().int().positive().optional()
.describe('Filter by contact type ID'),
important: z.boolean().optional()
.describe('Filter by important flag'),
psa_id: z.string().optional()
.describe('Filter by PSA integration ID'),
sort: z.enum(['first_name', 'last_name', 'id', 'updated_at', 'created_at'])
.default('last_name')
.describe('Field to sort by'),
sort_direction: SortDirectionSchema
}).strict();
export type ListContactsInput = z.infer<typeof ListContactsSchema>;
/**
* Get contact by ID schema
*/
export const GetContactSchema = z.object({
id: IdSchema,
response_format: ResponseFormatSchema
}).strict();
export type GetContactInput = z.infer<typeof GetContactSchema>;
/**
* Contact email schema
*/
const ContactEmailSchema = z.object({
value: z.string().email()
.describe('Email address'),
label_name: z.enum(['Work', 'Personal', 'Other']).default('Work')
.describe('Email label'),
primary: z.boolean().default(false)
.describe('Is this the primary email')
});
/**
* Contact phone schema
*/
const ContactPhoneSchema = z.object({
value: z.string()
.describe('Phone number'),
extension: z.string().optional()
.describe('Phone extension'),
label_name: z.enum(['Work', 'Mobile', 'Home', 'Fax', 'Other']).default('Work')
.describe('Phone label'),
primary: z.boolean().default(false)
.describe('Is this the primary phone')
});
/**
* Create contact schema
*/
export const CreateContactSchema = z.object({
organization_id: z.number().int().positive()
.describe('Organization ID (required)'),
first_name: z.string().min(1).max(255)
.describe('First name (required)'),
last_name: z.string().min(1).max(255)
.describe('Last name (required)'),
title: z.string().max(255).optional()
.describe('Job title'),
contact_type_id: z.number().int().positive().optional()
.describe('Contact type ID'),
location_id: z.number().int().positive().optional()
.describe('Location ID'),
important: z.boolean().optional()
.describe('Mark as important contact'),
notes: z.string().max(10000).optional()
.describe('Notes'),
contact_emails: z.array(ContactEmailSchema).optional()
.describe('Contact email addresses'),
contact_phones: z.array(ContactPhoneSchema).optional()
.describe('Contact phone numbers'),
response_format: ResponseFormatSchema
}).strict();
export type CreateContactInput = z.infer<typeof CreateContactSchema>;
/**
* Update contact schema
*/
export const UpdateContactSchema = z.object({
id: IdSchema,
organization_id: z.number().int().positive().optional()
.describe('Organization ID'),
first_name: z.string().min(1).max(255).optional()
.describe('First name'),
last_name: z.string().min(1).max(255).optional()
.describe('Last name'),
title: z.string().max(255).optional().nullable()
.describe('Job title'),
contact_type_id: z.number().int().positive().optional()
.describe('Contact type ID'),
location_id: z.number().int().positive().optional().nullable()
.describe('Location ID'),
important: z.boolean().optional()
.describe('Mark as important contact'),
notes: z.string().max(10000).optional().nullable()
.describe('Notes'),
contact_emails: z.array(ContactEmailSchema).optional()
.describe('Contact email addresses (replaces existing)'),
contact_phones: z.array(ContactPhoneSchema).optional()
.describe('Contact phone numbers (replaces existing)'),
response_format: ResponseFormatSchema
}).strict();
export type UpdateContactInput = z.infer<typeof UpdateContactSchema>;