diff --git a/src/types/entities.ts b/src/types/entities.ts new file mode 100644 index 0000000..53e54e6 --- /dev/null +++ b/src/types/entities.ts @@ -0,0 +1,244 @@ +// Lead domain +export type LeadSource = + | 'WEBSITE' + | 'FACEBOOK_AD' + | 'GOOGLE_AD' + | 'INSTAGRAM' + | 'GOOGLE_MY_BUSINESS' + | 'REFERRAL' + | 'WALK_IN' + | 'WHATSAPP' + | 'PHONE' + | 'OTHER'; + +export type LeadStatus = + | 'NEW' + | 'CONTACTED' + | 'QUALIFIED' + | 'NURTURING' + | 'APPOINTMENT_SET' + | 'CONVERTED' + | 'LOST'; + +export type Priority = 'LOW' | 'NORMAL' | 'HIGH' | 'URGENT'; + +// Campaign domain +export type CampaignType = + | 'OUTBOUND_CALL' + | 'WHATSAPP' + | 'SMS' + | 'EMAIL' + | 'FACEBOOK_AD' + | 'GOOGLE_AD' + | 'INSTAGRAM_AD'; + +export type CampaignStatus = 'DRAFT' | 'ACTIVE' | 'PAUSED' | 'COMPLETED'; + +export type CampaignPlatform = 'FACEBOOK' | 'GOOGLE' | 'INSTAGRAM' | 'YOUTUBE' | 'MANUAL'; + +// Ad domain +export type AdStatus = 'DRAFT' | 'ACTIVE' | 'PAUSED' | 'ENDED'; + +export type AdFormat = 'IMAGE' | 'VIDEO' | 'CAROUSEL' | 'TEXT' | 'LEAD_FORM'; + +// Activity domain +export type LeadActivityType = + | 'STATUS_CHANGE' + | 'CALL_MADE' + | 'CALL_RECEIVED' + | 'WHATSAPP_SENT' + | 'WHATSAPP_RECEIVED' + | 'SMS_SENT' + | 'EMAIL_SENT' + | 'EMAIL_RECEIVED' + | 'NOTE_ADDED' + | 'ASSIGNED' + | 'APPOINTMENT_BOOKED' + | 'FOLLOW_UP_CREATED' + | 'CONVERTED' + | 'MARKED_SPAM' + | 'DUPLICATE_DETECTED'; + +export type Channel = 'PHONE' | 'WHATSAPP' | 'SMS' | 'EMAIL' | 'IN_PERSON' | 'SYSTEM'; + +export type ActivityOutcome = + | 'SUCCESSFUL' + | 'NO_ANSWER' + | 'BUSY' + | 'NOT_INTERESTED' + | 'CALLBACK_REQUESTED' + | 'INFORMATION_SENT'; + +// Follow-up domain +export type FollowUpType = 'CALLBACK' | 'APPOINTMENT_REMINDER' | 'POST_VISIT' | 'MARKETING' | 'REVIEW_REQUEST'; + +export type FollowUpStatus = 'PENDING' | 'COMPLETED' | 'CANCELLED' | 'OVERDUE'; + +// Messaging domain +export type MessageDirection = 'CLINIC_TO_PATIENT' | 'PATIENT_TO_CLINIC'; + +export type MessageChannel = 'WHATSAPP' | 'SMS' | 'EMAIL' | 'IN_APP'; + +export type MessageStatus = 'SENT' | 'DELIVERED' | 'READ' | 'FAILED'; + +export type TemplateApprovalStatus = 'APPROVED' | 'PENDING' | 'REJECTED'; + +// System +export type HealthStatus = 'HEALTHY' | 'WARNING' | 'UNHEALTHY'; + +// Shared sub-types +type CurrencyAmount = { + amountMicros: number; + currencyCode: string; +}; + +// Entity types +export type Lead = { + id: string; + createdAt: string | null; + updatedAt: string | null; + leadSource: LeadSource | null; + leadStatus: LeadStatus | null; + priority: Priority | null; + contactName: { firstName: string; lastName: string } | null; + contactPhone: { number: string; callingCode: string }[] | null; + contactEmail: { address: string }[] | null; + interestedService: string | null; + assignedAgent: string | null; + utmSource: string | null; + utmMedium: string | null; + utmCampaign: string | null; + utmContent: string | null; + utmTerm: string | null; + landingPageUrl: string | null; + referrerUrl: string | null; + leadScore: number | null; + spamScore: number | null; + isSpam: boolean | null; + isDuplicate: boolean | null; + duplicateOfLeadId: string | null; + firstContactedAt: string | null; + lastContactedAt: string | null; + contactAttempts: number | null; + convertedAt: string | null; + patientId: string | null; + campaignId: string | null; + adId: string | null; +}; + +export type Campaign = { + id: string; + createdAt: string | null; + updatedAt: string | null; + campaignName: string | null; + campaignType: CampaignType | null; + campaignStatus: CampaignStatus | null; + platform: CampaignPlatform | null; + startDate: string | null; + endDate: string | null; + budget: CurrencyAmount | null; + amountSpent: CurrencyAmount | null; + impressionCount: number | null; + clickCount: number | null; + targetCount: number | null; + contactedCount: number | null; + convertedCount: number | null; + leadCount: number | null; + externalCampaignId: string | null; + platformUrl: string | null; +}; + +export type Ad = { + id: string; + createdAt: string | null; + updatedAt: string | null; + adName: string | null; + externalAdId: string | null; + adStatus: AdStatus | null; + adFormat: AdFormat | null; + headline: string | null; + adDescription: string | null; + destinationUrl: string | null; + previewUrl: string | null; + impressions: number | null; + clicks: number | null; + conversions: number | null; + spend: CurrencyAmount | null; + campaignId: string | null; +}; + +export type LeadActivity = { + id: string; + createdAt: string | null; + activityType: LeadActivityType | null; + summary: string | null; + occurredAt: string | null; + performedBy: string | null; + previousValue: string | null; + newValue: string | null; + channel: Channel | null; + durationSeconds: number | null; + outcome: ActivityOutcome | null; + leadId: string | null; +}; + +export type FollowUp = { + id: string; + createdAt: string | null; + followUpType: FollowUpType | null; + followUpStatus: FollowUpStatus | null; + scheduledAt: string | null; + completedAt: string | null; + priority: Priority | null; + assignedAgent: string | null; + patientId: string | null; + callId: string | null; + // Denormalized fields + patientName?: string; + patientPhone?: string; + description?: string; +}; + +export type PatientMessage = { + id: string; + createdAt: string | null; + subject: string | null; + body: string | null; + direction: MessageDirection | null; + channel: MessageChannel | null; + priority: Priority | null; + sentAt: string | null; + readAt: string | null; + senderName: string | null; + patientId: string | null; + // Optional fields + status?: MessageStatus; + recipientName?: string; + recipientPhone?: string; +}; + +export type WhatsAppTemplate = { + id: string; + name: string | null; + body: string | null; + variables: string[]; + linkedCampaignId: string | null; + linkedCampaignName: string | null; + approvalStatus: TemplateApprovalStatus | null; + language: string[]; + sendCount: number | null; + deliveredCount: number | null; + readCount: number | null; + clickedCount: number | null; + failedCount: number | null; +}; + +export type Agent = { + id: string; + name: string | null; + initials: string | null; + isOnShift: boolean | null; + shiftNote: string | null; + avgResponseHours: number | null; + activeLeadCount: number | null; +};