@ebowwa/crm 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +174 -0
  2. package/dist/cli/commands/activities.d.ts +11 -0
  3. package/dist/cli/commands/activities.d.ts.map +1 -0
  4. package/dist/cli/commands/activities.js +427 -0
  5. package/dist/cli/commands/activities.js.map +1 -0
  6. package/dist/cli/commands/contacts.d.ts +11 -0
  7. package/dist/cli/commands/contacts.d.ts.map +1 -0
  8. package/dist/cli/commands/contacts.js +458 -0
  9. package/dist/cli/commands/contacts.js.map +1 -0
  10. package/dist/cli/commands/deals.d.ts +11 -0
  11. package/dist/cli/commands/deals.d.ts.map +1 -0
  12. package/dist/cli/commands/deals.js +498 -0
  13. package/dist/cli/commands/deals.js.map +1 -0
  14. package/dist/cli/commands/media.d.ts +11 -0
  15. package/dist/cli/commands/media.d.ts.map +1 -0
  16. package/dist/cli/commands/media.js +417 -0
  17. package/dist/cli/commands/media.js.map +1 -0
  18. package/dist/cli/commands/search.d.ts +11 -0
  19. package/dist/cli/commands/search.d.ts.map +1 -0
  20. package/dist/cli/commands/search.js +346 -0
  21. package/dist/cli/commands/search.js.map +1 -0
  22. package/dist/cli/index.d.ts +13 -0
  23. package/dist/cli/index.d.ts.map +1 -0
  24. package/dist/cli/index.js +173 -0
  25. package/dist/cli/index.js.map +1 -0
  26. package/dist/cli/repl.d.ts +15 -0
  27. package/dist/cli/repl.d.ts.map +1 -0
  28. package/dist/cli/repl.js +318 -0
  29. package/dist/cli/repl.js.map +1 -0
  30. package/dist/cli/utils/config.d.ts +91 -0
  31. package/dist/cli/utils/config.d.ts.map +1 -0
  32. package/dist/cli/utils/config.js +212 -0
  33. package/dist/cli/utils/config.js.map +1 -0
  34. package/dist/cli/utils/output.d.ts +136 -0
  35. package/dist/cli/utils/output.d.ts.map +1 -0
  36. package/dist/cli/utils/output.js +323 -0
  37. package/dist/cli/utils/output.js.map +1 -0
  38. package/dist/cli/utils/prompt.d.ts +81 -0
  39. package/dist/cli/utils/prompt.d.ts.map +1 -0
  40. package/dist/cli/utils/prompt.js +341 -0
  41. package/dist/cli/utils/prompt.js.map +1 -0
  42. package/dist/cli.d.ts +3 -0
  43. package/dist/cli.d.ts.map +1 -0
  44. package/dist/cli.js +8 -0
  45. package/dist/cli.js.map +1 -0
  46. package/dist/core/index.d.ts +6 -0
  47. package/dist/core/index.d.ts.map +1 -0
  48. package/dist/core/index.js +32 -0
  49. package/dist/core/index.js.map +1 -0
  50. package/dist/core/schemas.d.ts +3050 -0
  51. package/dist/core/schemas.d.ts.map +1 -0
  52. package/dist/core/schemas.js +667 -0
  53. package/dist/core/schemas.js.map +1 -0
  54. package/dist/core/types.d.ts +597 -0
  55. package/dist/core/types.d.ts.map +1 -0
  56. package/dist/core/types.js +8 -0
  57. package/dist/core/types.js.map +1 -0
  58. package/dist/index.d.ts +7 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +8 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/mcp/index.d.ts +14 -0
  63. package/dist/mcp/index.d.ts.map +1 -0
  64. package/dist/mcp/index.js +11 -0
  65. package/dist/mcp/index.js.map +1 -0
  66. package/dist/mcp/server.d.ts +13 -0
  67. package/dist/mcp/server.d.ts.map +1 -0
  68. package/dist/mcp/server.js +18 -0
  69. package/dist/mcp/server.js.map +1 -0
  70. package/dist/mcp/storage/client.d.ts +109 -0
  71. package/dist/mcp/storage/client.d.ts.map +1 -0
  72. package/dist/mcp/storage/client.js +355 -0
  73. package/dist/mcp/storage/client.js.map +1 -0
  74. package/dist/mcp/storage/index.d.ts +7 -0
  75. package/dist/mcp/storage/index.d.ts.map +1 -0
  76. package/dist/mcp/storage/index.js +6 -0
  77. package/dist/mcp/storage/index.js.map +1 -0
  78. package/dist/mcp/storage/types.d.ts +44 -0
  79. package/dist/mcp/storage/types.d.ts.map +1 -0
  80. package/dist/mcp/storage/types.js +35 -0
  81. package/dist/mcp/storage/types.js.map +1 -0
  82. package/dist/mcp/tools/definitions.d.ts +16 -0
  83. package/dist/mcp/tools/definitions.d.ts.map +1 -0
  84. package/dist/mcp/tools/definitions.js +914 -0
  85. package/dist/mcp/tools/definitions.js.map +1 -0
  86. package/dist/mcp/tools/handlers.d.ts +50 -0
  87. package/dist/mcp/tools/handlers.d.ts.map +1 -0
  88. package/dist/mcp/tools/handlers.js +760 -0
  89. package/dist/mcp/tools/handlers.js.map +1 -0
  90. package/dist/mcp/tools/index.d.ts +7 -0
  91. package/dist/mcp/tools/index.d.ts.map +1 -0
  92. package/dist/mcp/tools/index.js +6 -0
  93. package/dist/mcp/tools/index.js.map +1 -0
  94. package/dist/mcp/tools/types.d.ts +314 -0
  95. package/dist/mcp/tools/types.d.ts.map +1 -0
  96. package/dist/mcp/tools/types.js +5 -0
  97. package/dist/mcp/tools/types.js.map +1 -0
  98. package/dist/mcp/transports/stdio.d.ts +27 -0
  99. package/dist/mcp/transports/stdio.d.ts.map +1 -0
  100. package/dist/mcp/transports/stdio.js +237 -0
  101. package/dist/mcp/transports/stdio.js.map +1 -0
  102. package/dist/telemetry/index.d.ts +58 -0
  103. package/dist/telemetry/index.d.ts.map +1 -0
  104. package/dist/telemetry/index.js +109 -0
  105. package/dist/telemetry/index.js.map +1 -0
  106. package/dist/telemetry/logger.d.ts +116 -0
  107. package/dist/telemetry/logger.d.ts.map +1 -0
  108. package/dist/telemetry/logger.js +256 -0
  109. package/dist/telemetry/logger.js.map +1 -0
  110. package/dist/telemetry/metrics.d.ts +115 -0
  111. package/dist/telemetry/metrics.d.ts.map +1 -0
  112. package/dist/telemetry/metrics.js +292 -0
  113. package/dist/telemetry/metrics.js.map +1 -0
  114. package/dist/telemetry/tracer.d.ts +227 -0
  115. package/dist/telemetry/tracer.d.ts.map +1 -0
  116. package/dist/telemetry/tracer.js +355 -0
  117. package/dist/telemetry/tracer.js.map +1 -0
  118. package/dist/web/app.d.ts +2 -0
  119. package/dist/web/app.d.ts.map +1 -0
  120. package/dist/web/app.js +115 -0
  121. package/dist/web/app.js.map +1 -0
  122. package/dist/web/components/ContactList.d.ts +3 -0
  123. package/dist/web/components/ContactList.d.ts.map +1 -0
  124. package/dist/web/components/ContactList.js +262 -0
  125. package/dist/web/components/ContactList.js.map +1 -0
  126. package/dist/web/components/Dashboard.d.ts +3 -0
  127. package/dist/web/components/Dashboard.d.ts.map +1 -0
  128. package/dist/web/components/Dashboard.js +158 -0
  129. package/dist/web/components/Dashboard.js.map +1 -0
  130. package/dist/web/components/DealPipeline.d.ts +3 -0
  131. package/dist/web/components/DealPipeline.d.ts.map +1 -0
  132. package/dist/web/components/DealPipeline.js +306 -0
  133. package/dist/web/components/DealPipeline.js.map +1 -0
  134. package/dist/web/index.d.ts +2 -0
  135. package/dist/web/index.d.ts.map +1 -0
  136. package/dist/web/index.js +269 -0
  137. package/dist/web/index.js.map +1 -0
  138. package/dist/web/types.d.ts +75 -0
  139. package/dist/web/types.d.ts.map +1 -0
  140. package/dist/web/types.js +3 -0
  141. package/dist/web/types.js.map +1 -0
  142. package/native/index.d.ts +571 -0
  143. package/native/index.js +687 -0
  144. package/package.json +105 -0
  145. package/src/cli/commands/activities.ts +543 -0
  146. package/src/cli/commands/contacts.ts +563 -0
  147. package/src/cli/commands/deals.ts +637 -0
  148. package/src/cli/commands/media.ts +521 -0
  149. package/src/cli/commands/search.ts +426 -0
  150. package/src/cli/index.ts +203 -0
  151. package/src/cli/repl.ts +379 -0
  152. package/src/cli/utils/config.ts +299 -0
  153. package/src/cli/utils/output.ts +386 -0
  154. package/src/cli/utils/prompt.ts +444 -0
  155. package/src/cli.ts +11 -0
  156. package/src/core/index.ts +184 -0
  157. package/src/core/schemas.ts +770 -0
  158. package/src/core/types.ts +969 -0
  159. package/src/index.ts +8 -0
  160. package/src/mcp/index.ts +17 -0
  161. package/src/mcp/server.ts +26 -0
  162. package/src/mcp/storage/client.ts +408 -0
  163. package/src/mcp/storage/index.ts +7 -0
  164. package/src/mcp/storage/types.ts +72 -0
  165. package/src/mcp/tools/definitions.ts +961 -0
  166. package/src/mcp/tools/handlers.ts +805 -0
  167. package/src/mcp/tools/index.ts +7 -0
  168. package/src/mcp/tools/types.ts +390 -0
  169. package/src/mcp/transports/stdio.ts +225 -0
  170. package/src/telemetry/index.ts +131 -0
  171. package/src/telemetry/logger.ts +318 -0
  172. package/src/telemetry/metrics.ts +393 -0
  173. package/src/telemetry/tracer.ts +487 -0
  174. package/src/web/api/activities.ts +41 -0
  175. package/src/web/api/contacts.ts +114 -0
  176. package/src/web/api/deals.ts +108 -0
  177. package/src/web/api/media.ts +98 -0
  178. package/src/web/app.tsx +143 -0
  179. package/src/web/components/ActivityFeed.tsx +195 -0
  180. package/src/web/components/ContactList.tsx +340 -0
  181. package/src/web/components/Dashboard.tsx +214 -0
  182. package/src/web/components/DealPipeline.tsx +405 -0
  183. package/src/web/components/MediaGallery.tsx +334 -0
  184. package/src/web/index.html +14 -0
  185. package/src/web/index.ts +326 -0
  186. package/src/web/styles/main.css +180 -0
  187. package/src/web/types.ts +311 -0
@@ -0,0 +1,969 @@
1
+ /**
2
+ * Core Types for CRM System
3
+ *
4
+ * Defines all TypeScript interfaces for the CRM data model.
5
+ * Supports contacts, deals, activities, media, notes, and tags.
6
+ */
7
+
8
+ // ============================================================================
9
+ // Base Types
10
+ // ============================================================================
11
+
12
+ /** Unique identifier type */
13
+ export type UUID = string;
14
+
15
+ /** ISO 8601 timestamp string */
16
+ export type Timestamp = string;
17
+
18
+ /** Generic metadata object */
19
+ export interface Metadata {
20
+ [key: string]: string | number | boolean | null | Metadata | Metadata[];
21
+ }
22
+
23
+ /** Base entity with common fields */
24
+ export interface BaseEntity {
25
+ id: UUID;
26
+ createdAt: Timestamp;
27
+ updatedAt: Timestamp;
28
+ }
29
+
30
+ // ============================================================================
31
+ // Contact Types
32
+ // ============================================================================
33
+
34
+ /** Contact phone number with type */
35
+ export interface PhoneNumber {
36
+ number: string;
37
+ type: 'mobile' | 'home' | 'work' | 'other';
38
+ primary: boolean;
39
+ }
40
+
41
+ /** Contact email address with type */
42
+ export interface EmailAddress {
43
+ email: string;
44
+ type: 'personal' | 'work' | 'other';
45
+ primary: boolean;
46
+ }
47
+
48
+ /** Contact address */
49
+ export interface Address {
50
+ street: string;
51
+ city: string;
52
+ state: string;
53
+ postalCode: string;
54
+ country: string;
55
+ type: 'home' | 'work' | 'billing' | 'shipping' | 'other';
56
+ }
57
+
58
+ /** Social media profile */
59
+ export interface SocialProfile {
60
+ platform: 'linkedin' | 'twitter' | 'facebook' | 'instagram' | 'github' | 'other';
61
+ handle: string;
62
+ url?: string;
63
+ }
64
+
65
+ /** Custom field value */
66
+ export interface CustomField {
67
+ key: string;
68
+ value: string | number | boolean | Date | null;
69
+ type: 'string' | 'number' | 'boolean' | 'date' | 'select' | 'multiselect';
70
+ }
71
+
72
+ /** Contact source tracking */
73
+ export type ContactSource =
74
+ | 'organic'
75
+ | 'referral'
76
+ | 'advertisement'
77
+ | 'social_media'
78
+ | 'email_campaign'
79
+ | 'website'
80
+ | 'event'
81
+ | 'cold_outreach'
82
+ | 'partner'
83
+ | 'other';
84
+
85
+ /** Contact status in the pipeline */
86
+ export type ContactStatus =
87
+ | 'lead'
88
+ | 'prospect'
89
+ | 'qualified'
90
+ | 'customer'
91
+ | 'churned'
92
+ | 'archived';
93
+
94
+ /**
95
+ * Contact entity representing a person or organization in the CRM
96
+ */
97
+ export interface Contact extends BaseEntity {
98
+ /** Full name of the contact */
99
+ name: string;
100
+
101
+ /** First name */
102
+ firstName?: string;
103
+
104
+ /** Last name */
105
+ lastName?: string;
106
+
107
+ /** Email addresses (supports multiple) */
108
+ emails: EmailAddress[];
109
+
110
+ /** Phone numbers (supports multiple) */
111
+ phones: PhoneNumber[];
112
+
113
+ /** Physical addresses */
114
+ addresses: Address[];
115
+
116
+ /** Company/organization name */
117
+ company?: string;
118
+
119
+ /** Job title/position */
120
+ title?: string;
121
+
122
+ /** Department within company */
123
+ department?: string;
124
+
125
+ /** Social media profiles */
126
+ socialProfiles: SocialProfile[];
127
+
128
+ /** Website URL */
129
+ website?: string;
130
+
131
+ /** Tags for categorization */
132
+ tags: string[];
133
+
134
+ /** Custom fields for extensibility */
135
+ customFields: CustomField[];
136
+
137
+ /** Contact source/origin */
138
+ source?: ContactSource;
139
+
140
+ /** Current status in the pipeline */
141
+ status: ContactStatus;
142
+
143
+ /** Assigned owner/user ID */
144
+ ownerId?: UUID;
145
+
146
+ /** Profile picture URL or media ID */
147
+ avatar?: string;
148
+
149
+ /** Preferred contact method */
150
+ preferredContact?: 'email' | 'phone' | 'sms' | 'none';
151
+
152
+ /** Language preference (ISO code) */
153
+ language?: string;
154
+
155
+ /** Timezone (IANA format) */
156
+ timezone?: string;
157
+
158
+ /** Notes specific to contact preferences */
159
+ preferences?: string;
160
+
161
+ /** Lead score (0-100) */
162
+ leadScore?: number;
163
+
164
+ /** Do not contact flag */
165
+ doNotContact: boolean;
166
+
167
+ /** Last contact timestamp */
168
+ lastContactedAt?: Timestamp;
169
+
170
+ /** Next follow-up timestamp */
171
+ nextFollowUpAt?: Timestamp;
172
+ }
173
+
174
+ // ============================================================================
175
+ // Deal Types
176
+ // ============================================================================
177
+
178
+ /** Deal stage in the pipeline */
179
+ export type DealStage =
180
+ | 'prospecting'
181
+ | 'qualification'
182
+ | 'needs_analysis'
183
+ | 'proposal'
184
+ | 'negotiation'
185
+ | 'closed_won'
186
+ | 'closed_lost';
187
+
188
+ /** Deal priority level */
189
+ export type DealPriority = 'low' | 'medium' | 'high' | 'urgent';
190
+
191
+ /** Currency codes (ISO 4217 subset) */
192
+ export type Currency =
193
+ | 'USD'
194
+ | 'EUR'
195
+ | 'GBP'
196
+ | 'CAD'
197
+ | 'AUD'
198
+ | 'JPY'
199
+ | 'CNY'
200
+ | 'INR'
201
+ | 'BRL'
202
+ | 'MXN';
203
+
204
+ /** Product/line item in a deal */
205
+ export interface DealLineItem {
206
+ id: UUID;
207
+ name: string;
208
+ description?: string;
209
+ quantity: number;
210
+ unitPrice: number;
211
+ discount?: number;
212
+ discountType?: 'percentage' | 'fixed';
213
+ total: number;
214
+ }
215
+
216
+ /** Competitor information */
217
+ export interface Competitor {
218
+ name: string;
219
+ strengths?: string[];
220
+ weaknesses?: string[];
221
+ notes?: string;
222
+ }
223
+
224
+ /**
225
+ * Deal entity representing a sales opportunity
226
+ */
227
+ export interface Deal extends BaseEntity {
228
+ /** Deal title/name */
229
+ title: string;
230
+
231
+ /** Associated contact ID */
232
+ contactId: UUID;
233
+
234
+ /** Associated company ID (if different from contact) */
235
+ companyId?: UUID;
236
+
237
+ /** Deal value (monetary) */
238
+ value: number;
239
+
240
+ /** Currency of the deal value */
241
+ currency: Currency;
242
+
243
+ /** Current pipeline stage */
244
+ stage: DealStage;
245
+
246
+ /** Win probability percentage (0-100) */
247
+ probability: number;
248
+
249
+ /** Expected close date */
250
+ expectedClose: Timestamp;
251
+
252
+ /** Actual close date (if closed) */
253
+ actualClose?: Timestamp;
254
+
255
+ /** Deal priority */
256
+ priority: DealPriority;
257
+
258
+ /** Line items/products */
259
+ lineItems: DealLineItem[];
260
+
261
+ /** Discount applied to total */
262
+ discount?: number;
263
+
264
+ /** Discount type */
265
+ discountType?: 'percentage' | 'fixed';
266
+
267
+ /** Total deal value after discounts */
268
+ totalValue: number;
269
+
270
+ /** Detailed notes/description */
271
+ notes: string;
272
+
273
+ /** Tags for categorization */
274
+ tags: string[];
275
+
276
+ /** Competitors in this deal */
277
+ competitors: Competitor[];
278
+
279
+ /** Reason for loss (if lost) */
280
+ lossReason?: string;
281
+
282
+ /** Next steps/action items */
283
+ nextSteps?: string[];
284
+
285
+ /** Assigned owner/user ID */
286
+ ownerId?: UUID;
287
+
288
+ /** Source of the deal */
289
+ source?: string;
290
+
291
+ /** Custom fields */
292
+ customFields: CustomField[];
293
+
294
+ /** Last activity timestamp */
295
+ lastActivityAt?: Timestamp;
296
+ }
297
+
298
+ // ============================================================================
299
+ // Activity Types
300
+ // ============================================================================
301
+
302
+ /** Activity type classification */
303
+ export type ActivityType =
304
+ | 'call'
305
+ | 'email'
306
+ | 'meeting'
307
+ | 'task'
308
+ | 'note'
309
+ | 'sms'
310
+ | 'video_call'
311
+ | 'demo'
312
+ | 'proposal_sent'
313
+ | 'contract_sent'
314
+ | 'follow_up'
315
+ | 'social_media'
316
+ | 'event'
317
+ | 'other';
318
+
319
+ /** Call outcome */
320
+ export type CallOutcome =
321
+ | 'connected'
322
+ | 'voicemail'
323
+ | 'no_answer'
324
+ | 'busy'
325
+ | 'wrong_number'
326
+ | 'disconnected';
327
+
328
+ /** Meeting outcome */
329
+ export type MeetingOutcome =
330
+ | 'completed'
331
+ | 'rescheduled'
332
+ | 'cancelled'
333
+ | 'no_show';
334
+
335
+ /** Email status */
336
+ export type EmailStatus =
337
+ | 'sent'
338
+ | 'delivered'
339
+ | 'opened'
340
+ | 'clicked'
341
+ | 'replied'
342
+ | 'bounced'
343
+ | 'unsubscribed';
344
+
345
+ /** Call-specific metadata */
346
+ export interface CallMetadata {
347
+ outcome: CallOutcome;
348
+ recording?: string;
349
+ transcription?: string;
350
+ fromNumber?: string;
351
+ toNumber?: string;
352
+ direction: 'inbound' | 'outbound';
353
+ }
354
+
355
+ /** Meeting-specific metadata */
356
+ export interface MeetingMetadata {
357
+ outcome: MeetingOutcome;
358
+ location?: string;
359
+ meetingUrl?: string;
360
+ calendarEventId?: string;
361
+ attendees?: string[];
362
+ recording?: string;
363
+ notes?: string;
364
+ }
365
+
366
+ /** Email-specific metadata */
367
+ export interface EmailMetadata {
368
+ status: EmailStatus;
369
+ subject: string;
370
+ from: string;
371
+ to: string[];
372
+ cc?: string[];
373
+ bcc?: string[];
374
+ templateId?: string;
375
+ trackingOpens: boolean;
376
+ trackingClicks: boolean;
377
+ }
378
+
379
+ /** Task-specific metadata */
380
+ export interface TaskMetadata {
381
+ status: 'pending' | 'in_progress' | 'completed' | 'cancelled';
382
+ dueDate?: Timestamp;
383
+ reminderAt?: Timestamp;
384
+ priority: 'low' | 'medium' | 'high';
385
+ assigneeId?: UUID;
386
+ checklist?: { item: string; completed: boolean }[];
387
+ }
388
+
389
+ /**
390
+ * Activity entity representing interactions with contacts/deals
391
+ */
392
+ export interface Activity extends BaseEntity {
393
+ /** Associated contact ID */
394
+ contactId?: UUID;
395
+
396
+ /** Associated deal ID */
397
+ dealId?: UUID;
398
+
399
+ /** Activity type */
400
+ type: ActivityType;
401
+
402
+ /** Activity title/subject */
403
+ title: string;
404
+
405
+ /** Detailed description */
406
+ description: string;
407
+
408
+ /** Activity timestamp */
409
+ timestamp: Timestamp;
410
+
411
+ /** Duration in seconds (for calls, meetings) */
412
+ duration?: number;
413
+
414
+ /** Activity-specific metadata */
415
+ metadata: CallMetadata | MeetingMetadata | EmailMetadata | TaskMetadata | Metadata;
416
+
417
+ /** User who created the activity */
418
+ createdBy?: UUID;
419
+
420
+ /** Tags for categorization */
421
+ tags: string[];
422
+
423
+ /** Custom fields */
424
+ customFields: CustomField[];
425
+ }
426
+
427
+ // ============================================================================
428
+ // Media Types
429
+ // ============================================================================
430
+
431
+ /** Media type classification */
432
+ export type MediaType =
433
+ | 'image'
434
+ | 'video'
435
+ | 'audio'
436
+ | 'document'
437
+ | 'spreadsheet'
438
+ | 'presentation'
439
+ | 'pdf'
440
+ | 'archive'
441
+ | 'other';
442
+
443
+ /** Common MIME types for media */
444
+ export type MimeType =
445
+ // Images
446
+ | 'image/jpeg'
447
+ | 'image/png'
448
+ | 'image/gif'
449
+ | 'image/webp'
450
+ | 'image/svg+xml'
451
+ | 'image/bmp'
452
+ // Videos
453
+ | 'video/mp4'
454
+ | 'video/webm'
455
+ | 'video/quicktime'
456
+ | 'video/x-msvideo'
457
+ // Audio
458
+ | 'audio/mpeg'
459
+ | 'audio/wav'
460
+ | 'audio/ogg'
461
+ | 'audio/webm'
462
+ // Documents
463
+ | 'application/pdf'
464
+ | 'application/msword'
465
+ | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
466
+ | 'application/vnd.ms-excel'
467
+ | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
468
+ | 'application/vnd.ms-powerpoint'
469
+ | 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
470
+ | 'text/plain'
471
+ | 'text/csv'
472
+ // Archives
473
+ | 'application/zip'
474
+ | 'application/x-rar-compressed'
475
+ | 'application/x-7z-compressed'
476
+ // Other
477
+ | string;
478
+
479
+ /** Image-specific metadata */
480
+ export interface ImageMetadata {
481
+ width?: number;
482
+ height?: number;
483
+ orientation?: 'landscape' | 'portrait' | 'square';
484
+ colorSpace?: string;
485
+ hasAlpha?: boolean;
486
+ }
487
+
488
+ /** Video-specific metadata */
489
+ export interface VideoMetadata {
490
+ width?: number;
491
+ height?: number;
492
+ duration?: number;
493
+ frameRate?: number;
494
+ codec?: string;
495
+ bitrate?: number;
496
+ hasAudio?: boolean;
497
+ }
498
+
499
+ /** Audio-specific metadata */
500
+ export interface AudioMetadata {
501
+ duration?: number;
502
+ sampleRate?: number;
503
+ channels?: number;
504
+ bitrate?: number;
505
+ codec?: string;
506
+ }
507
+
508
+ /** Document-specific metadata */
509
+ export interface DocumentMetadata {
510
+ pageCount?: number;
511
+ author?: string;
512
+ title?: string;
513
+ subject?: string;
514
+ keywords?: string[];
515
+ createdAt?: Timestamp;
516
+ modifiedAt?: Timestamp;
517
+ }
518
+
519
+ /**
520
+ * Media entity representing files attached to CRM entities
521
+ */
522
+ export interface Media extends BaseEntity {
523
+ /** Entity type this media is attached to */
524
+ entityType: 'contact' | 'deal' | 'activity' | 'note' | 'company';
525
+
526
+ /** ID of the entity this media belongs to */
527
+ entityId: UUID;
528
+
529
+ /** Media type classification */
530
+ type: MediaType;
531
+
532
+ /** Original filename */
533
+ filename: string;
534
+
535
+ /** MIME type */
536
+ mimeType: MimeType;
537
+
538
+ /** File size in bytes */
539
+ size: number;
540
+
541
+ /** Storage URL or path */
542
+ url: string;
543
+
544
+ /** Thumbnail URL (for images/videos) */
545
+ thumbnailUrl?: string;
546
+
547
+ /** Media-specific metadata */
548
+ metadata: ImageMetadata | VideoMetadata | AudioMetadata | DocumentMetadata | Metadata;
549
+
550
+ /** Alt text for accessibility */
551
+ altText?: string;
552
+
553
+ /** Caption/description */
554
+ caption?: string;
555
+
556
+ /** Is this media public/external */
557
+ isPublic: boolean;
558
+
559
+ /** Download count */
560
+ downloadCount: number;
561
+
562
+ /** User who uploaded */
563
+ uploadedBy?: UUID;
564
+
565
+ /** Expiration date (for temporary files) */
566
+ expiresAt?: Timestamp;
567
+ }
568
+
569
+ // ============================================================================
570
+ // Note Types
571
+ // ============================================================================
572
+
573
+ /** Note visibility level */
574
+ export type NoteVisibility = 'private' | 'team' | 'public';
575
+
576
+ /**
577
+ * Note entity for freeform text attached to contacts/deals
578
+ */
579
+ export interface Note extends BaseEntity {
580
+ /** Associated contact ID */
581
+ contactId?: UUID;
582
+
583
+ /** Associated deal ID */
584
+ dealId?: UUID;
585
+
586
+ /** Associated activity ID */
587
+ activityId?: UUID;
588
+
589
+ /** Note content (supports markdown) */
590
+ content: string;
591
+
592
+ /** Content format */
593
+ format: 'plain' | 'markdown' | 'html';
594
+
595
+ /** Note title/subject */
596
+ title?: string;
597
+
598
+ /** Visibility level */
599
+ visibility: NoteVisibility;
600
+
601
+ /** User who created the note */
602
+ createdBy?: UUID;
603
+
604
+ /** Pinned/important flag */
605
+ pinned: boolean;
606
+
607
+ /** Tags for categorization */
608
+ tags: string[];
609
+
610
+ /** Attached media IDs */
611
+ mediaIds: UUID[];
612
+ }
613
+
614
+ // ============================================================================
615
+ // Tag Types
616
+ // ============================================================================
617
+
618
+ /** Tag category */
619
+ export type TagCategory =
620
+ | 'general'
621
+ | 'industry'
622
+ | 'source'
623
+ | 'status'
624
+ | 'priority'
625
+ | 'product'
626
+ | 'region'
627
+ | 'custom';
628
+
629
+ /**
630
+ * Tag entity for categorizing contacts and deals
631
+ */
632
+ export interface Tag {
633
+ /** Unique identifier */
634
+ id: UUID;
635
+
636
+ /** Tag name (slug-friendly) */
637
+ name: string;
638
+
639
+ /** Display label */
640
+ label: string;
641
+
642
+ /** Color (hex code or named color) */
643
+ color: string;
644
+
645
+ /** Tag category */
646
+ category: TagCategory;
647
+
648
+ /** Description */
649
+ description?: string;
650
+
651
+ /** Icon (emoji or icon name) */
652
+ icon?: string;
653
+
654
+ /** Usage count */
655
+ usageCount: number;
656
+
657
+ /** Parent tag ID (for hierarchical tags) */
658
+ parentId?: UUID;
659
+
660
+ /** Created timestamp */
661
+ createdAt: Timestamp;
662
+
663
+ /** Updated timestamp */
664
+ updatedAt: Timestamp;
665
+ }
666
+
667
+ // ============================================================================
668
+ // Company Types (for B2B CRM)
669
+ // ============================================================================
670
+
671
+ /** Company size category */
672
+ export type CompanySize =
673
+ | 'sole_proprietor'
674
+ | 'startup'
675
+ | 'small'
676
+ | 'medium'
677
+ | 'large'
678
+ | 'enterprise';
679
+
680
+ /** Company industry classification */
681
+ export type Industry =
682
+ | 'technology'
683
+ | 'finance'
684
+ | 'healthcare'
685
+ | 'education'
686
+ | 'retail'
687
+ | 'manufacturing'
688
+ | 'consulting'
689
+ | 'marketing'
690
+ | 'legal'
691
+ | 'real_estate'
692
+ | 'construction'
693
+ | 'transportation'
694
+ | 'hospitality'
695
+ | 'energy'
696
+ | 'telecommunications'
697
+ | 'government'
698
+ | 'non_profit'
699
+ | 'other';
700
+
701
+ /**
702
+ * Company entity for B2B relationships
703
+ */
704
+ export interface Company extends BaseEntity {
705
+ /** Company name */
706
+ name: string;
707
+
708
+ /** Website URL */
709
+ website?: string;
710
+
711
+ /** Industry classification */
712
+ industry?: Industry;
713
+
714
+ /** Company size category */
715
+ size?: CompanySize;
716
+
717
+ /** Employee count */
718
+ employeeCount?: number;
719
+
720
+ /** Annual revenue */
721
+ annualRevenue?: number;
722
+
723
+ /** Currency for revenue */
724
+ currency?: Currency;
725
+
726
+ /** Company address */
727
+ address?: Address;
728
+
729
+ /** Phone number */
730
+ phone?: string;
731
+
732
+ /** Email domain */
733
+ emailDomain?: string;
734
+
735
+ /** LinkedIn company page */
736
+ linkedInUrl?: string;
737
+
738
+ /** Tags for categorization */
739
+ tags: string[];
740
+
741
+ /** Custom fields */
742
+ customFields: CustomField[];
743
+
744
+ /** Assigned owner/user ID */
745
+ ownerId?: UUID;
746
+
747
+ /** Notes about the company */
748
+ notes?: string;
749
+ }
750
+
751
+ // ============================================================================
752
+ // Pipeline Types
753
+ // ============================================================================
754
+
755
+ /** Pipeline stage definition */
756
+ export interface PipelineStage {
757
+ id: UUID;
758
+ name: string;
759
+ order: number;
760
+ probability: number;
761
+ color: string;
762
+ description?: string;
763
+ }
764
+
765
+ /** Sales pipeline */
766
+ export interface Pipeline {
767
+ id: UUID;
768
+ name: string;
769
+ description?: string;
770
+ stages: PipelineStage[];
771
+ isDefault: boolean;
772
+ createdAt: Timestamp;
773
+ updatedAt: Timestamp;
774
+ }
775
+
776
+ // ============================================================================
777
+ // Search and Filter Types
778
+ // ============================================================================
779
+
780
+ /** Sort direction */
781
+ export type SortDirection = 'asc' | 'desc';
782
+
783
+ /** Generic sort options */
784
+ export interface SortOptions<T extends string = string> {
785
+ field: T;
786
+ direction: SortDirection;
787
+ }
788
+
789
+ /** Pagination options */
790
+ export interface PaginationOptions {
791
+ page: number;
792
+ limit: number;
793
+ offset?: number;
794
+ }
795
+
796
+ /** Paginated response wrapper */
797
+ export interface PaginatedResponse<T> {
798
+ data: T[];
799
+ total: number;
800
+ page: number;
801
+ limit: number;
802
+ totalPages: number;
803
+ hasMore: boolean;
804
+ }
805
+
806
+ /** Date range filter */
807
+ export interface DateRange {
808
+ start: Timestamp;
809
+ end: Timestamp;
810
+ }
811
+
812
+ /** Contact filter options */
813
+ export interface ContactFilter {
814
+ search?: string;
815
+ status?: ContactStatus[];
816
+ tags?: string[];
817
+ source?: ContactSource[];
818
+ ownerId?: UUID;
819
+ companyId?: UUID;
820
+ createdAt?: DateRange;
821
+ updatedAt?: DateRange;
822
+ lastContactedAt?: DateRange;
823
+ nextFollowUpAt?: DateRange;
824
+ hasEmail?: boolean;
825
+ hasPhone?: boolean;
826
+ leadScoreMin?: number;
827
+ leadScoreMax?: number;
828
+ doNotContact?: boolean;
829
+ }
830
+
831
+ /** Deal filter options */
832
+ export interface DealFilter {
833
+ search?: string;
834
+ contactId?: UUID;
835
+ companyId?: UUID;
836
+ stage?: DealStage[];
837
+ priority?: DealPriority[];
838
+ ownerId?: UUID;
839
+ tags?: string[];
840
+ createdAt?: DateRange;
841
+ updatedAt?: DateRange;
842
+ expectedClose?: DateRange;
843
+ valueMin?: number;
844
+ valueMax?: number;
845
+ probabilityMin?: number;
846
+ probabilityMax?: number;
847
+ }
848
+
849
+ /** Activity filter options */
850
+ export interface ActivityFilter {
851
+ contactId?: UUID;
852
+ dealId?: UUID;
853
+ type?: ActivityType[];
854
+ createdBy?: UUID;
855
+ timestamp?: DateRange;
856
+ tags?: string[];
857
+ }
858
+
859
+ // ============================================================================
860
+ // Analytics Types
861
+ // ============================================================================
862
+
863
+ /** Metric aggregation period */
864
+ export type AggregationPeriod = 'day' | 'week' | 'month' | 'quarter' | 'year';
865
+
866
+ /** Metric data point */
867
+ export interface MetricDataPoint {
868
+ timestamp: Timestamp;
869
+ value: number;
870
+ label?: string;
871
+ }
872
+
873
+ /** Dashboard metric */
874
+ export interface DashboardMetric {
875
+ id: string;
876
+ name: string;
877
+ description?: string;
878
+ value: number;
879
+ previousValue?: number;
880
+ change?: number;
881
+ changePercent?: number;
882
+ trend?: 'up' | 'down' | 'stable';
883
+ dataPoints: MetricDataPoint[];
884
+ period: AggregationPeriod;
885
+ }
886
+
887
+ // ============================================================================
888
+ // Export Types
889
+ // ============================================================================
890
+
891
+ /** Export format options */
892
+ export type ExportFormat = 'csv' | 'xlsx' | 'json' | 'pdf';
893
+
894
+ /** Export job status */
895
+ export type ExportStatus = 'pending' | 'processing' | 'completed' | 'failed';
896
+
897
+ /** Export job */
898
+ export interface ExportJob {
899
+ id: UUID;
900
+ entityType: 'contacts' | 'deals' | 'activities' | 'notes';
901
+ format: ExportFormat;
902
+ status: ExportStatus;
903
+ filters?: Record<string, unknown>;
904
+ fields?: string[];
905
+ downloadUrl?: string;
906
+ error?: string;
907
+ createdAt: Timestamp;
908
+ completedAt?: Timestamp;
909
+ createdBy: UUID;
910
+ }
911
+
912
+ // ============================================================================
913
+ // Integration Types
914
+ // ============================================================================
915
+
916
+ /** Integration provider */
917
+ export type IntegrationProvider =
918
+ | 'google'
919
+ | 'microsoft'
920
+ | 'slack'
921
+ | 'mailchimp'
922
+ | 'hubspot'
923
+ | 'salesforce'
924
+ | 'zapier'
925
+ | 'custom';
926
+
927
+ /** Integration status */
928
+ export type IntegrationStatus = 'connected' | 'disconnected' | 'error' | 'pending';
929
+
930
+ /** External integration */
931
+ export interface Integration {
932
+ id: UUID;
933
+ provider: IntegrationProvider;
934
+ name: string;
935
+ status: IntegrationStatus;
936
+ configuredAt: Timestamp;
937
+ lastSyncAt?: Timestamp;
938
+ settings: Metadata;
939
+ error?: string;
940
+ }
941
+
942
+ // ============================================================================
943
+ // Telemetry Types
944
+ // ============================================================================
945
+
946
+ /** Telemetry event type */
947
+ export type TelemetryEventType =
948
+ | 'entity_created'
949
+ | 'entity_updated'
950
+ | 'entity_deleted'
951
+ | 'entity_viewed'
952
+ | 'search_performed'
953
+ | 'export_created'
954
+ | 'integration_sync'
955
+ | 'error_occurred';
956
+
957
+ /** Telemetry event */
958
+ export interface TelemetryEvent {
959
+ id: UUID;
960
+ type: TelemetryEventType;
961
+ entityType?: string;
962
+ entityId?: UUID;
963
+ userId?: UUID;
964
+ timestamp: Timestamp;
965
+ properties: Metadata;
966
+ duration?: number;
967
+ success: boolean;
968
+ errorMessage?: string;
969
+ }