- Build complete Next.js CRM for commercial real estate - Add authentication with JWT sessions and role-based access - Add GoHighLevel API integration for contacts, conversations, opportunities - Add AI-powered Control Center with tool calling - Add Setup page with onboarding checklist (/setup) - Add sidebar navigation with Setup menu item - Fix type errors in onboarding API, GHL services, and control center tools - Add Prisma schema with SQLite for local development - Add UI components with clay morphism design system Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
382 lines
9.4 KiB
TypeScript
382 lines
9.4 KiB
TypeScript
/**
|
|
* GoHighLevel API Types
|
|
* CRESyncFlow - Commercial Real Estate CRM
|
|
*
|
|
* These types correspond to the GHL API v2 endpoints
|
|
*/
|
|
|
|
// =============================================================================
|
|
// GHL Contact Types
|
|
// =============================================================================
|
|
|
|
export interface GHLContact {
|
|
id: string;
|
|
locationId: string;
|
|
firstName?: string;
|
|
lastName?: string;
|
|
name?: string;
|
|
email?: string;
|
|
phone?: string;
|
|
companyName?: string;
|
|
address1?: string;
|
|
city?: string;
|
|
state?: string;
|
|
country?: string;
|
|
postalCode?: string;
|
|
website?: string;
|
|
timezone?: string;
|
|
dnd?: boolean;
|
|
dndSettings?: GHLDNDSettings;
|
|
tags?: string[];
|
|
source?: string;
|
|
customFields?: Record<string, any>;
|
|
assignedTo?: string;
|
|
dateAdded?: string;
|
|
dateUpdated?: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface GHLDNDSettings {
|
|
call?: { status: 'active' | 'inactive' };
|
|
email?: { status: 'active' | 'inactive' };
|
|
sms?: { status: 'active' | 'inactive' };
|
|
whatsApp?: { status: 'active' | 'inactive' };
|
|
gmb?: { status: 'active' | 'inactive' };
|
|
fb?: { status: 'active' | 'inactive' };
|
|
}
|
|
|
|
export interface CreateContactDTO {
|
|
firstName?: string;
|
|
lastName?: string;
|
|
name?: string;
|
|
email?: string;
|
|
phone?: string;
|
|
companyName?: string;
|
|
address1?: string;
|
|
city?: string;
|
|
state?: string;
|
|
country?: string;
|
|
postalCode?: string;
|
|
website?: string;
|
|
timezone?: string;
|
|
dnd?: boolean;
|
|
tags?: string[];
|
|
source?: string;
|
|
customFields?: Record<string, any>;
|
|
assignedTo?: string;
|
|
}
|
|
|
|
export interface UpdateContactDTO extends Partial<CreateContactDTO> {
|
|
id?: string;
|
|
}
|
|
|
|
export interface ContactSearchParams {
|
|
locationId: string;
|
|
query?: string;
|
|
limit?: number;
|
|
skip?: number;
|
|
}
|
|
|
|
// =============================================================================
|
|
// GHL Conversation Types
|
|
// =============================================================================
|
|
|
|
export type ConversationType = 'SMS' | 'EMAIL' | 'CALL' | 'LIVE_CHAT' | 'FB' | 'GMB' | 'IG' | 'WhatsApp';
|
|
|
|
export interface GHLConversation {
|
|
id: string;
|
|
locationId: string;
|
|
contactId: string;
|
|
type: ConversationType;
|
|
lastMessageBody?: string;
|
|
lastMessageDate: string;
|
|
lastMessageType?: 'TYPE_CALL' | 'TYPE_SMS' | 'TYPE_EMAIL' | 'TYPE_SMS_REVIEW_REQUEST' | 'TYPE_WEBCHAT' | 'TYPE_FB_MESSENGER' | 'TYPE_IG_DM' | 'TYPE_LIVE_CHAT' | 'TYPE_ACTIVITY' | 'TYPE_WHATSAPP';
|
|
lastMessageDirection?: 'inbound' | 'outbound';
|
|
unreadCount: number;
|
|
starred?: boolean;
|
|
deleted?: boolean;
|
|
assignedTo?: string;
|
|
dateAdded?: string;
|
|
dateUpdated?: string;
|
|
}
|
|
|
|
export type MessageType = 'SMS' | 'EMAIL' | 'CALL' | 'LIVE_CHAT' | 'FB' | 'GMB' | 'IG' | 'WhatsApp';
|
|
export type MessageDirection = 'inbound' | 'outbound';
|
|
export type MessageStatus = 'pending' | 'scheduled' | 'sent' | 'delivered' | 'read' | 'undelivered' | 'failed';
|
|
|
|
export interface GHLMessage {
|
|
id: string;
|
|
conversationId: string;
|
|
locationId?: string;
|
|
contactId?: string;
|
|
type: MessageType;
|
|
direction: MessageDirection;
|
|
body: string;
|
|
subject?: string;
|
|
status: MessageStatus;
|
|
contentType?: string;
|
|
attachments?: GHLAttachment[];
|
|
meta?: Record<string, any>;
|
|
source?: string;
|
|
userId?: string;
|
|
dateAdded?: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface GHLAttachment {
|
|
url: string;
|
|
type?: string;
|
|
name?: string;
|
|
}
|
|
|
|
export interface SendMessageDTO {
|
|
type: 'SMS' | 'Email' | 'WhatsApp' | 'GMB' | 'FB' | 'IG' | 'Live_Chat' | 'Custom';
|
|
contactId: string;
|
|
message?: string;
|
|
subject?: string;
|
|
html?: string;
|
|
attachments?: string[];
|
|
emailFrom?: string;
|
|
emailReplyTo?: string;
|
|
emailBcc?: string[];
|
|
emailCc?: string[];
|
|
templateId?: string;
|
|
scheduledTimestamp?: number;
|
|
}
|
|
|
|
// =============================================================================
|
|
// GHL Opportunity Types
|
|
// =============================================================================
|
|
|
|
export type OpportunityStatus = 'open' | 'won' | 'lost' | 'abandoned';
|
|
|
|
export interface GHLOpportunity {
|
|
id: string;
|
|
locationId: string;
|
|
contactId: string;
|
|
contact?: GHLContact;
|
|
pipelineId: string;
|
|
pipelineStageId: string;
|
|
name: string;
|
|
monetaryValue?: number;
|
|
status: OpportunityStatus;
|
|
assignedTo?: string;
|
|
source?: string;
|
|
customFields?: Record<string, any>;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface CreateOpportunityDTO {
|
|
pipelineId: string;
|
|
pipelineStageId: string;
|
|
contactId: string;
|
|
name: string;
|
|
monetaryValue?: number;
|
|
status?: OpportunityStatus;
|
|
assignedTo?: string;
|
|
source?: string;
|
|
customFields?: Record<string, any>;
|
|
}
|
|
|
|
export interface UpdateOpportunityDTO extends Partial<CreateOpportunityDTO> {
|
|
id: string;
|
|
}
|
|
|
|
export interface GHLPipeline {
|
|
id: string;
|
|
locationId: string;
|
|
name: string;
|
|
stages: GHLPipelineStage[];
|
|
}
|
|
|
|
export interface GHLPipelineStage {
|
|
id: string;
|
|
name: string;
|
|
position: number;
|
|
showInFunnel?: boolean;
|
|
probability?: number;
|
|
}
|
|
|
|
// =============================================================================
|
|
// GHL Location (Sub-account) Types
|
|
// =============================================================================
|
|
|
|
export interface GHLLocation {
|
|
id: string;
|
|
name: string;
|
|
email?: string;
|
|
phone?: string;
|
|
companyId: string;
|
|
address?: string;
|
|
city?: string;
|
|
state?: string;
|
|
country?: string;
|
|
postalCode?: string;
|
|
website?: string;
|
|
timezone?: string;
|
|
logoUrl?: string;
|
|
settings?: GHLLocationSettings;
|
|
}
|
|
|
|
export interface GHLLocationSettings {
|
|
allowDuplicateContact?: boolean;
|
|
allowDuplicateOpportunity?: boolean;
|
|
allowFacebookNameMerge?: boolean;
|
|
disableContactTimezone?: boolean;
|
|
}
|
|
|
|
export interface CreateLocationDTO {
|
|
companyId: string;
|
|
name: string;
|
|
email?: string;
|
|
phone?: string;
|
|
address?: string;
|
|
city?: string;
|
|
state?: string;
|
|
country?: string;
|
|
postalCode?: string;
|
|
website?: string;
|
|
timezone?: string;
|
|
}
|
|
|
|
// =============================================================================
|
|
// GHL Workflow Types
|
|
// =============================================================================
|
|
|
|
export type WorkflowStatus = 'active' | 'inactive' | 'draft';
|
|
|
|
export interface GHLWorkflow {
|
|
id: string;
|
|
locationId: string;
|
|
name: string;
|
|
status: WorkflowStatus;
|
|
version?: number;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
}
|
|
|
|
// =============================================================================
|
|
// GHL Calendar Types
|
|
// =============================================================================
|
|
|
|
export interface GHLCalendar {
|
|
id: string;
|
|
locationId: string;
|
|
name: string;
|
|
description?: string;
|
|
calendarType?: 'round_robin' | 'event' | 'class_booking' | 'collective' | 'service_booking';
|
|
teamMembers?: string[];
|
|
eventColor?: string;
|
|
isActive?: boolean;
|
|
}
|
|
|
|
export interface GHLAppointment {
|
|
id: string;
|
|
locationId: string;
|
|
calendarId: string;
|
|
contactId: string;
|
|
title: string;
|
|
status: 'confirmed' | 'cancelled' | 'no_show' | 'completed';
|
|
startTime: string;
|
|
endTime: string;
|
|
appointmentStatus?: string;
|
|
assignedUserId?: string;
|
|
notes?: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
// =============================================================================
|
|
// GHL Tag Types
|
|
// =============================================================================
|
|
|
|
export interface GHLTag {
|
|
id: string;
|
|
locationId: string;
|
|
name: string;
|
|
}
|
|
|
|
export interface CreateTagDTO {
|
|
name: string;
|
|
}
|
|
|
|
// =============================================================================
|
|
// GHL Custom Field Types
|
|
// =============================================================================
|
|
|
|
export type CustomFieldDataType = 'TEXT' | 'LARGE_TEXT' | 'NUMERICAL' | 'PHONE' | 'MONETORY' | 'CHECKBOX' | 'SINGLE_OPTIONS' | 'MULTIPLE_OPTIONS' | 'FLOAT' | 'TIME' | 'DATE' | 'TEXTBOX_LIST' | 'FILE_UPLOAD' | 'SIGNATURE';
|
|
|
|
export interface GHLCustomField {
|
|
id: string;
|
|
locationId: string;
|
|
name: string;
|
|
fieldKey: string;
|
|
dataType: CustomFieldDataType;
|
|
placeholder?: string;
|
|
position?: number;
|
|
options?: string[];
|
|
model?: 'contact' | 'opportunity';
|
|
}
|
|
|
|
// =============================================================================
|
|
// GHL API Response Wrappers
|
|
// =============================================================================
|
|
|
|
export interface GHLPaginatedResponse<T> {
|
|
data: T[];
|
|
meta: {
|
|
total: number;
|
|
currentPage: number;
|
|
nextPage?: number;
|
|
prevPage?: number;
|
|
startAfter?: string;
|
|
startAfterId?: string;
|
|
};
|
|
}
|
|
|
|
export interface GHLSingleResponse<T> {
|
|
data: T;
|
|
}
|
|
|
|
export interface GHLErrorResponse {
|
|
statusCode: number;
|
|
message: string;
|
|
error?: string;
|
|
}
|
|
|
|
// =============================================================================
|
|
// GHL Webhook Types
|
|
// =============================================================================
|
|
|
|
export type GHLWebhookEvent =
|
|
| 'ContactCreate'
|
|
| 'ContactDelete'
|
|
| 'ContactDndUpdate'
|
|
| 'ContactTagUpdate'
|
|
| 'ConversationUnreadUpdate'
|
|
| 'InboundMessage'
|
|
| 'OutboundMessage'
|
|
| 'NoteCreate'
|
|
| 'NoteDelete'
|
|
| 'OpportunityCreate'
|
|
| 'OpportunityDelete'
|
|
| 'OpportunityStageUpdate'
|
|
| 'OpportunityStatusUpdate'
|
|
| 'OpportunityMonetaryValueUpdate'
|
|
| 'OpportunityAssignedToUpdate'
|
|
| 'TaskCreate'
|
|
| 'TaskComplete'
|
|
| 'TaskDelete'
|
|
| 'AppointmentCreate'
|
|
| 'AppointmentDelete'
|
|
| 'AppointmentUpdate';
|
|
|
|
export interface GHLWebhookPayload<T = any> {
|
|
type: GHLWebhookEvent;
|
|
locationId: string;
|
|
data: T;
|
|
timestamp: string;
|
|
}
|