@classytic/crm 0.5.0 → 0.5.1

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.
package/dist/index.d.ts CHANGED
@@ -1,382 +1,12 @@
1
- import * as mongoose1 from "mongoose";
1
+ import * as _$mongoose from "mongoose";
2
2
  import { Connection, Model, Schema, SchemaDefinitionProperty } from "mongoose";
3
3
  import { PaginationConfig, PluginType, Repository } from "@classytic/mongokit";
4
4
  import { DomainEvent, EventHandler, EventMeta, EventTransport } from "@classytic/primitives/events";
5
+ import * as _$_classytic_primitives_state_machine0 from "@classytic/primitives/state-machine";
5
6
  import { z } from "zod";
7
+ import { StatusChangeEntry, StatusHistory, appendStatus, lastTransitionTo, latestEntry, timeInStatus } from "@classytic/primitives/status-history";
6
8
  import { OperationContext } from "@classytic/primitives/context";
7
9
 
8
- //#region src/events/event-constants.d.ts
9
- /** PACKAGE_RULES rule 12: `package:resource.verb`. */
10
- declare const CRM_EVENTS: {
11
- readonly LEAD_CREATED: "crm:lead.created";
12
- readonly LEAD_STATUS_CHANGED: "crm:lead.status_changed";
13
- readonly LEAD_SCORED: "crm:lead.scored";
14
- readonly LEAD_CONVERTED: "crm:lead.converted";
15
- readonly LEAD_DISQUALIFIED: "crm:lead.disqualified";
16
- readonly ACCOUNT_CREATED: "crm:account.created";
17
- readonly ACCOUNT_UPDATED: "crm:account.updated";
18
- readonly CONTACT_CREATED: "crm:contact.created";
19
- readonly CONTACT_UPDATED: "crm:contact.updated";
20
- readonly OPPORTUNITY_CREATED: "crm:opportunity.created";
21
- readonly OPPORTUNITY_STAGE_ADVANCED: "crm:opportunity.stage_advanced";
22
- readonly OPPORTUNITY_STAGE_REGRESSED: "crm:opportunity.stage_regressed";
23
- readonly OPPORTUNITY_WON: "crm:opportunity.won";
24
- readonly OPPORTUNITY_LOST: "crm:opportunity.lost";
25
- readonly OPPORTUNITY_ABANDONED: "crm:opportunity.abandoned";
26
- readonly PIPELINE_CREATED: "crm:pipeline.created";
27
- readonly PIPELINE_ARCHIVED: "crm:pipeline.archived";
28
- readonly ACTIVITY_PLANNED: "crm:activity.planned";
29
- readonly ACTIVITY_COMPLETED: "crm:activity.completed";
30
- readonly ACTIVITY_CANCELLED: "crm:activity.cancelled";
31
- readonly NOTE_ADDED: "crm:note.added";
32
- readonly CAMPAIGN_CREATED: "crm:campaign.created";
33
- readonly CAMPAIGN_ACTIVATED: "crm:campaign.activated";
34
- readonly CAMPAIGN_PAUSED: "crm:campaign.paused";
35
- readonly CAMPAIGN_RESUMED: "crm:campaign.resumed";
36
- readonly CAMPAIGN_COMPLETED: "crm:campaign.completed";
37
- readonly CAMPAIGN_ARCHIVED: "crm:campaign.archived";
38
- readonly SUBSCRIPTION_CREATED: "crm:subscription.created";
39
- readonly SUBSCRIPTION_CONFIRMED: "crm:subscription.confirmed";
40
- readonly SUBSCRIPTION_UNSUBSCRIBED: "crm:subscription.unsubscribed";
41
- readonly SUBSCRIPTION_BOUNCED: "crm:subscription.bounced";
42
- readonly SUBSCRIPTION_COMPLAINED: "crm:subscription.complained";
43
- readonly EMAIL_EVENT_OPENED: "crm:email_event.opened";
44
- readonly EMAIL_EVENT_CLICKED: "crm:email_event.clicked";
45
- readonly EMAIL_EVENT_BOUNCED: "crm:email_event.bounced";
46
- readonly EMAIL_EVENT_COMPLAINED: "crm:email_event.complained";
47
- readonly EMAIL_EVENT_UNSUBSCRIBED: "crm:email_event.unsubscribed";
48
- readonly LEAD_ENRICHED: "crm:lead.enriched";
49
- readonly LEAD_ASSIGNED: "crm:lead.assigned";
50
- readonly CONTACT_ENRICHED: "crm:contact.enriched";
51
- readonly CONTACT_ASSIGNED: "crm:contact.assigned";
52
- readonly CONTACT_MERGED: "crm:contact.merged";
53
- readonly ACCOUNT_ENRICHED: "crm:account.enriched";
54
- readonly ACCOUNT_ASSIGNED: "crm:account.assigned";
55
- readonly ACCOUNT_MERGED: "crm:account.merged";
56
- readonly OPPORTUNITY_ASSIGNED: "crm:opportunity.assigned";
57
- readonly OPPORTUNITY_AMOUNT_CHANGED: "crm:opportunity.amount_changed";
58
- readonly OPPORTUNITY_EXTENDED: "crm:opportunity.extended";
59
- readonly ACTIVITY_RESCHEDULED: "crm:activity.rescheduled";
60
- readonly ACTIVITY_OUTCOME_RECORDED: "crm:activity.outcome_recorded";
61
- readonly CONVERSATION_CREATED: "crm:conversation.created";
62
- readonly CONVERSATION_ASSIGNED: "crm:conversation.assigned";
63
- readonly CONVERSATION_RESOLVED: "crm:conversation.resolved";
64
- readonly CONVERSATION_REOPENED: "crm:conversation.reopened";
65
- readonly MESSAGE_RECEIVED: "crm:message.received";
66
- readonly MESSAGE_SENT: "crm:message.sent";
67
- };
68
- type CrmEventName = (typeof CRM_EVENTS)[keyof typeof CRM_EVENTS];
69
- //#endregion
70
- //#region src/events/event-catalog.d.ts
71
-
72
- /** JSON-Schema object produced by `z.toJSONSchema` — what arc's registry consumes. */
73
- type CrmEventSchema = Record<string, unknown>;
74
- /** Structurally identical to arc's `EventDefinitionOutput` — do NOT import arc. */
75
- interface CrmEventDefinition<TSchema extends z.ZodType = z.ZodType> {
76
- name: CrmEventName;
77
- version: number;
78
- description: string;
79
- zodSchema: TSchema;
80
- schema: CrmEventSchema;
81
- create(payload: z.infer<TSchema>, meta?: Partial<EventMeta>): DomainEvent<z.infer<TSchema>>;
82
- }
83
- declare const LeadCreated: CrmEventDefinition<z.ZodObject<{
84
- leadId: z.ZodString;
85
- email: z.ZodOptional<z.ZodString>;
86
- score: z.ZodNumber;
87
- }, z.core.$strip>>;
88
- declare const LeadStatusChanged: CrmEventDefinition<z.ZodObject<{
89
- leadId: z.ZodString;
90
- from: z.ZodString;
91
- to: z.ZodString;
92
- }, z.core.$strip>>;
93
- declare const LeadScored: CrmEventDefinition<z.ZodObject<{
94
- leadId: z.ZodString;
95
- score: z.ZodNumber;
96
- }, z.core.$strip>>;
97
- declare const LeadConverted: CrmEventDefinition<z.ZodObject<{
98
- leadId: z.ZodString;
99
- contactId: z.ZodString;
100
- accountId: z.ZodOptional<z.ZodString>;
101
- opportunityId: z.ZodString;
102
- }, z.core.$strip>>;
103
- declare const LeadDisqualified: CrmEventDefinition<z.ZodObject<{
104
- leadId: z.ZodString;
105
- reason: z.ZodString;
106
- }, z.core.$strip>>;
107
- declare const LeadEnriched: CrmEventDefinition<z.ZodObject<{
108
- leadId: z.ZodString;
109
- fields: z.ZodArray<z.ZodString>;
110
- provider: z.ZodOptional<z.ZodString>;
111
- }, z.core.$strip>>;
112
- declare const LeadAssigned: CrmEventDefinition<z.ZodObject<{
113
- leadId: z.ZodString;
114
- ownerId: z.ZodString;
115
- previousOwnerId: z.ZodOptional<z.ZodString>;
116
- }, z.core.$strip>>;
117
- declare const AccountCreated: CrmEventDefinition<z.ZodObject<{
118
- accountId: z.ZodString;
119
- name: z.ZodString;
120
- }, z.core.$strip>>;
121
- declare const AccountUpdated: CrmEventDefinition<z.ZodObject<{
122
- accountId: z.ZodString;
123
- }, z.core.$strip>>;
124
- declare const AccountEnriched: CrmEventDefinition<z.ZodObject<{
125
- accountId: z.ZodString;
126
- fields: z.ZodArray<z.ZodString>;
127
- provider: z.ZodOptional<z.ZodString>;
128
- }, z.core.$strip>>;
129
- declare const AccountAssigned: CrmEventDefinition<z.ZodObject<{
130
- accountId: z.ZodString;
131
- ownerId: z.ZodString;
132
- previousOwnerId: z.ZodOptional<z.ZodString>;
133
- }, z.core.$strip>>;
134
- declare const AccountMerged: CrmEventDefinition<z.ZodObject<{
135
- primaryId: z.ZodString;
136
- secondaryId: z.ZodString;
137
- strategy: z.ZodEnum<{
138
- preferPrimary: "preferPrimary";
139
- preferSecondary: "preferSecondary";
140
- }>;
141
- }, z.core.$strip>>;
142
- declare const ContactCreated: CrmEventDefinition<z.ZodObject<{
143
- contactId: z.ZodString;
144
- email: z.ZodOptional<z.ZodString>;
145
- }, z.core.$strip>>;
146
- declare const ContactUpdated: CrmEventDefinition<z.ZodObject<{
147
- contactId: z.ZodString;
148
- }, z.core.$strip>>;
149
- declare const ContactEnriched: CrmEventDefinition<z.ZodObject<{
150
- contactId: z.ZodString;
151
- fields: z.ZodArray<z.ZodString>;
152
- provider: z.ZodOptional<z.ZodString>;
153
- }, z.core.$strip>>;
154
- declare const ContactAssigned: CrmEventDefinition<z.ZodObject<{
155
- contactId: z.ZodString;
156
- ownerId: z.ZodString;
157
- previousOwnerId: z.ZodOptional<z.ZodString>;
158
- }, z.core.$strip>>;
159
- declare const ContactMerged: CrmEventDefinition<z.ZodObject<{
160
- primaryId: z.ZodString;
161
- secondaryId: z.ZodString;
162
- strategy: z.ZodEnum<{
163
- preferPrimary: "preferPrimary";
164
- preferSecondary: "preferSecondary";
165
- }>;
166
- }, z.core.$strip>>;
167
- declare const OpportunityCreated: CrmEventDefinition<z.ZodObject<{
168
- opportunityId: z.ZodString;
169
- pipelineId: z.ZodString;
170
- stageId: z.ZodString;
171
- }, z.core.$strip>>;
172
- declare const OpportunityStageAdvanced: CrmEventDefinition<z.ZodObject<{
173
- opportunityId: z.ZodString;
174
- from: z.ZodObject<{
175
- stageId: z.ZodString;
176
- sequence: z.ZodNumber;
177
- }, z.core.$strip>;
178
- to: z.ZodObject<{
179
- stageId: z.ZodString;
180
- sequence: z.ZodNumber;
181
- }, z.core.$strip>;
182
- }, z.core.$strip>>;
183
- declare const OpportunityStageRegressed: CrmEventDefinition<z.ZodObject<{
184
- opportunityId: z.ZodString;
185
- from: z.ZodObject<{
186
- stageId: z.ZodString;
187
- sequence: z.ZodNumber;
188
- }, z.core.$strip>;
189
- to: z.ZodObject<{
190
- stageId: z.ZodString;
191
- sequence: z.ZodNumber;
192
- }, z.core.$strip>;
193
- }, z.core.$strip>>;
194
- declare const OpportunityWon: CrmEventDefinition<z.ZodObject<{
195
- opportunityId: z.ZodString;
196
- amount: z.ZodOptional<z.ZodNumber>;
197
- }, z.core.$strip>>;
198
- declare const OpportunityLost: CrmEventDefinition<z.ZodObject<{
199
- opportunityId: z.ZodString;
200
- lostReasonId: z.ZodOptional<z.ZodString>;
201
- }, z.core.$strip>>;
202
- declare const OpportunityAbandoned: CrmEventDefinition<z.ZodObject<{
203
- opportunityId: z.ZodString;
204
- }, z.core.$strip>>;
205
- declare const OpportunityAssigned: CrmEventDefinition<z.ZodObject<{
206
- opportunityId: z.ZodString;
207
- ownerId: z.ZodString;
208
- previousOwnerId: z.ZodOptional<z.ZodString>;
209
- }, z.core.$strip>>;
210
- declare const OpportunityAmountChanged: CrmEventDefinition<z.ZodObject<{
211
- opportunityId: z.ZodString;
212
- amount: z.ZodNumber;
213
- previousAmount: z.ZodOptional<z.ZodNumber>;
214
- reason: z.ZodOptional<z.ZodString>;
215
- by: z.ZodOptional<z.ZodString>;
216
- }, z.core.$strip>>;
217
- declare const OpportunityExtended: CrmEventDefinition<z.ZodObject<{
218
- opportunityId: z.ZodString;
219
- expectedCloseAt: z.ZodISODateTime;
220
- previousExpectedCloseAt: z.ZodOptional<z.ZodISODateTime>;
221
- reason: z.ZodOptional<z.ZodString>;
222
- by: z.ZodOptional<z.ZodString>;
223
- }, z.core.$strip>>;
224
- declare const PipelineCreated: CrmEventDefinition<z.ZodObject<{
225
- pipelineId: z.ZodString;
226
- }, z.core.$strip>>;
227
- declare const PipelineArchived: CrmEventDefinition<z.ZodObject<{
228
- pipelineId: z.ZodString;
229
- }, z.core.$strip>>;
230
- declare const ActivityPlanned: CrmEventDefinition<z.ZodObject<{
231
- activityId: z.ZodString;
232
- type: z.ZodString;
233
- subjectKind: z.ZodString;
234
- subjectId: z.ZodString;
235
- }, z.core.$strip>>;
236
- declare const ActivityCompleted: CrmEventDefinition<z.ZodObject<{
237
- activityId: z.ZodString;
238
- completedAt: z.ZodISODateTime;
239
- }, z.core.$strip>>;
240
- declare const ActivityCancelled: CrmEventDefinition<z.ZodObject<{
241
- activityId: z.ZodString;
242
- reason: z.ZodOptional<z.ZodString>;
243
- }, z.core.$strip>>;
244
- declare const ActivityRescheduled: CrmEventDefinition<z.ZodObject<{
245
- activityId: z.ZodString;
246
- dueDate: z.ZodISODateTime;
247
- previousDueDate: z.ZodOptional<z.ZodISODateTime>;
248
- reason: z.ZodOptional<z.ZodString>;
249
- by: z.ZodOptional<z.ZodString>;
250
- }, z.core.$strip>>;
251
- declare const ActivityOutcomeRecorded: CrmEventDefinition<z.ZodObject<{
252
- activityId: z.ZodString;
253
- outcome: z.ZodRecord<z.ZodString, z.ZodUnknown>;
254
- }, z.core.$strip>>;
255
- declare const NoteAdded: CrmEventDefinition<z.ZodObject<{
256
- noteId: z.ZodString;
257
- subjectKind: z.ZodString;
258
- subjectId: z.ZodString;
259
- }, z.core.$strip>>;
260
- declare const CampaignCreated: CrmEventDefinition<z.ZodObject<{
261
- campaignId: z.ZodString;
262
- name: z.ZodString;
263
- }, z.core.$strip>>;
264
- declare const CampaignActivated: CrmEventDefinition<z.ZodObject<{
265
- campaignId: z.ZodString;
266
- }, z.core.$strip>>;
267
- declare const CampaignPaused: CrmEventDefinition<z.ZodObject<{
268
- campaignId: z.ZodString;
269
- reason: z.ZodOptional<z.ZodString>;
270
- }, z.core.$strip>>;
271
- declare const CampaignResumed: CrmEventDefinition<z.ZodObject<{
272
- campaignId: z.ZodString;
273
- }, z.core.$strip>>;
274
- declare const CampaignCompleted: CrmEventDefinition<z.ZodObject<{
275
- campaignId: z.ZodString;
276
- actualRevenueAmount: z.ZodOptional<z.ZodNumber>;
277
- }, z.core.$strip>>;
278
- declare const CampaignArchived: CrmEventDefinition<z.ZodObject<{
279
- campaignId: z.ZodString;
280
- }, z.core.$strip>>;
281
- declare const SubscriptionCreated: CrmEventDefinition<z.ZodObject<{
282
- subscriptionId: z.ZodString;
283
- contactId: z.ZodString;
284
- campaignId: z.ZodString;
285
- requiresConfirmation: z.ZodBoolean;
286
- }, z.core.$strip>>;
287
- declare const SubscriptionConfirmed: CrmEventDefinition<z.ZodObject<{
288
- subscriptionId: z.ZodString;
289
- contactId: z.ZodString;
290
- campaignId: z.ZodString;
291
- confirmedAt: z.ZodISODateTime;
292
- }, z.core.$strip>>;
293
- declare const SubscriptionUnsubscribed: CrmEventDefinition<z.ZodObject<{
294
- subscriptionId: z.ZodString;
295
- contactId: z.ZodString;
296
- campaignId: z.ZodString;
297
- reason: z.ZodOptional<z.ZodString>;
298
- }, z.core.$strip>>;
299
- declare const SubscriptionBounced: CrmEventDefinition<z.ZodObject<{
300
- subscriptionId: z.ZodString;
301
- contactId: z.ZodString;
302
- campaignId: z.ZodString;
303
- reason: z.ZodOptional<z.ZodString>;
304
- }, z.core.$strip>>;
305
- declare const SubscriptionComplained: CrmEventDefinition<z.ZodObject<{
306
- subscriptionId: z.ZodString;
307
- contactId: z.ZodString;
308
- campaignId: z.ZodString;
309
- }, z.core.$strip>>;
310
- declare const EmailEventOpened: CrmEventDefinition<z.ZodObject<{
311
- eventId: z.ZodString;
312
- kind: z.ZodString;
313
- subjectKind: z.ZodString;
314
- subjectId: z.ZodString;
315
- campaignId: z.ZodOptional<z.ZodString>;
316
- }, z.core.$strip>>;
317
- declare const EmailEventClicked: CrmEventDefinition<z.ZodObject<{
318
- eventId: z.ZodString;
319
- kind: z.ZodString;
320
- subjectKind: z.ZodString;
321
- subjectId: z.ZodString;
322
- campaignId: z.ZodOptional<z.ZodString>;
323
- }, z.core.$strip>>;
324
- declare const EmailEventBounced: CrmEventDefinition<z.ZodObject<{
325
- eventId: z.ZodString;
326
- kind: z.ZodString;
327
- subjectKind: z.ZodString;
328
- subjectId: z.ZodString;
329
- campaignId: z.ZodOptional<z.ZodString>;
330
- }, z.core.$strip>>;
331
- declare const EmailEventComplained: CrmEventDefinition<z.ZodObject<{
332
- eventId: z.ZodString;
333
- kind: z.ZodString;
334
- subjectKind: z.ZodString;
335
- subjectId: z.ZodString;
336
- campaignId: z.ZodOptional<z.ZodString>;
337
- }, z.core.$strip>>;
338
- declare const EmailEventUnsubscribed: CrmEventDefinition<z.ZodObject<{
339
- eventId: z.ZodString;
340
- kind: z.ZodString;
341
- subjectKind: z.ZodString;
342
- subjectId: z.ZodString;
343
- campaignId: z.ZodOptional<z.ZodString>;
344
- }, z.core.$strip>>;
345
- declare const ConversationCreated: CrmEventDefinition<z.ZodObject<{
346
- conversationId: z.ZodString;
347
- channel: z.ZodString;
348
- participantKind: z.ZodString;
349
- participantId: z.ZodString;
350
- }, z.core.$strip>>;
351
- declare const ConversationAssigned: CrmEventDefinition<z.ZodObject<{
352
- conversationId: z.ZodString;
353
- assigneeId: z.ZodString;
354
- previousAssigneeId: z.ZodOptional<z.ZodString>;
355
- }, z.core.$strip>>;
356
- declare const ConversationResolved: CrmEventDefinition<z.ZodObject<{
357
- conversationId: z.ZodString;
358
- status: z.ZodString;
359
- previousStatus: z.ZodString;
360
- }, z.core.$strip>>;
361
- declare const ConversationReopened: CrmEventDefinition<z.ZodObject<{
362
- conversationId: z.ZodString;
363
- status: z.ZodString;
364
- previousStatus: z.ZodString;
365
- }, z.core.$strip>>;
366
- declare const MessageReceived: CrmEventDefinition<z.ZodObject<{
367
- messageId: z.ZodString;
368
- conversationId: z.ZodString;
369
- direction: z.ZodString;
370
- externalMessageId: z.ZodOptional<z.ZodString>;
371
- }, z.core.$strip>>;
372
- declare const MessageSent: CrmEventDefinition<z.ZodObject<{
373
- messageId: z.ZodString;
374
- conversationId: z.ZodString;
375
- direction: z.ZodString;
376
- externalMessageId: z.ZodOptional<z.ZodString>;
377
- }, z.core.$strip>>;
378
- declare const crmEventDefinitions: ReadonlyArray<CrmEventDefinition>;
379
- //#endregion
380
10
  //#region src/models/tenant-field.d.ts
381
11
  type TenantFieldType = 'objectId' | 'string';
382
12
  interface SchemaBuildConfig {
@@ -392,7 +22,7 @@ declare function tenantFieldDef(config: SchemaBuildConfig): SchemaDefinitionProp
392
22
  //#region src/models/pipeline.schema.d.ts
393
23
  /** Mongoose document shape for a single embedded stage. */
394
24
  interface IStageDocument {
395
- _id: mongoose1.Types.ObjectId;
25
+ _id: _$mongoose.Types.ObjectId;
396
26
  name: string;
397
27
  /** Ascending order in the pipeline. Treated as identifier on `moveToStage`. */
398
28
  sequence: number;
@@ -403,8 +33,8 @@ interface IStageDocument {
403
33
  }
404
34
  /** Mongoose document shape for a Pipeline. */
405
35
  interface IPipelineDocument {
406
- _id: mongoose1.Types.ObjectId;
407
- organizationId: mongoose1.Types.ObjectId | string;
36
+ _id: _$mongoose.Types.ObjectId;
37
+ organizationId: _$mongoose.Types.ObjectId | string;
408
38
  name: string;
409
39
  /** Deprecates the pipeline — existing opps still move, no new ones created. */
410
40
  isArchived: boolean;
@@ -443,8 +73,8 @@ interface ILeadStatusEntry {
443
73
  note?: string;
444
74
  }
445
75
  interface ILeadDocument {
446
- _id: mongoose1.Types.ObjectId;
447
- organizationId: mongoose1.Types.ObjectId | string;
76
+ _id: _$mongoose.Types.ObjectId;
77
+ organizationId: _$mongoose.Types.ObjectId | string;
448
78
  fullName: string;
449
79
  firstName?: string;
450
80
  lastName?: string;
@@ -459,9 +89,9 @@ interface ILeadDocument {
459
89
  statusHistory: ILeadStatusEntry[];
460
90
  ownerId?: string;
461
91
  tags: string[];
462
- convertedContactId?: mongoose1.Types.ObjectId | string;
463
- convertedAccountId?: mongoose1.Types.ObjectId | string;
464
- convertedOpportunityId?: mongoose1.Types.ObjectId | string;
92
+ convertedContactId?: _$mongoose.Types.ObjectId | string;
93
+ convertedAccountId?: _$mongoose.Types.ObjectId | string;
94
+ convertedOpportunityId?: _$mongoose.Types.ObjectId | string;
465
95
  convertedAt?: Date;
466
96
  disqualifyReason?: string;
467
97
  metadata?: Record<string, unknown>;
@@ -493,12 +123,12 @@ interface IOpportunityStatusEntry {
493
123
  note?: string;
494
124
  }
495
125
  interface IOpportunityDocument {
496
- _id: mongoose1.Types.ObjectId;
497
- organizationId: mongoose1.Types.ObjectId | string;
126
+ _id: _$mongoose.Types.ObjectId;
127
+ organizationId: _$mongoose.Types.ObjectId | string;
498
128
  name: string;
499
- accountId?: mongoose1.Types.ObjectId | string;
500
- primaryContactId?: mongoose1.Types.ObjectId | string;
501
- pipelineId: mongoose1.Types.ObjectId | string;
129
+ accountId?: _$mongoose.Types.ObjectId | string;
130
+ primaryContactId?: _$mongoose.Types.ObjectId | string;
131
+ pipelineId: _$mongoose.Types.ObjectId | string;
502
132
  stageId: string;
503
133
  status: OpportunityStatus;
504
134
  statusHistory: IOpportunityStatusEntry[];
@@ -507,9 +137,9 @@ interface IOpportunityDocument {
507
137
  probability: number;
508
138
  expectedCloseAt?: Date;
509
139
  closedAt?: Date;
510
- lostReasonId?: mongoose1.Types.ObjectId | string;
140
+ lostReasonId?: _$mongoose.Types.ObjectId | string;
511
141
  ownerId?: string;
512
- sourceLeadId?: mongoose1.Types.ObjectId | string;
142
+ sourceLeadId?: _$mongoose.Types.ObjectId | string;
513
143
  tags: string[];
514
144
  metadata?: Record<string, unknown>;
515
145
  createdAt: Date;
@@ -538,12 +168,12 @@ interface IContactInfoEmbedded {
538
168
  instagram?: string;
539
169
  }
540
170
  interface IContactDocument {
541
- _id: mongoose1.Types.ObjectId;
542
- organizationId: mongoose1.Types.ObjectId | string;
171
+ _id: _$mongoose.Types.ObjectId;
172
+ organizationId: _$mongoose.Types.ObjectId | string;
543
173
  name: IContactName;
544
174
  contact: IContactInfoEmbedded;
545
175
  jobTitle?: string;
546
- accountId?: mongoose1.Types.ObjectId | string;
176
+ accountId?: _$mongoose.Types.ObjectId | string;
547
177
  ownerId?: string;
548
178
  tags: string[];
549
179
  metadata?: Record<string, unknown>;
@@ -555,8 +185,8 @@ declare function createContactModel(connection: Connection, config: SchemaBuildC
555
185
  //#endregion
556
186
  //#region src/models/account.schema.d.ts
557
187
  interface IAccountDocument {
558
- _id: mongoose1.Types.ObjectId;
559
- organizationId: mongoose1.Types.ObjectId | string;
188
+ _id: _$mongoose.Types.ObjectId;
189
+ organizationId: _$mongoose.Types.ObjectId | string;
560
190
  name: string;
561
191
  domain?: string;
562
192
  industry?: string;
@@ -595,8 +225,8 @@ interface ICampaignStatusEntry {
595
225
  note?: string;
596
226
  }
597
227
  interface ICampaignDocument {
598
- _id: mongoose1.Types.ObjectId;
599
- organizationId: mongoose1.Types.ObjectId | string;
228
+ _id: _$mongoose.Types.ObjectId;
229
+ organizationId: _$mongoose.Types.ObjectId | string;
600
230
  name: string;
601
231
  description?: string;
602
232
  status: CampaignStatus;
@@ -646,10 +276,10 @@ interface ISubscriptionStatusEntry {
646
276
  note?: string;
647
277
  }
648
278
  interface ISubscriptionDocument {
649
- _id: mongoose1.Types.ObjectId;
650
- organizationId: mongoose1.Types.ObjectId | string;
651
- contactId: mongoose1.Types.ObjectId | string;
652
- campaignId: mongoose1.Types.ObjectId | string;
279
+ _id: _$mongoose.Types.ObjectId;
280
+ organizationId: _$mongoose.Types.ObjectId | string;
281
+ contactId: _$mongoose.Types.ObjectId | string;
282
+ campaignId: _$mongoose.Types.ObjectId | string;
653
283
  status: SubscriptionStatus;
654
284
  statusHistory: ISubscriptionStatusEntry[];
655
285
  source?: string;
@@ -694,12 +324,12 @@ type SubjectKind = (typeof SUBJECT_KINDS)[number];
694
324
  //#endregion
695
325
  //#region src/models/activity.schema.d.ts
696
326
  interface IActivityDocument {
697
- _id: mongoose1.Types.ObjectId;
698
- organizationId: mongoose1.Types.ObjectId | string;
327
+ _id: _$mongoose.Types.ObjectId;
328
+ organizationId: _$mongoose.Types.ObjectId | string;
699
329
  type: ActivityType;
700
330
  status: ActivityStatus;
701
331
  subjectKind: SubjectKind;
702
- subjectId: mongoose1.Types.ObjectId | string;
332
+ subjectId: _$mongoose.Types.ObjectId | string;
703
333
  title: string;
704
334
  description?: string;
705
335
  ownerId?: string;
@@ -716,10 +346,10 @@ declare function createActivityModel(connection: Connection, config: SchemaBuild
716
346
  //#endregion
717
347
  //#region src/models/note.schema.d.ts
718
348
  interface INoteDocument {
719
- _id: mongoose1.Types.ObjectId;
720
- organizationId: mongoose1.Types.ObjectId | string;
349
+ _id: _$mongoose.Types.ObjectId;
350
+ organizationId: _$mongoose.Types.ObjectId | string;
721
351
  subjectKind: SubjectKind;
722
- subjectId: mongoose1.Types.ObjectId | string;
352
+ subjectId: _$mongoose.Types.ObjectId | string;
723
353
  body: string;
724
354
  authorId?: string;
725
355
  pinned: boolean;
@@ -732,8 +362,8 @@ declare function createNoteModel(connection: Connection, config: SchemaBuildConf
732
362
  //#endregion
733
363
  //#region src/models/loss-reason.schema.d.ts
734
364
  interface ILossReasonDocument {
735
- _id: mongoose1.Types.ObjectId;
736
- organizationId: mongoose1.Types.ObjectId | string;
365
+ _id: _$mongoose.Types.ObjectId;
366
+ organizationId: _$mongoose.Types.ObjectId | string;
737
367
  name: string;
738
368
  description?: string;
739
369
  isActive: boolean;
@@ -775,18 +405,17 @@ declare function createLossReasonModel(connection: Connection, config: SchemaBui
775
405
  */
776
406
  declare const EMAIL_EVENT_KINDS: readonly ["open", "click", "bounce", "complaint", "unsubscribe"];
777
407
  type EmailEventKind = (typeof EMAIL_EVENT_KINDS)[number];
778
- /** Engagement (positive signal). */
779
408
  //#endregion
780
409
  //#region src/models/email-event.schema.d.ts
781
410
  declare const EMAIL_EVENT_SUBJECT_KINDS: readonly ["contact", "subscription"];
782
411
  type EmailEventSubjectKind = (typeof EMAIL_EVENT_SUBJECT_KINDS)[number];
783
412
  interface IEmailEventDocument {
784
- _id: mongoose1.Types.ObjectId;
785
- organizationId: mongoose1.Types.ObjectId | string;
413
+ _id: _$mongoose.Types.ObjectId;
414
+ organizationId: _$mongoose.Types.ObjectId | string;
786
415
  kind: EmailEventKind;
787
416
  subjectKind: EmailEventSubjectKind;
788
- subjectId: mongoose1.Types.ObjectId | string;
789
- campaignId?: mongoose1.Types.ObjectId | string;
417
+ subjectId: _$mongoose.Types.ObjectId | string;
418
+ campaignId?: _$mongoose.Types.ObjectId | string;
790
419
  messageId?: string;
791
420
  url?: string;
792
421
  userAgent?: string;
@@ -820,11 +449,11 @@ type MessageDeliveryStatus = (typeof MESSAGE_DELIVERY_STATUSES)[number];
820
449
  //#endregion
821
450
  //#region src/models/conversation.schema.d.ts
822
451
  interface IConversationDocument {
823
- _id: mongoose1.Types.ObjectId;
824
- organizationId: mongoose1.Types.ObjectId | string;
452
+ _id: _$mongoose.Types.ObjectId;
453
+ organizationId: _$mongoose.Types.ObjectId | string;
825
454
  channel: ConversationChannel;
826
455
  participantKind: ConversationParticipantKind;
827
- participantId: mongoose1.Types.ObjectId | string;
456
+ participantId: _$mongoose.Types.ObjectId | string;
828
457
  /** Channel-side identifier (e.g. WhatsApp wa_id, Telegram chat id). */
829
458
  channelUserId?: string;
830
459
  status: ConversationStatus;
@@ -851,9 +480,9 @@ interface IMessageAttachment {
851
480
  mimeType?: string;
852
481
  }
853
482
  interface IMessageDocument {
854
- _id: mongoose1.Types.ObjectId;
855
- organizationId: mongoose1.Types.ObjectId | string;
856
- conversationId: mongoose1.Types.ObjectId | string;
483
+ _id: _$mongoose.Types.ObjectId;
484
+ organizationId: _$mongoose.Types.ObjectId | string;
485
+ conversationId: _$mongoose.Types.ObjectId | string;
857
486
  direction: MessageDirection;
858
487
  body: string;
859
488
  attachments: IMessageAttachment[];
@@ -901,587 +530,1698 @@ interface CreateModelsOptions extends SchemaBuildConfig {
901
530
  /** Mongoose auto-index builds. Default `true` (dev); `false` in prod. */
902
531
  autoIndex?: boolean;
903
532
  }
904
- declare function createCrmModels(connection: Connection, config: CreateModelsOptions): CrmModels;
533
+ declare function createCrmModels(connection: Connection, config: CreateModelsOptions): CrmModels;
534
+ //#endregion
535
+ //#region src/repositories/pipeline.repository.d.ts
536
+ interface PipelineRepositoryDeps {
537
+ events: EventTransport;
538
+ }
539
+ declare class PipelineRepository extends Repository<IPipelineDocument> {
540
+ private readonly events;
541
+ constructor(model: Model<IPipelineDocument>, plugins: PluginType[], deps: PipelineRepositoryDeps, pagination?: PaginationConfig);
542
+ /**
543
+ * Read a single embedded stage. Used by Opportunity create / move to
544
+ * validate stage membership + pick up `defaultProbability`.
545
+ */
546
+ getStage(pipelineId: string, stageId: string, ctx?: CrmContext): Promise<IStageDocument>;
547
+ /** First stage by `sequence` ascending. */
548
+ getFirstStage(pipelineId: string, ctx?: CrmContext): Promise<IStageDocument>;
549
+ /** Stage immediately after the given one. `null` at terminal stage. */
550
+ getNextStage(pipelineId: string, stageId: string, ctx?: CrmContext): Promise<IStageDocument | null>;
551
+ /** Soft-deprecate — existing opps still move; no new ones can be created. */
552
+ archive(id: string, ctx?: CrmContext): Promise<IPipelineDocument>;
553
+ }
554
+ //#endregion
555
+ //#region src/shared/calculators/scoring.d.ts
556
+ /** Minimal Lead shape the scorer reads. */
557
+ type LeadInput = Pick<ILeadDocument, 'email' | 'phone' | 'companyName' | 'tags' | 'jobTitle'>;
558
+ type LeadScorer = (lead: LeadInput) => number;
559
+ /**
560
+ * Reference implementation. Intentionally simple — hosts read it and
561
+ * replace it.
562
+ *
563
+ * +20 if email is present
564
+ * +20 if phone is present
565
+ * +20 if companyName is present
566
+ * +10 per populated tag up to 40
567
+ * +10 if jobTitle hints senior (director / manager / head / chief / vp / founder)
568
+ */
569
+ declare function defaultLeadScorer(lead: LeadInput): number;
570
+ /** Compose multiple small rules into one scorer. */
571
+ declare function composeScorers(...rules: readonly LeadScorer[]): LeadScorer;
572
+ //#endregion
573
+ //#region src/repositories/lead.repository.d.ts
574
+ interface LeadRepositoryDeps {
575
+ events: EventTransport;
576
+ /** Override the default lead scorer. */
577
+ scorer?: LeadScorer;
578
+ /** Reject `create()` when an email already exists in-tenant (default true). */
579
+ rejectDuplicates?: boolean;
580
+ }
581
+ type TransitionExtras = {
582
+ by?: string;
583
+ note?: string;
584
+ patch?: Partial<ILeadDocument>;
585
+ };
586
+ declare class LeadRepository extends Repository<ILeadDocument> {
587
+ private readonly events;
588
+ private readonly scorer;
589
+ private readonly rejectDuplicates;
590
+ constructor(model: Model<ILeadDocument>, plugins: PluginType[], deps: LeadRepositoryDeps, pagination?: PaginationConfig);
591
+ /**
592
+ * Create a Lead. Auto-scores on insert so hosts can route immediately.
593
+ * Rejects duplicate emails inside the same tenant unless
594
+ * `rejectDuplicates: false` was set at engine boot.
595
+ */
596
+ createLead(input: Partial<ILeadDocument>, ctx?: CrmContext): Promise<ILeadDocument>;
597
+ markContacted(id: string, extras?: TransitionExtras, ctx?: CrmContext): Promise<ILeadDocument>;
598
+ qualify(id: string, extras?: TransitionExtras, ctx?: CrmContext): Promise<ILeadDocument>;
599
+ disqualify(id: string, reason: string, extras?: Omit<TransitionExtras, 'patch'>, ctx?: CrmContext): Promise<ILeadDocument>;
600
+ nurture(id: string, extras?: TransitionExtras, ctx?: CrmContext): Promise<ILeadDocument>;
601
+ /**
602
+ * Merge enrichment payload (3rd-party provider response or manual
603
+ * patch) into the lead doc, then re-score. Emits `crm:lead.enriched`
604
+ * with the field set written so subscribers can fan out (e.g. push a
605
+ * `recompute_segment` job) without re-reading the doc.
606
+ *
607
+ * The `provider` tag flows into the event for attribution; the package
608
+ * is provider-agnostic so the actual enrichment call lives at the host.
609
+ */
610
+ enrich(id: string, patch: Partial<ILeadDocument>, extras?: {
611
+ provider?: string;
612
+ }, ctx?: CrmContext): Promise<ILeadDocument>;
613
+ /**
614
+ * Assign / re-assign the lead's owner. Emits `crm:lead.assigned` with
615
+ * the previous owner so audit consumers can compute hand-off chains.
616
+ */
617
+ assign(id: string, ownerId: string, ctx?: CrmContext): Promise<ILeadDocument>;
618
+ /**
619
+ * Recompute + persist the lead's score. Called from `createLead`
620
+ * automatically; hosts also call this after enrichment writes.
621
+ */
622
+ recomputeScore(id: string, ctx?: CrmContext): Promise<ILeadDocument>;
623
+ private _transition;
624
+ /**
625
+ * Count leads created on or after `since`. Used by dashboard KPI tiles.
626
+ * Goes through the inherited tenant-scoped `count()` — the plugin
627
+ * injects `organizationId` (never a manual `if (ctx)` filter, which
628
+ * silently reads ALL tenants when ctx is absent).
629
+ */
630
+ countCreatedSince(since: Date, ctx?: CrmContext): Promise<number>;
631
+ /** Latest `limit` leads — lightweight projection for the activity feed. */
632
+ findRecentForFeed(limit: number, ctx?: CrmContext): Promise<ILeadDocument[]>;
633
+ }
634
+ //#endregion
635
+ //#region src/repositories/opportunity.repository.d.ts
636
+ interface OpportunityRepositoryDeps {
637
+ events: EventTransport;
638
+ /** Cross-repo reference: read embedded stages from Pipeline. */
639
+ pipelines: PipelineRepository;
640
+ }
641
+ interface OpenOpportunityInput {
642
+ name: string;
643
+ pipelineId: string;
644
+ /** When omitted, opp enters the pipeline's first stage. */
645
+ stageId?: string;
646
+ accountId?: string;
647
+ primaryContactId?: string;
648
+ sourceLeadId?: string;
649
+ amount?: number;
650
+ currency?: string;
651
+ /** Override the stage's `defaultProbability`. */
652
+ probability?: number;
653
+ expectedCloseAt?: Date;
654
+ ownerId?: string;
655
+ tags?: readonly string[];
656
+ metadata?: Record<string, unknown>;
657
+ }
658
+ interface MoveStageInput {
659
+ stageId: string;
660
+ by?: string;
661
+ note?: string;
662
+ /** Override the target stage's `defaultProbability`. */
663
+ probability?: number;
664
+ }
665
+ interface CloseInput {
666
+ by?: string;
667
+ note?: string;
668
+ closedAt?: Date;
669
+ amount?: number;
670
+ lostReasonId?: string;
671
+ }
672
+ declare class OpportunityRepository extends Repository<IOpportunityDocument> {
673
+ private readonly events;
674
+ private readonly pipelines;
675
+ constructor(model: Model<IOpportunityDocument>, plugins: PluginType[], deps: OpportunityRepositoryDeps, pagination?: PaginationConfig);
676
+ openOpportunity(input: OpenOpportunityInput, ctx?: CrmContext): Promise<IOpportunityDocument>;
677
+ /**
678
+ * Atomic stage move. CAS on `(status='open', stageId=current)` so two
679
+ * concurrent moves can't both win. Emits `stage_advanced` or
680
+ * `stage_regressed` based on `sequence` ordering of the embedded stages.
681
+ */
682
+ moveToStage(id: string, input: MoveStageInput, ctx?: CrmContext): Promise<IOpportunityDocument>;
683
+ win(id: string, input?: CloseInput, ctx?: CrmContext): Promise<IOpportunityDocument>;
684
+ lose(id: string, input?: CloseInput, ctx?: CrmContext): Promise<IOpportunityDocument>;
685
+ /**
686
+ * Re-assign opportunity owner. Mutates `ownerId` only; no status
687
+ * transition. Emits `crm:opportunity.assigned` with the previous owner.
688
+ */
689
+ assign(id: string, ownerId: string, ctx?: CrmContext): Promise<IOpportunityDocument>;
690
+ /**
691
+ * Adjust the deal amount on an open opportunity. Rejected after
692
+ * win/lose/abandon — closed-deal amounts are immutable history.
693
+ * Emits `crm:opportunity.amount_changed` with the delta so forecast
694
+ * subscribers can re-bucket.
695
+ */
696
+ updateAmount(id: string, amount: number, extras?: {
697
+ reason?: string;
698
+ by?: string;
699
+ }, ctx?: CrmContext): Promise<IOpportunityDocument>;
700
+ /**
701
+ * Push `expectedCloseAt` further out. Only valid on open opps —
702
+ * extending a closed deal is meaningless. The new date must be later
703
+ * than the current one; pulling the date in is silently accepted
704
+ * (no event is meaningful there).
705
+ */
706
+ extendCloseDate(id: string, newDate: Date, extras?: {
707
+ reason?: string;
708
+ by?: string;
709
+ }, ctx?: CrmContext): Promise<IOpportunityDocument>;
710
+ abandon(id: string, by?: string, note?: string, ctx?: CrmContext): Promise<IOpportunityDocument>;
711
+ private _closeStatus;
712
+ /** Count opportunities with status `open`. Used by dashboard KPI tiles. */
713
+ countOpen(ctx?: CrmContext): Promise<number>;
714
+ /**
715
+ * Sum `amount` on won opportunities updated within `since`.
716
+ * Goes through the tenant-scoped `findAll()` — the multiTenant plugin
717
+ * injects `organizationId`, so a missing ctx can't leak other tenants'
718
+ * revenue (a manual `if (ctx)` filter would).
719
+ */
720
+ sumWonSince(since: Date, ctx?: CrmContext): Promise<{
721
+ total: number;
722
+ currency?: string;
723
+ } | null>;
724
+ /** Latest `limit` opportunities — lightweight projection for the activity feed. */
725
+ findRecentForFeed(limit: number, ctx?: CrmContext): Promise<IOpportunityDocument[]>;
726
+ }
905
727
  //#endregion
906
- //#region src/repositories/pipeline.repository.d.ts
907
- interface PipelineRepositoryDeps {
728
+ //#region src/repositories/contact.repository.d.ts
729
+ interface ContactRepositoryDeps {
908
730
  events: EventTransport;
909
731
  }
910
- declare class PipelineRepository extends Repository<IPipelineDocument> {
732
+ interface MergeContactInput {
733
+ /** Surviving contact id. Receives merged fields. */
734
+ primaryId: string;
735
+ /** Secondary contact id. Deleted after merge. */
736
+ secondaryId: string;
737
+ /**
738
+ * Per-field strategy. Defaults to `'preferPrimary'` — primary's
739
+ * non-empty fields win, secondary fills the gaps. Use `'preferSecondary'`
740
+ * for the reverse. `tags` are always unioned.
741
+ */
742
+ strategy?: 'preferPrimary' | 'preferSecondary';
743
+ }
744
+ declare class ContactRepository extends Repository<IContactDocument> {
911
745
  private readonly events;
912
- constructor(model: Model<IPipelineDocument>, plugins: PluginType[], deps: PipelineRepositoryDeps, pagination?: PaginationConfig);
746
+ constructor(model: Model<IContactDocument>, plugins: PluginType[], deps: ContactRepositoryDeps, pagination?: PaginationConfig);
913
747
  /**
914
- * Read a single embedded stage. Used by Opportunity create / move to
915
- * validate stage membership + pick up `defaultProbability`.
748
+ * Create + emit `crm:contact.created`. Hosts call this instead of
749
+ * `create()` when they want the event side-effect (e.g. webhook fan-out).
916
750
  */
917
- getStage(pipelineId: string, stageId: string, ctx?: CrmContext): Promise<IStageDocument>;
918
- /** First stage by `sequence` ascending. */
919
- getFirstStage(pipelineId: string, ctx?: CrmContext): Promise<IStageDocument>;
920
- /** Stage immediately after the given one. `null` at terminal stage. */
921
- getNextStage(pipelineId: string, stageId: string, ctx?: CrmContext): Promise<IStageDocument | null>;
922
- /** Soft-deprecate — existing opps still move; no new ones can be created. */
923
- archive(id: string, ctx?: CrmContext): Promise<IPipelineDocument>;
751
+ createContact(input: Partial<IContactDocument>, ctx?: CrmContext): Promise<IContactDocument>;
752
+ /**
753
+ * Merge enrichment payload into the contact. The `patch` is applied
754
+ * verbatim; deep-merge of `contact.*` channels is the caller's job
755
+ * (they own the provider response shape).
756
+ */
757
+ enrich(id: string, patch: Partial<IContactDocument>, extras?: {
758
+ provider?: string;
759
+ }, ctx?: CrmContext): Promise<IContactDocument>;
760
+ /** Set / re-assign the contact's owner. Atomic; no-op when unchanged. */
761
+ assign(id: string, ownerId: string, ctx?: CrmContext): Promise<IContactDocument>;
762
+ /**
763
+ * Merge two contacts. Secondary's non-conflicting fields are folded
764
+ * into primary, tags are unioned, then secondary is deleted.
765
+ *
766
+ * Hosts wanting transactional safety can pass `ctx.session` —
767
+ * mongokit threads it through `update` + `delete`.
768
+ *
769
+ * Re-pointing related Activities / Notes / Opportunities is the host's
770
+ * job (they own those relationships) — subscribe to
771
+ * `crm:contact.merged` and rewrite `subjectId` / `primaryContactId`
772
+ * from there.
773
+ */
774
+ merge(input: MergeContactInput, ctx?: CrmContext): Promise<IContactDocument>;
924
775
  }
925
776
  //#endregion
926
- //#region src/shared/calculators/scoring.d.ts
927
- /** Minimal Lead shape the scorer reads. */
928
- type LeadInput = Pick<ILeadDocument, 'email' | 'phone' | 'companyName' | 'tags' | 'jobTitle'>;
929
- type LeadScorer = (lead: LeadInput) => number;
930
- /**
931
- * Reference implementation. Intentionally simple — hosts read it and
932
- * replace it.
933
- *
934
- * +20 if email is present
935
- * +20 if phone is present
936
- * +20 if companyName is present
937
- * +10 per populated tag up to 40
938
- * +10 if jobTitle hints senior (director / manager / head / chief / vp / founder)
939
- */
940
- declare function defaultLeadScorer(lead: LeadInput): number;
941
- /** Compose multiple small rules into one scorer. */
942
- declare function composeScorers(...rules: readonly LeadScorer[]): LeadScorer;
777
+ //#region src/repositories/account.repository.d.ts
778
+ interface AccountRepositoryDeps {
779
+ events: EventTransport;
780
+ }
781
+ interface MergeAccountInput {
782
+ primaryId: string;
783
+ secondaryId: string;
784
+ strategy?: 'preferPrimary' | 'preferSecondary';
785
+ }
786
+ declare class AccountRepository extends Repository<IAccountDocument> {
787
+ private readonly events;
788
+ constructor(model: Model<IAccountDocument>, plugins: PluginType[], deps: AccountRepositoryDeps, pagination?: PaginationConfig);
789
+ createAccount(input: Partial<IAccountDocument>, ctx?: CrmContext): Promise<IAccountDocument>;
790
+ enrich(id: string, patch: Partial<IAccountDocument>, extras?: {
791
+ provider?: string;
792
+ }, ctx?: CrmContext): Promise<IAccountDocument>;
793
+ assign(id: string, ownerId: string, ctx?: CrmContext): Promise<IAccountDocument>;
794
+ merge(input: MergeAccountInput, ctx?: CrmContext): Promise<IAccountDocument>;
795
+ }
943
796
  //#endregion
944
- //#region src/repositories/lead.repository.d.ts
945
- interface LeadRepositoryDeps {
797
+ //#region src/repositories/campaign.repository.d.ts
798
+ interface CampaignRepositoryDeps {
946
799
  events: EventTransport;
947
- /** Override the default lead scorer. */
948
- scorer?: LeadScorer;
949
- /** Reject `create()` when an email already exists in-tenant (default true). */
800
+ /** Reject `createCampaign` on duplicate names per-tenant (default true). */
950
801
  rejectDuplicates?: boolean;
951
802
  }
952
- type TransitionExtras = {
803
+ type ExtrasWithRevenue = {
953
804
  by?: string;
954
805
  note?: string;
955
- patch?: Partial<ILeadDocument>;
806
+ actualRevenueAmount?: number;
956
807
  };
957
- declare class LeadRepository extends Repository<ILeadDocument> {
808
+ declare class CampaignRepository extends Repository<ICampaignDocument> {
958
809
  private readonly events;
959
- private readonly scorer;
960
810
  private readonly rejectDuplicates;
961
- constructor(model: Model<ILeadDocument>, plugins: PluginType[], deps: LeadRepositoryDeps, pagination?: PaginationConfig);
811
+ constructor(model: Model<ICampaignDocument>, plugins: PluginType[], deps: CampaignRepositoryDeps, pagination?: PaginationConfig);
812
+ createCampaign(input: Partial<ICampaignDocument>, ctx?: CrmContext): Promise<ICampaignDocument>;
813
+ activate(id: string, by?: string, ctx?: CrmContext): Promise<ICampaignDocument>;
814
+ pause(id: string, reason?: string, by?: string, ctx?: CrmContext): Promise<ICampaignDocument>;
815
+ resume(id: string, by?: string, ctx?: CrmContext): Promise<ICampaignDocument>;
816
+ complete(id: string, extras?: ExtrasWithRevenue, ctx?: CrmContext): Promise<ICampaignDocument>;
817
+ archive(id: string, by?: string, ctx?: CrmContext): Promise<ICampaignDocument>;
818
+ private _transition;
819
+ }
820
+ //#endregion
821
+ //#region src/repositories/subscription.repository.d.ts
822
+ interface SubscriptionRepositoryDeps {
823
+ events: EventTransport;
824
+ /** Default DOI policy when `subscribe` doesn't pass `requireDoubleOptIn`. */
825
+ defaultRequireDoubleOptIn?: boolean;
826
+ }
827
+ interface SubscribeInput {
828
+ contactId: string;
829
+ campaignId: string;
830
+ source?: string;
831
+ consentIpAddress?: string;
832
+ consentUserAgent?: string;
833
+ metadata?: Record<string, unknown>;
834
+ /** Override the engine-level default. */
835
+ requireDoubleOptIn?: boolean;
836
+ }
837
+ declare class SubscriptionRepository extends Repository<ISubscriptionDocument> {
838
+ private readonly events;
839
+ private readonly defaultRequireDoubleOptIn;
840
+ constructor(model: Model<ISubscriptionDocument>, plugins: PluginType[], deps: SubscriptionRepositoryDeps, pagination?: PaginationConfig);
841
+ subscribe(input: SubscribeInput, ctx?: CrmContext): Promise<ISubscriptionDocument>;
842
+ confirm(token: string, ctx?: CrmContext): Promise<ISubscriptionDocument>;
843
+ unsubscribe(token: string, reason?: string, ctx?: CrmContext): Promise<ISubscriptionDocument>;
844
+ markBounced(id: string, reason?: string, ctx?: CrmContext): Promise<ISubscriptionDocument>;
845
+ markComplained(id: string, ctx?: CrmContext): Promise<ISubscriptionDocument>;
846
+ private _transition;
847
+ }
848
+ //#endregion
849
+ //#region src/repositories/activity.repository.d.ts
850
+ interface ActivityRepositoryDeps {
851
+ events: EventTransport;
852
+ }
853
+ declare class ActivityRepository extends Repository<IActivityDocument> {
854
+ private readonly events;
855
+ constructor(model: Model<IActivityDocument>, plugins: PluginType[], deps: ActivityRepositoryDeps, pagination?: PaginationConfig);
856
+ plan(input: Partial<IActivityDocument>, ctx?: CrmContext): Promise<IActivityDocument>;
857
+ start(id: string, ctx?: CrmContext): Promise<IActivityDocument>;
858
+ complete(id: string, completedAt?: Date, ctx?: CrmContext): Promise<IActivityDocument>;
859
+ cancel(id: string, reason?: string, ctx?: CrmContext): Promise<IActivityDocument>;
962
860
  /**
963
- * Create a Lead. Auto-scores on insert so hosts can route immediately.
964
- * Rejects duplicate emails inside the same tenant unless
965
- * `rejectDuplicates: false` was set at engine boot.
861
+ * Push an activity's `dueDate`. Allowed on planned / in_progress only;
862
+ * rescheduling a completed or cancelled activity makes no sense.
863
+ * Emits `crm:activity.rescheduled` with the previous date for audit.
966
864
  */
967
- createLead(input: Partial<ILeadDocument>, ctx?: CrmContext): Promise<ILeadDocument>;
968
- markContacted(id: string, extras?: TransitionExtras, ctx?: CrmContext): Promise<ILeadDocument>;
969
- qualify(id: string, extras?: TransitionExtras, ctx?: CrmContext): Promise<ILeadDocument>;
970
- disqualify(id: string, reason: string, extras?: Omit<TransitionExtras, 'patch'>, ctx?: CrmContext): Promise<ILeadDocument>;
971
- nurture(id: string, extras?: TransitionExtras, ctx?: CrmContext): Promise<ILeadDocument>;
865
+ reschedule(id: string, newDueDate: Date, extras?: {
866
+ reason?: string;
867
+ by?: string;
868
+ }, ctx?: CrmContext): Promise<IActivityDocument>;
972
869
  /**
973
- * Merge enrichment payload (3rd-party provider response or manual
974
- * patch) into the lead doc, then re-score. Emits `crm:lead.enriched`
975
- * with the field set written so subscribers can fan out (e.g. push a
976
- * `recompute_segment` job) without re-reading the doc.
870
+ * Record the outcome of an activity (call result, email engagement,
871
+ * meeting confirmation). Stored under `metadata.outcome` so it stays
872
+ * polymorphic — the shape is the channel's concern, not this package's.
977
873
  *
978
- * The `provider` tag flows into the event for attribution; the package
979
- * is provider-agnostic so the actual enrichment call lives at the host.
980
- */
981
- enrich(id: string, patch: Partial<ILeadDocument>, extras?: {
982
- provider?: string;
983
- }, ctx?: CrmContext): Promise<ILeadDocument>;
984
- /**
985
- * Assign / re-assign the lead's owner. Emits `crm:lead.assigned` with
986
- * the previous owner so audit consumers can compute hand-off chains.
987
- */
988
- assign(id: string, ownerId: string, ctx?: CrmContext): Promise<ILeadDocument>;
989
- /**
990
- * Recompute + persist the lead's score. Called from `createLead`
991
- * automatically; hosts also call this after enrichment writes.
874
+ * Does NOT transition status — call `complete()` separately when the
875
+ * outcome implies completion. This split lets agents log partial
876
+ * outcomes (e.g. "left voicemail") without forcing terminal state.
992
877
  */
993
- recomputeScore(id: string, ctx?: CrmContext): Promise<ILeadDocument>;
878
+ recordOutcome(id: string, outcome: Record<string, unknown>, ctx?: CrmContext): Promise<IActivityDocument>;
994
879
  private _transition;
880
+ /** Count `planned` activities with `dueDate` before `asOf`. Dashboard KPI. */
881
+ countOverduePlanned(asOf: Date, ctx?: CrmContext): Promise<number>;
882
+ /** Latest `limit` activities — lightweight projection for the activity feed. */
883
+ findRecentForFeed(limit: number, ctx?: CrmContext): Promise<IActivityDocument[]>;
884
+ }
885
+ //#endregion
886
+ //#region src/repositories/note.repository.d.ts
887
+ interface NoteRepositoryDeps {
888
+ events: EventTransport;
889
+ }
890
+ declare class NoteRepository extends Repository<INoteDocument> {
891
+ private readonly events;
892
+ constructor(model: Model<INoteDocument>, plugins: PluginType[], deps: NoteRepositoryDeps, pagination?: PaginationConfig);
893
+ addNote(input: Partial<INoteDocument>, ctx?: CrmContext): Promise<INoteDocument>;
894
+ }
895
+ //#endregion
896
+ //#region src/repositories/loss-reason.repository.d.ts
897
+ interface LossReasonRepositoryDeps {
898
+ events: EventTransport;
899
+ }
900
+ declare class LossReasonRepository extends Repository<ILossReasonDocument> {
901
+ private readonly events;
902
+ constructor(model: Model<ILossReasonDocument>, plugins: PluginType[], deps: LossReasonRepositoryDeps, pagination?: PaginationConfig);
903
+ /** Hide from pickers without breaking historical FKs. */
904
+ archive(id: string, ctx?: CrmContext): Promise<ILossReasonDocument>;
905
+ }
906
+ //#endregion
907
+ //#region src/repositories/email-event.repository.d.ts
908
+ interface EmailEventRepositoryDeps {
909
+ events: EventTransport;
910
+ }
911
+ interface RecordEmailEventInput {
912
+ subjectKind: EmailEventSubjectKind;
913
+ subjectId: string;
914
+ campaignId?: string;
915
+ messageId?: string;
916
+ url?: string;
917
+ userAgent?: string;
918
+ ip?: string;
919
+ metadata?: Record<string, unknown>;
920
+ }
921
+ declare class EmailEventRepository extends Repository<IEmailEventDocument> {
922
+ private readonly events;
923
+ constructor(model: Model<IEmailEventDocument>, plugins: PluginType[], deps: EmailEventRepositoryDeps, pagination?: PaginationConfig);
924
+ recordOpen(input: RecordEmailEventInput, ctx?: CrmContext): Promise<IEmailEventDocument>;
925
+ recordClick(input: RecordEmailEventInput, ctx?: CrmContext): Promise<IEmailEventDocument>;
926
+ recordBounce(input: RecordEmailEventInput, ctx?: CrmContext): Promise<IEmailEventDocument>;
927
+ recordComplaint(input: RecordEmailEventInput, ctx?: CrmContext): Promise<IEmailEventDocument>;
928
+ recordUnsubscribe(input: RecordEmailEventInput, ctx?: CrmContext): Promise<IEmailEventDocument>;
929
+ private _record;
930
+ }
931
+ //#endregion
932
+ //#region src/repositories/conversation.repository.d.ts
933
+ interface ConversationRepositoryDeps {
934
+ events: EventTransport;
935
+ }
936
+ interface OpenConversationInput {
937
+ channel: ConversationChannel;
938
+ participantKind: ConversationParticipantKind;
939
+ participantId: string;
940
+ channelUserId?: string;
941
+ assigneeId?: string;
942
+ metadata?: Record<string, unknown>;
943
+ }
944
+ declare class ConversationRepository extends Repository<IConversationDocument> {
945
+ private readonly events;
946
+ constructor(model: Model<IConversationDocument>, plugins: PluginType[], deps: ConversationRepositoryDeps, pagination?: PaginationConfig);
947
+ openConversation(input: OpenConversationInput, ctx?: CrmContext): Promise<IConversationDocument>;
948
+ assign(id: string, assigneeId: string, ctx?: CrmContext): Promise<IConversationDocument>;
949
+ resolve(id: string, ctx?: CrmContext): Promise<IConversationDocument>;
950
+ reopen(id: string, ctx?: CrmContext): Promise<IConversationDocument>;
951
+ /** Reset unread badge. Pure UI affordance, no event. */
952
+ markRead(id: string, ctx?: CrmContext): Promise<IConversationDocument>;
995
953
  /**
996
- * Count leads created on or after `since`. Used by dashboard KPI tiles.
997
- * Goes through the inherited tenant-scoped `count()` — the plugin
998
- * injects `organizationId` (never a manual `if (ctx)` filter, which
999
- * silently reads ALL tenants when ctx is absent).
954
+ * Bump `lastMessageAt` and (for inbound) increment `unreadCount`.
955
+ * Called by `MessageRepository` when a message is recorded — not part
956
+ * of the public surface. Returns the conversation for the caller's
957
+ * follow-up writes.
1000
958
  */
1001
- countCreatedSince(since: Date, ctx?: CrmContext): Promise<number>;
1002
- /** Latest `limit` leads — lightweight projection for the activity feed. */
1003
- findRecentForFeed(limit: number, ctx?: CrmContext): Promise<ILeadDocument[]>;
959
+ touch(id: string, args: {
960
+ direction: 'inbound' | 'outbound';
961
+ sentAt: Date;
962
+ }, ctx?: CrmContext): Promise<IConversationDocument | null>;
963
+ private _setStatus;
1004
964
  }
1005
965
  //#endregion
1006
- //#region src/repositories/opportunity.repository.d.ts
1007
- interface OpportunityRepositoryDeps {
966
+ //#region src/repositories/message.repository.d.ts
967
+ interface MessageRepositoryDeps {
1008
968
  events: EventTransport;
1009
- /** Cross-repo reference: read embedded stages from Pipeline. */
1010
- pipelines: PipelineRepository;
969
+ conversations: ConversationRepository;
1011
970
  }
1012
- interface OpenOpportunityInput {
1013
- name: string;
1014
- pipelineId: string;
1015
- /** When omitted, opp enters the pipeline's first stage. */
1016
- stageId?: string;
1017
- accountId?: string;
1018
- primaryContactId?: string;
1019
- sourceLeadId?: string;
1020
- amount?: number;
1021
- currency?: string;
1022
- /** Override the stage's `defaultProbability`. */
1023
- probability?: number;
1024
- expectedCloseAt?: Date;
1025
- ownerId?: string;
1026
- tags?: readonly string[];
971
+ interface RecordMessageInput {
972
+ conversationId: string;
973
+ body: string;
974
+ attachments?: IMessageAttachment[];
975
+ externalMessageId?: string;
976
+ senderRef?: string;
977
+ recipientRef?: string;
978
+ sentAt?: Date;
1027
979
  metadata?: Record<string, unknown>;
1028
980
  }
1029
- interface MoveStageInput {
1030
- stageId: string;
1031
- by?: string;
1032
- note?: string;
1033
- /** Override the target stage's `defaultProbability`. */
1034
- probability?: number;
981
+ declare class MessageRepository extends Repository<IMessageDocument> {
982
+ private readonly events;
983
+ private readonly conversations;
984
+ constructor(model: Model<IMessageDocument>, plugins: PluginType[], deps: MessageRepositoryDeps, pagination?: PaginationConfig);
985
+ recordInbound(input: RecordMessageInput, ctx?: CrmContext): Promise<IMessageDocument>;
986
+ recordOutbound(input: RecordMessageInput, ctx?: CrmContext): Promise<IMessageDocument>;
987
+ /** Wire delivery callback (e.g. WhatsApp `status` webhook). */
988
+ updateStatus(id: string, status: MessageDeliveryStatus, ctx?: CrmContext): Promise<IMessageDocument>;
989
+ private _record;
990
+ /** Latest `limit` messages — lightweight projection for the activity feed. */
991
+ findRecentForFeed(limit: number, ctx?: CrmContext): Promise<IMessageDocument[]>;
1035
992
  }
1036
- interface CloseInput {
1037
- by?: string;
1038
- note?: string;
1039
- closedAt?: Date;
1040
- amount?: number;
1041
- lostReasonId?: string;
993
+ //#endregion
994
+ //#region src/engine/engine-types.d.ts
995
+ interface CrmLogger {
996
+ info?(msg: string, meta?: Record<string, unknown>): void;
997
+ warn?(msg: string, meta?: Record<string, unknown>): void;
998
+ error?(msg: string, meta?: Record<string, unknown>): void;
999
+ debug?(msg: string, meta?: Record<string, unknown>): void;
1042
1000
  }
1043
- declare class OpportunityRepository extends Repository<IOpportunityDocument> {
1044
- private readonly events;
1045
- private readonly pipelines;
1046
- constructor(model: Model<IOpportunityDocument>, plugins: PluginType[], deps: OpportunityRepositoryDeps, pagination?: PaginationConfig);
1047
- openOpportunity(input: OpenOpportunityInput, ctx?: CrmContext): Promise<IOpportunityDocument>;
1001
+ interface CrmConfig {
1002
+ /** Mongoose connection — package creates models on this connection. */
1003
+ connection: Connection;
1048
1004
  /**
1049
- * Atomic stage move. CAS on `(status='open', stageId=current)` so two
1050
- * concurrent moves can't both win. Emits `stage_advanced` or
1051
- * `stage_regressed` based on `sequence` ordering of the embedded stages.
1005
+ * Tenant column shape. `'objectId'` (default) matches Better Auth orgs
1006
+ * and unlocks `$lookup` / `.populate()`; `'string'` matches UUID hosts.
1007
+ * Threaded into both schemas and `multiTenantPlugin` so they stay in
1008
+ * sync (PACKAGE_RULES §9.2).
1052
1009
  */
1053
- moveToStage(id: string, input: MoveStageInput, ctx?: CrmContext): Promise<IOpportunityDocument>;
1054
- win(id: string, input?: CloseInput, ctx?: CrmContext): Promise<IOpportunityDocument>;
1055
- lose(id: string, input?: CloseInput, ctx?: CrmContext): Promise<IOpportunityDocument>;
1010
+ tenantFieldType?: TenantFieldType;
1056
1011
  /**
1057
- * Re-assign opportunity owner. Mutates `ownerId` only; no status
1058
- * transition. Emits `crm:opportunity.assigned` with the previous owner.
1012
+ * When `true` (default), wire `multiTenantPlugin` on every repository
1013
+ * with `required: true`. Set `false` only for fixtures / smoke tests
1014
+ * that intentionally drop the scope.
1059
1015
  */
1060
- assign(id: string, ownerId: string, ctx?: CrmContext): Promise<IOpportunityDocument>;
1016
+ multiTenant?: boolean;
1017
+ /** Arc-compatible event transport. Default: in-process bus. */
1018
+ eventTransport?: EventTransport;
1019
+ /** Logger surface used by the in-process bus + repositories. */
1020
+ logger?: CrmLogger;
1021
+ /** Pagination defaults for every repository (mongokit). */
1022
+ pagination?: PaginationConfig;
1023
+ /** Extra mongokit plugins applied to every repository (after defaults). */
1024
+ plugins?: PluginType[];
1061
1025
  /**
1062
- * Adjust the deal amount on an open opportunity. Rejected after
1063
- * win/lose/abandon — closed-deal amounts are immutable history.
1064
- * Emits `crm:opportunity.amount_changed` with the delta so forecast
1065
- * subscribers can re-bucket.
1026
+ * On a Mongoose model-name collision (another engine / hot reload owns
1027
+ * the name): `false` (default) throws `CrmModelCollisionError`; `true`
1028
+ * deletes + re-registers. Test fixtures / hot reload only (§21).
1066
1029
  */
1067
- updateAmount(id: string, amount: number, extras?: {
1068
- reason?: string;
1069
- by?: string;
1070
- }, ctx?: CrmContext): Promise<IOpportunityDocument>;
1030
+ forceRecreate?: boolean;
1071
1031
  /**
1072
- * Push `expectedCloseAt` further out. Only valid on open opps —
1073
- * extending a closed deal is meaningless. The new date must be later
1074
- * than the current one; pulling the date in is silently accepted
1075
- * (no event is meaningful there).
1032
+ * Mongoose auto-index builds. Default `true` (dev). Set `false` in
1033
+ * production and run `engine.syncIndexes()` from a deploy script so
1034
+ * cold-boot index builds don't blow Fastify's plugin timeout (§35).
1076
1035
  */
1077
- extendCloseDate(id: string, newDate: Date, extras?: {
1078
- reason?: string;
1079
- by?: string;
1080
- }, ctx?: CrmContext): Promise<IOpportunityDocument>;
1081
- abandon(id: string, by?: string, note?: string, ctx?: CrmContext): Promise<IOpportunityDocument>;
1082
- private _closeStatus;
1083
- /** Count opportunities with status `open`. Used by dashboard KPI tiles. */
1084
- countOpen(ctx?: CrmContext): Promise<number>;
1036
+ autoIndex?: boolean;
1085
1037
  /**
1086
- * Sum `amount` on won opportunities updated within `since`.
1087
- * Goes through the tenant-scoped `findAll()` — the multiTenant plugin
1088
- * injects `organizationId`, so a missing ctx can't leak other tenants'
1089
- * revenue (a manual `if (ctx)` filter would).
1038
+ * Skip the boot-time `transactions` capability requirement, downgrading
1039
+ * it to a warning. Set only when the host never calls
1040
+ * `LeadService.convert()` inside a transaction (standalone Mongo).
1090
1041
  */
1091
- sumWonSince(since: Date, ctx?: CrmContext): Promise<{
1092
- total: number;
1093
- currency?: string;
1094
- } | null>;
1095
- /** Latest `limit` opportunities — lightweight projection for the activity feed. */
1096
- findRecentForFeed(limit: number, ctx?: CrmContext): Promise<IOpportunityDocument[]>;
1042
+ allowNonTransactional?: boolean;
1097
1043
  }
1098
- //#endregion
1099
- //#region src/repositories/contact.repository.d.ts
1100
- interface ContactRepositoryDeps {
1101
- events: EventTransport;
1044
+ interface ResolvedCrmConfig extends SchemaBuildConfig {
1045
+ connection: Connection;
1046
+ tenantFieldType: TenantFieldType;
1047
+ multiTenant: boolean;
1048
+ forceRecreate: boolean;
1049
+ autoIndex: boolean;
1050
+ logger?: CrmLogger;
1051
+ pagination?: PaginationConfig;
1052
+ plugins: PluginType[];
1102
1053
  }
1103
- interface MergeContactInput {
1104
- /** Surviving contact id. Receives merged fields. */
1105
- primaryId: string;
1106
- /** Secondary contact id. Deleted after merge. */
1107
- secondaryId: string;
1108
- /**
1109
- * Per-field strategy. Defaults to `'preferPrimary'` — primary's
1110
- * non-empty fields win, secondary fills the gaps. Use `'preferSecondary'`
1111
- * for the reverse. `tags` are always unioned.
1112
- */
1113
- strategy?: 'preferPrimary' | 'preferSecondary';
1054
+ interface CrmRepositories {
1055
+ pipeline: PipelineRepository;
1056
+ lead: LeadRepository;
1057
+ opportunity: OpportunityRepository;
1058
+ contact: ContactRepository;
1059
+ account: AccountRepository;
1060
+ campaign: CampaignRepository;
1061
+ subscription: SubscriptionRepository;
1062
+ activity: ActivityRepository;
1063
+ note: NoteRepository;
1064
+ lossReason: LossReasonRepository;
1065
+ emailEvent: EmailEventRepository;
1066
+ conversation: ConversationRepository;
1067
+ message: MessageRepository;
1114
1068
  }
1115
- declare class ContactRepository extends Repository<IContactDocument> {
1116
- private readonly events;
1117
- constructor(model: Model<IContactDocument>, plugins: PluginType[], deps: ContactRepositoryDeps, pagination?: PaginationConfig);
1118
- /**
1119
- * Create + emit `crm:contact.created`. Hosts call this instead of
1120
- * `create()` when they want the event side-effect (e.g. webhook fan-out).
1121
- */
1122
- createContact(input: Partial<IContactDocument>, ctx?: CrmContext): Promise<IContactDocument>;
1123
- /**
1124
- * Merge enrichment payload into the contact. The `patch` is applied
1125
- * verbatim; deep-merge of `contact.*` channels is the caller's job
1126
- * (they own the provider response shape).
1127
- */
1128
- enrich(id: string, patch: Partial<IContactDocument>, extras?: {
1129
- provider?: string;
1130
- }, ctx?: CrmContext): Promise<IContactDocument>;
1131
- /** Set / re-assign the contact's owner. Atomic; no-op when unchanged. */
1132
- assign(id: string, ownerId: string, ctx?: CrmContext): Promise<IContactDocument>;
1069
+ interface CrmEngine {
1070
+ /** Repositories ARE the API surface (PACKAGE_RULES §1). */
1071
+ readonly repositories: Readonly<CrmRepositories>;
1072
+ /** Arc-compatible event transport. */
1073
+ readonly events: EventTransport;
1074
+ /** Mongoose models — for arc adapter wiring. */
1075
+ readonly models: Readonly<CrmModels>;
1076
+ /** Resolved configuration (frozen). */
1077
+ readonly config: Readonly<ResolvedCrmConfig>;
1133
1078
  /**
1134
- * Merge two contacts. Secondary's non-conflicting fields are folded
1135
- * into primary, tags are unioned, then secondary is deleted.
1136
- *
1137
- * Hosts wanting transactional safety can pass `ctx.session` —
1138
- * mongokit threads it through `update` + `delete`.
1139
- *
1140
- * Re-pointing related Activities / Notes / Opportunities is the host's
1141
- * job (they own those relationships) — subscribe to
1142
- * `crm:contact.merged` and rewrite `subjectId` / `primaryContactId`
1143
- * from there.
1079
+ * Build/align every model's indexes against its schema. Call once per
1080
+ * deploy when booted with `autoIndex: false` (§35). Idempotent.
1144
1081
  */
1145
- merge(input: MergeContactInput, ctx?: CrmContext): Promise<IContactDocument>;
1082
+ syncIndexes(): Promise<void>;
1083
+ /** Release resources. Safe to call multiple times. */
1084
+ dispose(): Promise<void>;
1085
+ }
1086
+ /**
1087
+ * Operation context threaded through every domain verb. Extends
1088
+ * primitives' `OperationContext` and narrows `IdLike` to types Mongoose
1089
+ * stores cleanly. Host-specific extras go through the inherited
1090
+ * `metadata?` field — keep the typed surface tight.
1091
+ */
1092
+ interface CrmContext extends OperationContext {
1093
+ organizationId?: string | _$mongoose.Types.ObjectId;
1094
+ actorId?: string | _$mongoose.Types.ObjectId;
1095
+ /** Mongo transaction session (passed through to mongokit). */
1096
+ session?: unknown;
1146
1097
  }
1098
+ type _ModelTypes = Model<unknown>;
1147
1099
  //#endregion
1148
- //#region src/repositories/account.repository.d.ts
1149
- interface AccountRepositoryDeps {
1100
+ //#region src/engine/create-crm.d.ts
1101
+ declare function createCrm(config: CrmConfig): Promise<CrmEngine>;
1102
+ //#endregion
1103
+ //#region src/repositories/create-repositories.d.ts
1104
+ interface CreateCrmRepositoriesDeps {
1150
1105
  events: EventTransport;
1106
+ config: ResolvedCrmConfig;
1151
1107
  }
1152
- interface MergeAccountInput {
1153
- primaryId: string;
1154
- secondaryId: string;
1155
- strategy?: 'preferPrimary' | 'preferSecondary';
1108
+ declare function createCrmRepositories(models: CrmModels, deps: CreateCrmRepositoriesDeps): CrmRepositories;
1109
+ //#endregion
1110
+ //#region src/services/lead.service.d.ts
1111
+ interface ConvertLeadInput {
1112
+ pipelineId: string;
1113
+ /** Defaults to `<companyName> — <source>` / `<fullName> — New`. */
1114
+ opportunityName?: string;
1115
+ /** Stored flat on the opportunity (`amount` + `currency`). */
1116
+ amount?: number;
1117
+ currency?: string;
1118
+ expectedCloseAt?: Date;
1119
+ by?: string;
1156
1120
  }
1157
- declare class AccountRepository extends Repository<IAccountDocument> {
1158
- private readonly events;
1159
- constructor(model: Model<IAccountDocument>, plugins: PluginType[], deps: AccountRepositoryDeps, pagination?: PaginationConfig);
1160
- createAccount(input: Partial<IAccountDocument>, ctx?: CrmContext): Promise<IAccountDocument>;
1161
- enrich(id: string, patch: Partial<IAccountDocument>, extras?: {
1162
- provider?: string;
1163
- }, ctx?: CrmContext): Promise<IAccountDocument>;
1164
- assign(id: string, ownerId: string, ctx?: CrmContext): Promise<IAccountDocument>;
1165
- merge(input: MergeAccountInput, ctx?: CrmContext): Promise<IAccountDocument>;
1121
+ interface ConvertResult {
1122
+ lead: ILeadDocument;
1123
+ contact: IContactDocument;
1124
+ account?: IAccountDocument;
1125
+ opportunity: IOpportunityDocument;
1126
+ /** Convenience string id — same as `String(contact._id)`. */
1127
+ contactId: string;
1128
+ /** Convenience string id — present only when an account was created. */
1129
+ accountId?: string;
1130
+ /** Convenience string id — same as `String(opportunity._id)`. */
1131
+ opportunityId: string;
1166
1132
  }
1167
- //#endregion
1168
- //#region src/repositories/campaign.repository.d.ts
1169
- interface CampaignRepositoryDeps {
1133
+ interface LeadServiceDeps {
1134
+ lead: LeadRepository;
1135
+ contact: ContactRepository;
1136
+ account: AccountRepository;
1137
+ opportunity: OpportunityRepository;
1170
1138
  events: EventTransport;
1171
- /** Reject `createCampaign` on duplicate names per-tenant (default true). */
1172
- rejectDuplicates?: boolean;
1173
1139
  }
1174
- type ExtrasWithRevenue = {
1175
- by?: string;
1176
- note?: string;
1177
- actualRevenueAmount?: number;
1178
- };
1179
- declare class CampaignRepository extends Repository<ICampaignDocument> {
1140
+ declare class LeadService {
1141
+ private readonly leads;
1142
+ private readonly contacts;
1143
+ private readonly accounts;
1144
+ private readonly opportunities;
1180
1145
  private readonly events;
1181
- private readonly rejectDuplicates;
1182
- constructor(model: Model<ICampaignDocument>, plugins: PluginType[], deps: CampaignRepositoryDeps, pagination?: PaginationConfig);
1183
- createCampaign(input: Partial<ICampaignDocument>, ctx?: CrmContext): Promise<ICampaignDocument>;
1184
- activate(id: string, by?: string, ctx?: CrmContext): Promise<ICampaignDocument>;
1185
- pause(id: string, reason?: string, by?: string, ctx?: CrmContext): Promise<ICampaignDocument>;
1186
- resume(id: string, by?: string, ctx?: CrmContext): Promise<ICampaignDocument>;
1187
- complete(id: string, extras?: ExtrasWithRevenue, ctx?: CrmContext): Promise<ICampaignDocument>;
1188
- archive(id: string, by?: string, ctx?: CrmContext): Promise<ICampaignDocument>;
1189
- private _transition;
1146
+ constructor(deps: LeadServiceDeps);
1147
+ /**
1148
+ * Construct from an already-built CrmEngine — the host's preferred path.
1149
+ * Avoids manually wiring four repositories.
1150
+ */
1151
+ static fromEngine(engine: CrmEngine): LeadService;
1152
+ /**
1153
+ * Convert a Lead into Account + Contact + Opportunity, then transition
1154
+ * the lead. Wrap the call in `connection.transaction()` and pass the
1155
+ * session via `ctx.session` for atomicity — all four writes commit or
1156
+ * roll back together.
1157
+ *
1158
+ * Best-effort compensation: if a downstream write fails, already-
1159
+ * created docs are deleted in reverse order. The reverse delete may
1160
+ * itself fail (e.g. transient DB issues) — when transactions are
1161
+ * active, prefer that path; compensation is the no-transaction
1162
+ * fallback.
1163
+ */
1164
+ convert(leadId: string, input: ConvertLeadInput, ctx?: CrmContext): Promise<ConvertResult>;
1165
+ /**
1166
+ * The state-machine hop from whichever status the lead is in to
1167
+ * `converted`. We do this directly (instead of calling
1168
+ * `LeadRepository.qualify` first then a hypothetical `complete`)
1169
+ * because the conversion is "this lead is done" regardless of where
1170
+ * it started — bypassing the `qualified` waypoint is intentional when
1171
+ * a Lead is converted directly from `new` (importers, webhooks).
1172
+ */
1173
+ private _markConverted;
1190
1174
  }
1191
1175
  //#endregion
1192
- //#region src/repositories/subscription.repository.d.ts
1193
- interface SubscriptionRepositoryDeps {
1194
- events: EventTransport;
1195
- /** Default DOI policy when `subscribe` doesn't pass `requireDoubleOptIn`. */
1196
- defaultRequireDoubleOptIn?: boolean;
1197
- }
1198
- interface SubscribeInput {
1199
- contactId: string;
1200
- campaignId: string;
1201
- source?: string;
1202
- consentIpAddress?: string;
1203
- consentUserAgent?: string;
1204
- metadata?: Record<string, unknown>;
1205
- /** Override the engine-level default. */
1206
- requireDoubleOptIn?: boolean;
1207
- }
1208
- declare class SubscriptionRepository extends Repository<ISubscriptionDocument> {
1209
- private readonly events;
1210
- private readonly defaultRequireDoubleOptIn;
1211
- constructor(model: Model<ISubscriptionDocument>, plugins: PluginType[], deps: SubscriptionRepositoryDeps, pagination?: PaginationConfig);
1212
- subscribe(input: SubscribeInput, ctx?: CrmContext): Promise<ISubscriptionDocument>;
1213
- confirm(token: string, ctx?: CrmContext): Promise<ISubscriptionDocument>;
1214
- unsubscribe(token: string, reason?: string, ctx?: CrmContext): Promise<ISubscriptionDocument>;
1215
- markBounced(id: string, reason?: string, ctx?: CrmContext): Promise<ISubscriptionDocument>;
1216
- markComplained(id: string, ctx?: CrmContext): Promise<ISubscriptionDocument>;
1217
- private _transition;
1176
+ //#region src/events/event-constants.d.ts
1177
+ /** PACKAGE_RULES rule 12: `package:resource.verb`. */
1178
+ declare const CRM_EVENTS: {
1179
+ readonly LEAD_CREATED: "crm:lead.created";
1180
+ readonly LEAD_STATUS_CHANGED: "crm:lead.status_changed";
1181
+ readonly LEAD_SCORED: "crm:lead.scored";
1182
+ readonly LEAD_CONVERTED: "crm:lead.converted";
1183
+ readonly LEAD_DISQUALIFIED: "crm:lead.disqualified";
1184
+ readonly ACCOUNT_CREATED: "crm:account.created";
1185
+ readonly ACCOUNT_UPDATED: "crm:account.updated";
1186
+ readonly CONTACT_CREATED: "crm:contact.created";
1187
+ readonly CONTACT_UPDATED: "crm:contact.updated";
1188
+ readonly OPPORTUNITY_CREATED: "crm:opportunity.created";
1189
+ readonly OPPORTUNITY_STAGE_ADVANCED: "crm:opportunity.stage_advanced";
1190
+ readonly OPPORTUNITY_STAGE_REGRESSED: "crm:opportunity.stage_regressed";
1191
+ readonly OPPORTUNITY_WON: "crm:opportunity.won";
1192
+ readonly OPPORTUNITY_LOST: "crm:opportunity.lost";
1193
+ readonly OPPORTUNITY_ABANDONED: "crm:opportunity.abandoned";
1194
+ readonly PIPELINE_CREATED: "crm:pipeline.created";
1195
+ readonly PIPELINE_ARCHIVED: "crm:pipeline.archived";
1196
+ readonly ACTIVITY_PLANNED: "crm:activity.planned";
1197
+ readonly ACTIVITY_COMPLETED: "crm:activity.completed";
1198
+ readonly ACTIVITY_CANCELLED: "crm:activity.cancelled";
1199
+ readonly NOTE_ADDED: "crm:note.added";
1200
+ readonly CAMPAIGN_CREATED: "crm:campaign.created";
1201
+ readonly CAMPAIGN_ACTIVATED: "crm:campaign.activated";
1202
+ readonly CAMPAIGN_PAUSED: "crm:campaign.paused";
1203
+ readonly CAMPAIGN_RESUMED: "crm:campaign.resumed";
1204
+ readonly CAMPAIGN_COMPLETED: "crm:campaign.completed";
1205
+ readonly CAMPAIGN_ARCHIVED: "crm:campaign.archived";
1206
+ readonly SUBSCRIPTION_CREATED: "crm:subscription.created";
1207
+ readonly SUBSCRIPTION_CONFIRMED: "crm:subscription.confirmed";
1208
+ readonly SUBSCRIPTION_UNSUBSCRIBED: "crm:subscription.unsubscribed";
1209
+ readonly SUBSCRIPTION_BOUNCED: "crm:subscription.bounced";
1210
+ readonly SUBSCRIPTION_COMPLAINED: "crm:subscription.complained";
1211
+ readonly EMAIL_EVENT_OPENED: "crm:email_event.opened";
1212
+ readonly EMAIL_EVENT_CLICKED: "crm:email_event.clicked";
1213
+ readonly EMAIL_EVENT_BOUNCED: "crm:email_event.bounced";
1214
+ readonly EMAIL_EVENT_COMPLAINED: "crm:email_event.complained";
1215
+ readonly EMAIL_EVENT_UNSUBSCRIBED: "crm:email_event.unsubscribed";
1216
+ readonly LEAD_ENRICHED: "crm:lead.enriched";
1217
+ readonly LEAD_ASSIGNED: "crm:lead.assigned";
1218
+ readonly CONTACT_ENRICHED: "crm:contact.enriched";
1219
+ readonly CONTACT_ASSIGNED: "crm:contact.assigned";
1220
+ readonly CONTACT_MERGED: "crm:contact.merged";
1221
+ readonly ACCOUNT_ENRICHED: "crm:account.enriched";
1222
+ readonly ACCOUNT_ASSIGNED: "crm:account.assigned";
1223
+ readonly ACCOUNT_MERGED: "crm:account.merged";
1224
+ readonly OPPORTUNITY_ASSIGNED: "crm:opportunity.assigned";
1225
+ readonly OPPORTUNITY_AMOUNT_CHANGED: "crm:opportunity.amount_changed";
1226
+ readonly OPPORTUNITY_EXTENDED: "crm:opportunity.extended";
1227
+ readonly ACTIVITY_RESCHEDULED: "crm:activity.rescheduled";
1228
+ readonly ACTIVITY_OUTCOME_RECORDED: "crm:activity.outcome_recorded";
1229
+ readonly CONVERSATION_CREATED: "crm:conversation.created";
1230
+ readonly CONVERSATION_ASSIGNED: "crm:conversation.assigned";
1231
+ readonly CONVERSATION_RESOLVED: "crm:conversation.resolved";
1232
+ readonly CONVERSATION_REOPENED: "crm:conversation.reopened";
1233
+ readonly MESSAGE_RECEIVED: "crm:message.received";
1234
+ readonly MESSAGE_SENT: "crm:message.sent";
1235
+ };
1236
+ type CrmEventName = (typeof CRM_EVENTS)[keyof typeof CRM_EVENTS];
1237
+ //#endregion
1238
+ //#region src/events/event-catalog.d.ts
1239
+ /** JSON-Schema object produced by `z.toJSONSchema` — what arc's registry consumes. */
1240
+ type CrmEventSchema = Record<string, unknown>;
1241
+ /** Structurally identical to arc's `EventDefinitionOutput` — do NOT import arc. */
1242
+ interface CrmEventDefinition<TSchema extends z.ZodType = z.ZodType> {
1243
+ name: CrmEventName;
1244
+ version: number;
1245
+ description: string;
1246
+ zodSchema: TSchema;
1247
+ schema: CrmEventSchema;
1248
+ create(payload: z.infer<TSchema>, meta?: Partial<EventMeta>): DomainEvent<z.infer<TSchema>>;
1218
1249
  }
1250
+ declare const LeadCreated: CrmEventDefinition<z.ZodObject<{
1251
+ leadId: z.ZodString;
1252
+ email: z.ZodOptional<z.ZodString>;
1253
+ score: z.ZodNumber;
1254
+ }, z.core.$strip>>;
1255
+ declare const LeadStatusChanged: CrmEventDefinition<z.ZodObject<{
1256
+ leadId: z.ZodString;
1257
+ from: z.ZodString;
1258
+ to: z.ZodString;
1259
+ }, z.core.$strip>>;
1260
+ declare const LeadScored: CrmEventDefinition<z.ZodObject<{
1261
+ leadId: z.ZodString;
1262
+ score: z.ZodNumber;
1263
+ }, z.core.$strip>>;
1264
+ declare const LeadConverted: CrmEventDefinition<z.ZodObject<{
1265
+ leadId: z.ZodString;
1266
+ contactId: z.ZodString;
1267
+ accountId: z.ZodOptional<z.ZodString>;
1268
+ opportunityId: z.ZodString;
1269
+ }, z.core.$strip>>;
1270
+ declare const LeadDisqualified: CrmEventDefinition<z.ZodObject<{
1271
+ leadId: z.ZodString;
1272
+ reason: z.ZodString;
1273
+ }, z.core.$strip>>;
1274
+ declare const LeadEnriched: CrmEventDefinition<z.ZodObject<{
1275
+ leadId: z.ZodString;
1276
+ fields: z.ZodArray<z.ZodString>;
1277
+ provider: z.ZodOptional<z.ZodString>;
1278
+ }, z.core.$strip>>;
1279
+ declare const LeadAssigned: CrmEventDefinition<z.ZodObject<{
1280
+ leadId: z.ZodString;
1281
+ ownerId: z.ZodString;
1282
+ previousOwnerId: z.ZodOptional<z.ZodString>;
1283
+ }, z.core.$strip>>;
1284
+ declare const AccountCreated: CrmEventDefinition<z.ZodObject<{
1285
+ accountId: z.ZodString;
1286
+ name: z.ZodString;
1287
+ }, z.core.$strip>>;
1288
+ declare const AccountUpdated: CrmEventDefinition<z.ZodObject<{
1289
+ accountId: z.ZodString;
1290
+ }, z.core.$strip>>;
1291
+ declare const AccountEnriched: CrmEventDefinition<z.ZodObject<{
1292
+ accountId: z.ZodString;
1293
+ fields: z.ZodArray<z.ZodString>;
1294
+ provider: z.ZodOptional<z.ZodString>;
1295
+ }, z.core.$strip>>;
1296
+ declare const AccountAssigned: CrmEventDefinition<z.ZodObject<{
1297
+ accountId: z.ZodString;
1298
+ ownerId: z.ZodString;
1299
+ previousOwnerId: z.ZodOptional<z.ZodString>;
1300
+ }, z.core.$strip>>;
1301
+ declare const AccountMerged: CrmEventDefinition<z.ZodObject<{
1302
+ primaryId: z.ZodString;
1303
+ secondaryId: z.ZodString;
1304
+ strategy: z.ZodEnum<{
1305
+ preferPrimary: "preferPrimary";
1306
+ preferSecondary: "preferSecondary";
1307
+ }>;
1308
+ }, z.core.$strip>>;
1309
+ declare const ContactCreated: CrmEventDefinition<z.ZodObject<{
1310
+ contactId: z.ZodString;
1311
+ email: z.ZodOptional<z.ZodString>;
1312
+ }, z.core.$strip>>;
1313
+ declare const ContactUpdated: CrmEventDefinition<z.ZodObject<{
1314
+ contactId: z.ZodString;
1315
+ }, z.core.$strip>>;
1316
+ declare const ContactEnriched: CrmEventDefinition<z.ZodObject<{
1317
+ contactId: z.ZodString;
1318
+ fields: z.ZodArray<z.ZodString>;
1319
+ provider: z.ZodOptional<z.ZodString>;
1320
+ }, z.core.$strip>>;
1321
+ declare const ContactAssigned: CrmEventDefinition<z.ZodObject<{
1322
+ contactId: z.ZodString;
1323
+ ownerId: z.ZodString;
1324
+ previousOwnerId: z.ZodOptional<z.ZodString>;
1325
+ }, z.core.$strip>>;
1326
+ declare const ContactMerged: CrmEventDefinition<z.ZodObject<{
1327
+ primaryId: z.ZodString;
1328
+ secondaryId: z.ZodString;
1329
+ strategy: z.ZodEnum<{
1330
+ preferPrimary: "preferPrimary";
1331
+ preferSecondary: "preferSecondary";
1332
+ }>;
1333
+ }, z.core.$strip>>;
1334
+ declare const OpportunityCreated: CrmEventDefinition<z.ZodObject<{
1335
+ opportunityId: z.ZodString;
1336
+ pipelineId: z.ZodString;
1337
+ stageId: z.ZodString;
1338
+ }, z.core.$strip>>;
1339
+ declare const OpportunityStageAdvanced: CrmEventDefinition<z.ZodObject<{
1340
+ opportunityId: z.ZodString;
1341
+ from: z.ZodObject<{
1342
+ stageId: z.ZodString;
1343
+ sequence: z.ZodNumber;
1344
+ }, z.core.$strip>;
1345
+ to: z.ZodObject<{
1346
+ stageId: z.ZodString;
1347
+ sequence: z.ZodNumber;
1348
+ }, z.core.$strip>;
1349
+ }, z.core.$strip>>;
1350
+ declare const OpportunityStageRegressed: CrmEventDefinition<z.ZodObject<{
1351
+ opportunityId: z.ZodString;
1352
+ from: z.ZodObject<{
1353
+ stageId: z.ZodString;
1354
+ sequence: z.ZodNumber;
1355
+ }, z.core.$strip>;
1356
+ to: z.ZodObject<{
1357
+ stageId: z.ZodString;
1358
+ sequence: z.ZodNumber;
1359
+ }, z.core.$strip>;
1360
+ }, z.core.$strip>>;
1361
+ declare const OpportunityWon: CrmEventDefinition<z.ZodObject<{
1362
+ opportunityId: z.ZodString;
1363
+ amount: z.ZodOptional<z.ZodNumber>;
1364
+ }, z.core.$strip>>;
1365
+ declare const OpportunityLost: CrmEventDefinition<z.ZodObject<{
1366
+ opportunityId: z.ZodString;
1367
+ lostReasonId: z.ZodOptional<z.ZodString>;
1368
+ }, z.core.$strip>>;
1369
+ declare const OpportunityAbandoned: CrmEventDefinition<z.ZodObject<{
1370
+ opportunityId: z.ZodString;
1371
+ }, z.core.$strip>>;
1372
+ declare const OpportunityAssigned: CrmEventDefinition<z.ZodObject<{
1373
+ opportunityId: z.ZodString;
1374
+ ownerId: z.ZodString;
1375
+ previousOwnerId: z.ZodOptional<z.ZodString>;
1376
+ }, z.core.$strip>>;
1377
+ declare const OpportunityAmountChanged: CrmEventDefinition<z.ZodObject<{
1378
+ opportunityId: z.ZodString;
1379
+ amount: z.ZodNumber;
1380
+ previousAmount: z.ZodOptional<z.ZodNumber>;
1381
+ reason: z.ZodOptional<z.ZodString>;
1382
+ by: z.ZodOptional<z.ZodString>;
1383
+ }, z.core.$strip>>;
1384
+ declare const OpportunityExtended: CrmEventDefinition<z.ZodObject<{
1385
+ opportunityId: z.ZodString;
1386
+ expectedCloseAt: z.ZodISODateTime;
1387
+ previousExpectedCloseAt: z.ZodOptional<z.ZodISODateTime>;
1388
+ reason: z.ZodOptional<z.ZodString>;
1389
+ by: z.ZodOptional<z.ZodString>;
1390
+ }, z.core.$strip>>;
1391
+ declare const PipelineCreated: CrmEventDefinition<z.ZodObject<{
1392
+ pipelineId: z.ZodString;
1393
+ }, z.core.$strip>>;
1394
+ declare const PipelineArchived: CrmEventDefinition<z.ZodObject<{
1395
+ pipelineId: z.ZodString;
1396
+ }, z.core.$strip>>;
1397
+ declare const ActivityPlanned: CrmEventDefinition<z.ZodObject<{
1398
+ activityId: z.ZodString;
1399
+ type: z.ZodString;
1400
+ subjectKind: z.ZodString;
1401
+ subjectId: z.ZodString;
1402
+ }, z.core.$strip>>;
1403
+ declare const ActivityCompleted: CrmEventDefinition<z.ZodObject<{
1404
+ activityId: z.ZodString;
1405
+ completedAt: z.ZodISODateTime;
1406
+ }, z.core.$strip>>;
1407
+ declare const ActivityCancelled: CrmEventDefinition<z.ZodObject<{
1408
+ activityId: z.ZodString;
1409
+ reason: z.ZodOptional<z.ZodString>;
1410
+ }, z.core.$strip>>;
1411
+ declare const ActivityRescheduled: CrmEventDefinition<z.ZodObject<{
1412
+ activityId: z.ZodString;
1413
+ dueDate: z.ZodISODateTime;
1414
+ previousDueDate: z.ZodOptional<z.ZodISODateTime>;
1415
+ reason: z.ZodOptional<z.ZodString>;
1416
+ by: z.ZodOptional<z.ZodString>;
1417
+ }, z.core.$strip>>;
1418
+ declare const ActivityOutcomeRecorded: CrmEventDefinition<z.ZodObject<{
1419
+ activityId: z.ZodString;
1420
+ outcome: z.ZodRecord<z.ZodString, z.ZodUnknown>;
1421
+ }, z.core.$strip>>;
1422
+ declare const NoteAdded: CrmEventDefinition<z.ZodObject<{
1423
+ noteId: z.ZodString;
1424
+ subjectKind: z.ZodString;
1425
+ subjectId: z.ZodString;
1426
+ }, z.core.$strip>>;
1427
+ declare const CampaignCreated: CrmEventDefinition<z.ZodObject<{
1428
+ campaignId: z.ZodString;
1429
+ name: z.ZodString;
1430
+ }, z.core.$strip>>;
1431
+ declare const CampaignActivated: CrmEventDefinition<z.ZodObject<{
1432
+ campaignId: z.ZodString;
1433
+ }, z.core.$strip>>;
1434
+ declare const CampaignPaused: CrmEventDefinition<z.ZodObject<{
1435
+ campaignId: z.ZodString;
1436
+ reason: z.ZodOptional<z.ZodString>;
1437
+ }, z.core.$strip>>;
1438
+ declare const CampaignResumed: CrmEventDefinition<z.ZodObject<{
1439
+ campaignId: z.ZodString;
1440
+ }, z.core.$strip>>;
1441
+ declare const CampaignCompleted: CrmEventDefinition<z.ZodObject<{
1442
+ campaignId: z.ZodString;
1443
+ actualRevenueAmount: z.ZodOptional<z.ZodNumber>;
1444
+ }, z.core.$strip>>;
1445
+ declare const CampaignArchived: CrmEventDefinition<z.ZodObject<{
1446
+ campaignId: z.ZodString;
1447
+ }, z.core.$strip>>;
1448
+ declare const SubscriptionCreated: CrmEventDefinition<z.ZodObject<{
1449
+ subscriptionId: z.ZodString;
1450
+ contactId: z.ZodString;
1451
+ campaignId: z.ZodString;
1452
+ requiresConfirmation: z.ZodBoolean;
1453
+ }, z.core.$strip>>;
1454
+ declare const SubscriptionConfirmed: CrmEventDefinition<z.ZodObject<{
1455
+ subscriptionId: z.ZodString;
1456
+ contactId: z.ZodString;
1457
+ campaignId: z.ZodString;
1458
+ confirmedAt: z.ZodISODateTime;
1459
+ }, z.core.$strip>>;
1460
+ declare const SubscriptionUnsubscribed: CrmEventDefinition<z.ZodObject<{
1461
+ subscriptionId: z.ZodString;
1462
+ contactId: z.ZodString;
1463
+ campaignId: z.ZodString;
1464
+ reason: z.ZodOptional<z.ZodString>;
1465
+ }, z.core.$strip>>;
1466
+ declare const SubscriptionBounced: CrmEventDefinition<z.ZodObject<{
1467
+ subscriptionId: z.ZodString;
1468
+ contactId: z.ZodString;
1469
+ campaignId: z.ZodString;
1470
+ reason: z.ZodOptional<z.ZodString>;
1471
+ }, z.core.$strip>>;
1472
+ declare const SubscriptionComplained: CrmEventDefinition<z.ZodObject<{
1473
+ subscriptionId: z.ZodString;
1474
+ contactId: z.ZodString;
1475
+ campaignId: z.ZodString;
1476
+ }, z.core.$strip>>;
1477
+ declare const EmailEventOpened: CrmEventDefinition<z.ZodObject<{
1478
+ eventId: z.ZodString;
1479
+ kind: z.ZodString;
1480
+ subjectKind: z.ZodString;
1481
+ subjectId: z.ZodString;
1482
+ campaignId: z.ZodOptional<z.ZodString>;
1483
+ }, z.core.$strip>>;
1484
+ declare const EmailEventClicked: CrmEventDefinition<z.ZodObject<{
1485
+ eventId: z.ZodString;
1486
+ kind: z.ZodString;
1487
+ subjectKind: z.ZodString;
1488
+ subjectId: z.ZodString;
1489
+ campaignId: z.ZodOptional<z.ZodString>;
1490
+ }, z.core.$strip>>;
1491
+ declare const EmailEventBounced: CrmEventDefinition<z.ZodObject<{
1492
+ eventId: z.ZodString;
1493
+ kind: z.ZodString;
1494
+ subjectKind: z.ZodString;
1495
+ subjectId: z.ZodString;
1496
+ campaignId: z.ZodOptional<z.ZodString>;
1497
+ }, z.core.$strip>>;
1498
+ declare const EmailEventComplained: CrmEventDefinition<z.ZodObject<{
1499
+ eventId: z.ZodString;
1500
+ kind: z.ZodString;
1501
+ subjectKind: z.ZodString;
1502
+ subjectId: z.ZodString;
1503
+ campaignId: z.ZodOptional<z.ZodString>;
1504
+ }, z.core.$strip>>;
1505
+ declare const EmailEventUnsubscribed: CrmEventDefinition<z.ZodObject<{
1506
+ eventId: z.ZodString;
1507
+ kind: z.ZodString;
1508
+ subjectKind: z.ZodString;
1509
+ subjectId: z.ZodString;
1510
+ campaignId: z.ZodOptional<z.ZodString>;
1511
+ }, z.core.$strip>>;
1512
+ declare const ConversationCreated: CrmEventDefinition<z.ZodObject<{
1513
+ conversationId: z.ZodString;
1514
+ channel: z.ZodString;
1515
+ participantKind: z.ZodString;
1516
+ participantId: z.ZodString;
1517
+ }, z.core.$strip>>;
1518
+ declare const ConversationAssigned: CrmEventDefinition<z.ZodObject<{
1519
+ conversationId: z.ZodString;
1520
+ assigneeId: z.ZodString;
1521
+ previousAssigneeId: z.ZodOptional<z.ZodString>;
1522
+ }, z.core.$strip>>;
1523
+ declare const ConversationResolved: CrmEventDefinition<z.ZodObject<{
1524
+ conversationId: z.ZodString;
1525
+ status: z.ZodString;
1526
+ previousStatus: z.ZodString;
1527
+ }, z.core.$strip>>;
1528
+ declare const ConversationReopened: CrmEventDefinition<z.ZodObject<{
1529
+ conversationId: z.ZodString;
1530
+ status: z.ZodString;
1531
+ previousStatus: z.ZodString;
1532
+ }, z.core.$strip>>;
1533
+ declare const MessageReceived: CrmEventDefinition<z.ZodObject<{
1534
+ messageId: z.ZodString;
1535
+ conversationId: z.ZodString;
1536
+ direction: z.ZodString;
1537
+ externalMessageId: z.ZodOptional<z.ZodString>;
1538
+ }, z.core.$strip>>;
1539
+ declare const MessageSent: CrmEventDefinition<z.ZodObject<{
1540
+ messageId: z.ZodString;
1541
+ conversationId: z.ZodString;
1542
+ direction: z.ZodString;
1543
+ externalMessageId: z.ZodOptional<z.ZodString>;
1544
+ }, z.core.$strip>>;
1545
+ declare const crmEventDefinitions: ReadonlyArray<CrmEventDefinition>;
1219
1546
  //#endregion
1220
- //#region src/repositories/activity.repository.d.ts
1221
- interface ActivityRepositoryDeps {
1222
- events: EventTransport;
1223
- }
1224
- declare class ActivityRepository extends Repository<IActivityDocument> {
1225
- private readonly events;
1226
- constructor(model: Model<IActivityDocument>, plugins: PluginType[], deps: ActivityRepositoryDeps, pagination?: PaginationConfig);
1227
- plan(input: Partial<IActivityDocument>, ctx?: CrmContext): Promise<IActivityDocument>;
1228
- start(id: string, ctx?: CrmContext): Promise<IActivityDocument>;
1229
- complete(id: string, completedAt?: Date, ctx?: CrmContext): Promise<IActivityDocument>;
1230
- cancel(id: string, reason?: string, ctx?: CrmContext): Promise<IActivityDocument>;
1231
- /**
1232
- * Push an activity's `dueDate`. Allowed on planned / in_progress only;
1233
- * rescheduling a completed or cancelled activity makes no sense.
1234
- * Emits `crm:activity.rescheduled` with the previous date for audit.
1235
- */
1236
- reschedule(id: string, newDueDate: Date, extras?: {
1237
- reason?: string;
1238
- by?: string;
1239
- }, ctx?: CrmContext): Promise<IActivityDocument>;
1240
- /**
1241
- * Record the outcome of an activity (call result, email engagement,
1242
- * meeting confirmation). Stored under `metadata.outcome` so it stays
1243
- * polymorphic — the shape is the channel's concern, not this package's.
1244
- *
1245
- * Does NOT transition status — call `complete()` separately when the
1246
- * outcome implies completion. This split lets agents log partial
1247
- * outcomes (e.g. "left voicemail") without forcing terminal state.
1248
- */
1249
- recordOutcome(id: string, outcome: Record<string, unknown>, ctx?: CrmContext): Promise<IActivityDocument>;
1250
- private _transition;
1251
- /** Count `planned` activities with `dueDate` before `asOf`. Dashboard KPI. */
1252
- countOverduePlanned(asOf: Date, ctx?: CrmContext): Promise<number>;
1253
- /** Latest `limit` activities — lightweight projection for the activity feed. */
1254
- findRecentForFeed(limit: number, ctx?: CrmContext): Promise<IActivityDocument[]>;
1255
- }
1547
+ //#region src/events/helpers.d.ts
1548
+ declare function createEvent<T>(type: string, payload: T, ctx?: CrmContext, meta?: Partial<EventMeta>): DomainEvent<T>;
1256
1549
  //#endregion
1257
- //#region src/repositories/note.repository.d.ts
1258
- interface NoteRepositoryDeps {
1259
- events: EventTransport;
1260
- }
1261
- declare class NoteRepository extends Repository<INoteDocument> {
1262
- private readonly events;
1263
- constructor(model: Model<INoteDocument>, plugins: PluginType[], deps: NoteRepositoryDeps, pagination?: PaginationConfig);
1264
- addNote(input: Partial<INoteDocument>, ctx?: CrmContext): Promise<INoteDocument>;
1550
+ //#region src/events/in-process-bus.d.ts
1551
+ declare class InProcessCrmBus implements EventTransport {
1552
+ readonly name = "in-process-crm";
1553
+ private subs;
1554
+ private logger?;
1555
+ constructor(options?: {
1556
+ logger?: CrmLogger;
1557
+ });
1558
+ publish(event: DomainEvent): Promise<void>;
1559
+ subscribe(pattern: string, handler: EventHandler): Promise<() => void>;
1560
+ close(): Promise<void>;
1265
1561
  }
1266
1562
  //#endregion
1267
- //#region src/repositories/loss-reason.repository.d.ts
1268
- interface LossReasonRepositoryDeps {
1269
- events: EventTransport;
1270
- }
1271
- declare class LossReasonRepository extends Repository<ILossReasonDocument> {
1272
- private readonly events;
1273
- constructor(model: Model<ILossReasonDocument>, plugins: PluginType[], deps: LossReasonRepositoryDeps, pagination?: PaginationConfig);
1274
- /** Hide from pickers without breaking historical FKs. */
1275
- archive(id: string, ctx?: CrmContext): Promise<ILossReasonDocument>;
1276
- }
1563
+ //#region src/core/state-machines.d.ts
1564
+ /**
1565
+ * Declarative state machines for every CRM aggregate that has lifecycle
1566
+ * transitions. Single source of truth for what `from -> to` moves are
1567
+ * legal — the repositories' domain verbs (`qualify`, `convert`, `win`,
1568
+ * `lose`, `confirm`, `unsubscribe`, ...) call `assertTransition` before
1569
+ * they touch Mongo.
1570
+ *
1571
+ * Per PACKAGE_RULES §30: "State machines map to Arc Actions". The host
1572
+ * exposes each domain verb as an arc Action (`POST /:id/action` with
1573
+ * `{ action: 'qualify' }`); the verb's implementation lives on the
1574
+ * Repository class and uses these machines internally.
1575
+ *
1576
+ * Built on `@classytic/primitives/state-machine` so the same shape lights
1577
+ * up across kits (mongokit's `claim()` pairing, sqlitekit follow-ups).
1578
+ */
1579
+ declare const LEAD_MACHINE: _$_classytic_primitives_state_machine0.StateMachine<"new" | "contacted" | "qualified" | "converted" | "disqualified" | "nurturing">;
1580
+ declare const OPPORTUNITY_MACHINE: _$_classytic_primitives_state_machine0.StateMachine<"open" | "won" | "lost" | "abandoned">;
1581
+ declare const CAMPAIGN_MACHINE: _$_classytic_primitives_state_machine0.StateMachine<"draft" | "active" | "paused" | "completed" | "archived">;
1582
+ declare const SUBSCRIPTION_MACHINE: _$_classytic_primitives_state_machine0.StateMachine<"pending" | "confirmed" | "unsubscribed" | "bounced" | "complained">;
1583
+ declare const ACTIVITY_MACHINE: _$_classytic_primitives_state_machine0.StateMachine<"completed" | "planned" | "in_progress" | "cancelled">;
1277
1584
  //#endregion
1278
- //#region src/repositories/email-event.repository.d.ts
1279
- interface EmailEventRepositoryDeps {
1280
- events: EventTransport;
1585
+ //#region src/core/errors.d.ts
1586
+ /**
1587
+ * CRM error vocabulary. Hosts catch `CrmError` at API edges.
1588
+ */
1589
+ declare class CrmError extends Error {
1590
+ readonly code: string;
1591
+ readonly details?: Record<string, unknown>;
1592
+ constructor(code: string, message: string, details?: Record<string, unknown>);
1593
+ }
1594
+ declare class NotFoundError extends CrmError {
1595
+ constructor(kind: string, id: string);
1596
+ }
1597
+ declare class InvalidLeadTransitionError extends CrmError {
1598
+ constructor(details: {
1599
+ from: string;
1600
+ to: string;
1601
+ leadId: string;
1602
+ });
1281
1603
  }
1282
- interface RecordEmailEventInput {
1283
- subjectKind: EmailEventSubjectKind;
1284
- subjectId: string;
1285
- campaignId?: string;
1286
- messageId?: string;
1287
- url?: string;
1288
- userAgent?: string;
1289
- ip?: string;
1290
- metadata?: Record<string, unknown>;
1604
+ declare class InvalidOpportunityTransitionError extends CrmError {
1605
+ constructor(details: {
1606
+ from: string;
1607
+ to: string;
1608
+ opportunityId: string;
1609
+ });
1291
1610
  }
1292
- declare class EmailEventRepository extends Repository<IEmailEventDocument> {
1293
- private readonly events;
1294
- constructor(model: Model<IEmailEventDocument>, plugins: PluginType[], deps: EmailEventRepositoryDeps, pagination?: PaginationConfig);
1295
- recordOpen(input: RecordEmailEventInput, ctx?: CrmContext): Promise<IEmailEventDocument>;
1296
- recordClick(input: RecordEmailEventInput, ctx?: CrmContext): Promise<IEmailEventDocument>;
1297
- recordBounce(input: RecordEmailEventInput, ctx?: CrmContext): Promise<IEmailEventDocument>;
1298
- recordComplaint(input: RecordEmailEventInput, ctx?: CrmContext): Promise<IEmailEventDocument>;
1299
- recordUnsubscribe(input: RecordEmailEventInput, ctx?: CrmContext): Promise<IEmailEventDocument>;
1300
- private _record;
1611
+ declare class InvalidActivityTransitionError extends CrmError {
1612
+ constructor(details: {
1613
+ from: string;
1614
+ to: string;
1615
+ activityId: string;
1616
+ });
1301
1617
  }
1302
- //#endregion
1303
- //#region src/repositories/conversation.repository.d.ts
1304
- interface ConversationRepositoryDeps {
1305
- events: EventTransport;
1618
+ declare class StageNotInPipelineError extends CrmError {
1619
+ constructor(details: {
1620
+ pipelineId: string;
1621
+ stageId: string;
1622
+ });
1306
1623
  }
1307
- interface OpenConversationInput {
1308
- channel: ConversationChannel;
1309
- participantKind: ConversationParticipantKind;
1310
- participantId: string;
1311
- channelUserId?: string;
1312
- assigneeId?: string;
1313
- metadata?: Record<string, unknown>;
1624
+ declare class LeadAlreadyConvertedError extends CrmError {
1625
+ constructor(leadId: string);
1314
1626
  }
1315
- declare class ConversationRepository extends Repository<IConversationDocument> {
1316
- private readonly events;
1317
- constructor(model: Model<IConversationDocument>, plugins: PluginType[], deps: ConversationRepositoryDeps, pagination?: PaginationConfig);
1318
- openConversation(input: OpenConversationInput, ctx?: CrmContext): Promise<IConversationDocument>;
1319
- assign(id: string, assigneeId: string, ctx?: CrmContext): Promise<IConversationDocument>;
1320
- resolve(id: string, ctx?: CrmContext): Promise<IConversationDocument>;
1321
- reopen(id: string, ctx?: CrmContext): Promise<IConversationDocument>;
1322
- /** Reset unread badge. Pure UI affordance, no event. */
1323
- markRead(id: string, ctx?: CrmContext): Promise<IConversationDocument>;
1324
- /**
1325
- * Bump `lastMessageAt` and (for inbound) increment `unreadCount`.
1326
- * Called by `MessageRepository` when a message is recorded — not part
1327
- * of the public surface. Returns the conversation for the caller's
1328
- * follow-up writes.
1329
- */
1330
- touch(id: string, args: {
1331
- direction: 'inbound' | 'outbound';
1332
- sentAt: Date;
1333
- }, ctx?: CrmContext): Promise<IConversationDocument | null>;
1334
- private _setStatus;
1627
+ declare class DuplicateLeadError extends CrmError {
1628
+ constructor(details: {
1629
+ email?: string;
1630
+ phone?: string;
1631
+ });
1335
1632
  }
1336
- //#endregion
1337
- //#region src/repositories/message.repository.d.ts
1338
- interface MessageRepositoryDeps {
1339
- events: EventTransport;
1340
- conversations: ConversationRepository;
1633
+ declare class EmptyPipelineError extends CrmError {
1634
+ constructor(pipelineId: string);
1341
1635
  }
1342
- interface RecordMessageInput {
1343
- conversationId: string;
1344
- body: string;
1345
- attachments?: IMessageAttachment[];
1346
- externalMessageId?: string;
1347
- senderRef?: string;
1348
- recipientRef?: string;
1349
- sentAt?: Date;
1350
- metadata?: Record<string, unknown>;
1636
+ declare class InvalidCampaignTransitionError extends CrmError {
1637
+ constructor(details: {
1638
+ from: string;
1639
+ to: string;
1640
+ campaignId: string;
1641
+ });
1351
1642
  }
1352
- declare class MessageRepository extends Repository<IMessageDocument> {
1353
- private readonly events;
1354
- private readonly conversations;
1355
- constructor(model: Model<IMessageDocument>, plugins: PluginType[], deps: MessageRepositoryDeps, pagination?: PaginationConfig);
1356
- recordInbound(input: RecordMessageInput, ctx?: CrmContext): Promise<IMessageDocument>;
1357
- recordOutbound(input: RecordMessageInput, ctx?: CrmContext): Promise<IMessageDocument>;
1358
- /** Wire delivery callback (e.g. WhatsApp `status` webhook). */
1359
- updateStatus(id: string, status: MessageDeliveryStatus, ctx?: CrmContext): Promise<IMessageDocument>;
1360
- private _record;
1361
- /** Latest `limit` messages — lightweight projection for the activity feed. */
1362
- findRecentForFeed(limit: number, ctx?: CrmContext): Promise<IMessageDocument[]>;
1643
+ declare class DuplicateCampaignError extends CrmError {
1644
+ constructor(name: string);
1363
1645
  }
1364
- //#endregion
1365
- //#region src/engine/engine-types.d.ts
1366
- interface CrmLogger {
1367
- info?(msg: string, meta?: Record<string, unknown>): void;
1368
- warn?(msg: string, meta?: Record<string, unknown>): void;
1369
- error?(msg: string, meta?: Record<string, unknown>): void;
1370
- debug?(msg: string, meta?: Record<string, unknown>): void;
1646
+ declare class InvalidSubscriptionTransitionError extends CrmError {
1647
+ constructor(details: {
1648
+ from: string;
1649
+ to: string;
1650
+ subscriptionId: string;
1651
+ });
1371
1652
  }
1372
- interface CrmConfig {
1373
- /** Mongoose connection — package creates models on this connection. */
1374
- connection: Connection;
1375
- /**
1376
- * Tenant column shape. `'objectId'` (default) matches Better Auth orgs
1377
- * and unlocks `$lookup` / `.populate()`; `'string'` matches UUID hosts.
1378
- * Threaded into both schemas and `multiTenantPlugin` so they stay in
1379
- * sync (PACKAGE_RULES §9.2).
1380
- */
1381
- tenantFieldType?: TenantFieldType;
1382
- /**
1383
- * When `true` (default), wire `multiTenantPlugin` on every repository
1384
- * with `required: true`. Set `false` only for fixtures / smoke tests
1385
- * that intentionally drop the scope.
1386
- */
1387
- multiTenant?: boolean;
1388
- /** Arc-compatible event transport. Default: in-process bus. */
1389
- eventTransport?: EventTransport;
1390
- /** Logger surface used by the in-process bus + repositories. */
1391
- logger?: CrmLogger;
1392
- /** Pagination defaults for every repository (mongokit). */
1393
- pagination?: PaginationConfig;
1394
- /** Extra mongokit plugins applied to every repository (after defaults). */
1395
- plugins?: PluginType[];
1396
- /**
1397
- * On a Mongoose model-name collision (another engine / hot reload owns
1398
- * the name): `false` (default) throws `CrmModelCollisionError`; `true`
1399
- * deletes + re-registers. Test fixtures / hot reload only (§21).
1400
- */
1401
- forceRecreate?: boolean;
1402
- /**
1403
- * Mongoose auto-index builds. Default `true` (dev). Set `false` in
1404
- * production and run `engine.syncIndexes()` from a deploy script so
1405
- * cold-boot index builds don't blow Fastify's plugin timeout (§35).
1406
- */
1407
- autoIndex?: boolean;
1408
- /**
1409
- * Skip the boot-time `transactions` capability requirement, downgrading
1410
- * it to a warning. Set only when the host never calls
1411
- * `LeadService.convert()` inside a transaction (standalone Mongo).
1412
- */
1413
- allowNonTransactional?: boolean;
1653
+ declare class DuplicateSubscriptionError extends CrmError {
1654
+ constructor(details: {
1655
+ contactId: string;
1656
+ campaignId: string;
1657
+ });
1414
1658
  }
1415
- interface ResolvedCrmConfig extends SchemaBuildConfig {
1416
- connection: Connection;
1417
- tenantFieldType: TenantFieldType;
1418
- multiTenant: boolean;
1419
- forceRecreate: boolean;
1420
- autoIndex: boolean;
1421
- logger?: CrmLogger;
1422
- pagination?: PaginationConfig;
1423
- plugins: PluginType[];
1659
+ declare class InvalidConfirmationTokenError extends CrmError {
1660
+ constructor();
1424
1661
  }
1425
- interface CrmRepositories {
1426
- pipeline: PipelineRepository;
1427
- lead: LeadRepository;
1428
- opportunity: OpportunityRepository;
1429
- contact: ContactRepository;
1430
- account: AccountRepository;
1431
- campaign: CampaignRepository;
1432
- subscription: SubscriptionRepository;
1433
- activity: ActivityRepository;
1434
- note: NoteRepository;
1435
- lossReason: LossReasonRepository;
1436
- emailEvent: EmailEventRepository;
1437
- conversation: ConversationRepository;
1438
- message: MessageRepository;
1662
+ declare class InvalidUnsubscribeTokenError extends CrmError {
1663
+ constructor();
1439
1664
  }
1440
- interface CrmEngine {
1441
- /** Repositories ARE the API surface (PACKAGE_RULES §1). */
1442
- readonly repositories: Readonly<CrmRepositories>;
1443
- /** Arc-compatible event transport. */
1444
- readonly events: EventTransport;
1445
- /** Mongoose models — for arc adapter wiring. */
1446
- readonly models: Readonly<CrmModels>;
1447
- /** Resolved configuration (frozen). */
1448
- readonly config: Readonly<ResolvedCrmConfig>;
1449
- /**
1450
- * Build/align every model's indexes against its schema. Call once per
1451
- * deploy when booted with `autoIndex: false` (§35). Idempotent.
1452
- */
1453
- syncIndexes(): Promise<void>;
1454
- /** Release resources. Safe to call multiple times. */
1455
- dispose(): Promise<void>;
1665
+ //#endregion
1666
+ //#region src/shared/calculators/forecast.d.ts
1667
+ type OpportunityForecast = Pick<IOpportunityDocument, 'amount' | 'currency' | 'probability' | 'status' | 'expectedCloseAt' | 'stageId' | 'statusHistory'>;
1668
+ interface ForecastRow {
1669
+ /** Bucket key — ISO month `YYYY-MM` by default. */
1670
+ bucket: string;
1671
+ /** Σ amount. */
1672
+ committed: number;
1673
+ /** Σ amount × probability. */
1674
+ weighted: number;
1675
+ /** Number of opportunities in the bucket. */
1676
+ count: number;
1677
+ currency: string;
1678
+ }
1679
+ interface ForecastOptions {
1680
+ /** Bucket function. Default: ISO month from `expectedCloseAt`. */
1681
+ bucket?: (o: OpportunityForecast) => string;
1682
+ /** Filter before bucketing. Default: open + has amount + has expectedCloseAt. */
1683
+ include?: (o: OpportunityForecast) => boolean;
1456
1684
  }
1457
1685
  /**
1458
- * Operation context threaded through every domain verb. Extends
1459
- * primitives' `OperationContext` and narrows `IdLike` to types Mongoose
1460
- * stores cleanly. Host-specific extras go through the inherited
1461
- * `metadata?` field — keep the typed surface tight.
1686
+ * Aggregate opportunities into a forecast table — one row per bucket.
1687
+ * Currency mismatch within a bucket throws — partition by currency
1688
+ * upstream when multi-currency.
1462
1689
  */
1463
- interface CrmContext extends OperationContext {
1464
- organizationId?: string | mongoose1.Types.ObjectId;
1465
- actorId?: string | mongoose1.Types.ObjectId;
1466
- /** Mongo transaction session (passed through to mongokit). */
1467
- session?: unknown;
1690
+ declare function forecast(opportunities: readonly OpportunityForecast[], options?: ForecastOptions): ForecastRow[];
1691
+ interface ConversionRow {
1692
+ stageId: string;
1693
+ currentCount: number;
1694
+ wonFromHere: number;
1695
+ lostFromHere: number;
1696
+ conversionRate: number;
1468
1697
  }
1469
- type _ModelTypes = Model<unknown>;
1698
+ /**
1699
+ * "Where do deals die?" summary — opportunities partitioned across
1700
+ * stages with current count + won/lost-from-here.
1701
+ */
1702
+ declare function pipelineConversion(opportunities: readonly OpportunityForecast[], stageIds: readonly string[]): ConversionRow[];
1470
1703
  //#endregion
1471
- //#region src/events/helpers.d.ts
1472
- declare function createEvent$1<T>(type: string, payload: T, ctx?: CrmContext, meta?: Partial<EventMeta>): DomainEvent<T>;
1704
+ //#region src/validators/common.d.ts
1705
+ declare const objectIdLike: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
1706
+ declare const metadataSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1707
+ declare const tagsSchema: z.ZodOptional<z.ZodArray<z.ZodString>>;
1708
+ declare const moneyAmountSchema: z.ZodNumber;
1709
+ declare const currencyCodeSchema: z.ZodString;
1473
1710
  //#endregion
1474
- //#region src/events/in-process-bus.d.ts
1475
- declare class InProcessCrmBus implements EventTransport {
1476
- readonly name = "in-process-crm";
1477
- private subs;
1478
- private logger?;
1479
- constructor(options?: {
1480
- logger?: CrmLogger;
1481
- });
1482
- publish(event: DomainEvent): Promise<void>;
1483
- subscribe(pattern: string, handler: EventHandler): Promise<() => void>;
1484
- close(): Promise<void>;
1711
+ //#region src/validators/pipeline.schema.d.ts
1712
+ declare const stageInputSchema: z.ZodObject<{
1713
+ name: z.ZodString;
1714
+ sequence: z.ZodNumber;
1715
+ defaultProbability: z.ZodNumber;
1716
+ color: z.ZodOptional<z.ZodString>;
1717
+ description: z.ZodOptional<z.ZodString>;
1718
+ }, z.core.$strip>;
1719
+ declare const createPipelineSchema: z.ZodObject<{
1720
+ name: z.ZodString;
1721
+ stages: z.ZodDefault<z.ZodArray<z.ZodObject<{
1722
+ name: z.ZodString;
1723
+ sequence: z.ZodNumber;
1724
+ defaultProbability: z.ZodNumber;
1725
+ color: z.ZodOptional<z.ZodString>;
1726
+ description: z.ZodOptional<z.ZodString>;
1727
+ }, z.core.$strip>>>;
1728
+ teamRef: z.ZodOptional<z.ZodString>;
1729
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1730
+ }, z.core.$strip>;
1731
+ declare const updatePipelineSchema: z.ZodObject<{
1732
+ name: z.ZodOptional<z.ZodString>;
1733
+ stages: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
1734
+ name: z.ZodString;
1735
+ sequence: z.ZodNumber;
1736
+ defaultProbability: z.ZodNumber;
1737
+ color: z.ZodOptional<z.ZodString>;
1738
+ description: z.ZodOptional<z.ZodString>;
1739
+ }, z.core.$strip>>>>;
1740
+ teamRef: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1741
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
1742
+ }, z.core.$strip>;
1743
+ declare const stageInputSchemaExport: z.ZodObject<{
1744
+ name: z.ZodString;
1745
+ sequence: z.ZodNumber;
1746
+ defaultProbability: z.ZodNumber;
1747
+ color: z.ZodOptional<z.ZodString>;
1748
+ description: z.ZodOptional<z.ZodString>;
1749
+ }, z.core.$strip>;
1750
+ declare const pipelineFilterSchema: z.ZodObject<{
1751
+ isArchived: z.ZodOptional<z.ZodCoercedBoolean<unknown>>;
1752
+ teamRef: z.ZodOptional<z.ZodString>;
1753
+ }, z.core.$strip>;
1754
+ type CreatePipelineDto = z.infer<typeof createPipelineSchema>;
1755
+ type UpdatePipelineDto = z.infer<typeof updatePipelineSchema>;
1756
+ type StageInputDto = z.infer<typeof stageInputSchema>;
1757
+ //#endregion
1758
+ //#region src/validators/lead.schema.d.ts
1759
+ declare const createLeadSchema: z.ZodObject<{
1760
+ fullName: z.ZodOptional<z.ZodString>;
1761
+ firstName: z.ZodOptional<z.ZodString>;
1762
+ lastName: z.ZodOptional<z.ZodString>;
1763
+ email: z.ZodOptional<z.ZodString>;
1764
+ phone: z.ZodOptional<z.ZodString>;
1765
+ companyName: z.ZodOptional<z.ZodString>;
1766
+ jobTitle: z.ZodOptional<z.ZodString>;
1767
+ source: z.ZodOptional<z.ZodString>;
1768
+ campaignRef: z.ZodOptional<z.ZodString>;
1769
+ ownerId: z.ZodOptional<z.ZodString>;
1770
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1771
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1772
+ }, z.core.$strip>;
1773
+ declare const updateLeadSchema: z.ZodObject<{
1774
+ fullName: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1775
+ firstName: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1776
+ lastName: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1777
+ email: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1778
+ phone: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1779
+ companyName: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1780
+ jobTitle: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1781
+ source: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1782
+ campaignRef: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1783
+ ownerId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1784
+ tags: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
1785
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
1786
+ }, z.core.$strip>;
1787
+ declare const leadFilterSchema: z.ZodObject<{
1788
+ status: z.ZodOptional<z.ZodEnum<{
1789
+ new: "new";
1790
+ contacted: "contacted";
1791
+ qualified: "qualified";
1792
+ converted: "converted";
1793
+ disqualified: "disqualified";
1794
+ nurturing: "nurturing";
1795
+ }>>;
1796
+ ownerId: z.ZodOptional<z.ZodString>;
1797
+ email: z.ZodOptional<z.ZodString>;
1798
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1799
+ source: z.ZodOptional<z.ZodString>;
1800
+ campaignRef: z.ZodOptional<z.ZodString>;
1801
+ scoreMin: z.ZodOptional<z.ZodNumber>;
1802
+ scoreMax: z.ZodOptional<z.ZodNumber>;
1803
+ }, z.core.$strip>;
1804
+ declare const convertLeadSchema: z.ZodObject<{
1805
+ pipelineId: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
1806
+ opportunityName: z.ZodOptional<z.ZodString>;
1807
+ amount: z.ZodOptional<z.ZodNumber>;
1808
+ currency: z.ZodOptional<z.ZodString>;
1809
+ expectedCloseAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
1810
+ by: z.ZodOptional<z.ZodString>;
1811
+ }, z.core.$strip>;
1812
+ type CreateLeadDto = z.infer<typeof createLeadSchema>;
1813
+ type UpdateLeadDto = z.infer<typeof updateLeadSchema>;
1814
+ type ConvertLeadDto = z.infer<typeof convertLeadSchema>;
1815
+ type LeadFilterDto = z.infer<typeof leadFilterSchema>;
1816
+ //#endregion
1817
+ //#region src/validators/opportunity.schema.d.ts
1818
+ declare const openOpportunitySchema: z.ZodObject<{
1819
+ name: z.ZodString;
1820
+ pipelineId: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
1821
+ stageId: z.ZodOptional<z.ZodString>;
1822
+ accountId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
1823
+ primaryContactId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
1824
+ sourceLeadId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
1825
+ amount: z.ZodOptional<z.ZodNumber>;
1826
+ currency: z.ZodOptional<z.ZodString>;
1827
+ probability: z.ZodOptional<z.ZodNumber>;
1828
+ expectedCloseAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
1829
+ ownerId: z.ZodOptional<z.ZodString>;
1830
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1831
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1832
+ }, z.core.$strip>;
1833
+ declare const moveStageSchema: z.ZodObject<{
1834
+ stageId: z.ZodString;
1835
+ by: z.ZodOptional<z.ZodString>;
1836
+ note: z.ZodOptional<z.ZodString>;
1837
+ probability: z.ZodOptional<z.ZodNumber>;
1838
+ }, z.core.$strip>;
1839
+ declare const closeWinSchema: z.ZodObject<{
1840
+ by: z.ZodOptional<z.ZodString>;
1841
+ note: z.ZodOptional<z.ZodString>;
1842
+ closedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
1843
+ amount: z.ZodOptional<z.ZodNumber>;
1844
+ }, z.core.$strip>;
1845
+ declare const closeLossSchema: z.ZodObject<{
1846
+ by: z.ZodOptional<z.ZodString>;
1847
+ note: z.ZodOptional<z.ZodString>;
1848
+ closedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
1849
+ lostReasonId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
1850
+ }, z.core.$strip>;
1851
+ declare const opportunityFilterSchema: z.ZodObject<{
1852
+ status: z.ZodOptional<z.ZodEnum<{
1853
+ open: "open";
1854
+ won: "won";
1855
+ lost: "lost";
1856
+ abandoned: "abandoned";
1857
+ }>>;
1858
+ pipelineId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
1859
+ stageId: z.ZodOptional<z.ZodString>;
1860
+ ownerId: z.ZodOptional<z.ZodString>;
1861
+ accountId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
1862
+ expectedCloseFrom: z.ZodOptional<z.ZodCoercedDate<unknown>>;
1863
+ expectedCloseTo: z.ZodOptional<z.ZodCoercedDate<unknown>>;
1864
+ }, z.core.$strip>;
1865
+ type OpenOpportunityDto = z.infer<typeof openOpportunitySchema>;
1866
+ type MoveStageDto = z.infer<typeof moveStageSchema>;
1867
+ type CloseWinDto = z.infer<typeof closeWinSchema>;
1868
+ type CloseLossDto = z.infer<typeof closeLossSchema>;
1869
+ type OpportunityFilterDto = z.infer<typeof opportunityFilterSchema>;
1870
+ //#endregion
1871
+ //#region src/validators/contact.schema.d.ts
1872
+ declare const createContactSchema: z.ZodObject<{
1873
+ name: z.ZodObject<{
1874
+ given: z.ZodString;
1875
+ family: z.ZodDefault<z.ZodString>;
1876
+ middle: z.ZodOptional<z.ZodString>;
1877
+ prefix: z.ZodOptional<z.ZodString>;
1878
+ suffix: z.ZodOptional<z.ZodString>;
1879
+ preferred: z.ZodOptional<z.ZodString>;
1880
+ }, z.core.$strip>;
1881
+ contact: z.ZodDefault<z.ZodObject<{
1882
+ email: z.ZodOptional<z.ZodString>;
1883
+ personalEmail: z.ZodOptional<z.ZodString>;
1884
+ phone: z.ZodOptional<z.ZodString>;
1885
+ alternatePhone: z.ZodOptional<z.ZodString>;
1886
+ whatsapp: z.ZodOptional<z.ZodString>;
1887
+ telegram: z.ZodOptional<z.ZodString>;
1888
+ linkedin: z.ZodOptional<z.ZodString>;
1889
+ instagram: z.ZodOptional<z.ZodString>;
1890
+ }, z.core.$strip>>;
1891
+ jobTitle: z.ZodOptional<z.ZodString>;
1892
+ accountId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
1893
+ ownerId: z.ZodOptional<z.ZodString>;
1894
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1895
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1896
+ }, z.core.$strip>;
1897
+ declare const updateContactSchema: z.ZodObject<{
1898
+ name: z.ZodOptional<z.ZodObject<{
1899
+ given: z.ZodString;
1900
+ family: z.ZodDefault<z.ZodString>;
1901
+ middle: z.ZodOptional<z.ZodString>;
1902
+ prefix: z.ZodOptional<z.ZodString>;
1903
+ suffix: z.ZodOptional<z.ZodString>;
1904
+ preferred: z.ZodOptional<z.ZodString>;
1905
+ }, z.core.$strip>>;
1906
+ contact: z.ZodOptional<z.ZodDefault<z.ZodObject<{
1907
+ email: z.ZodOptional<z.ZodString>;
1908
+ personalEmail: z.ZodOptional<z.ZodString>;
1909
+ phone: z.ZodOptional<z.ZodString>;
1910
+ alternatePhone: z.ZodOptional<z.ZodString>;
1911
+ whatsapp: z.ZodOptional<z.ZodString>;
1912
+ telegram: z.ZodOptional<z.ZodString>;
1913
+ linkedin: z.ZodOptional<z.ZodString>;
1914
+ instagram: z.ZodOptional<z.ZodString>;
1915
+ }, z.core.$strip>>>;
1916
+ jobTitle: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1917
+ accountId: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>>;
1918
+ ownerId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1919
+ tags: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
1920
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
1921
+ }, z.core.$strip>;
1922
+ declare const contactFilterSchema: z.ZodObject<{
1923
+ accountId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
1924
+ ownerId: z.ZodOptional<z.ZodString>;
1925
+ email: z.ZodOptional<z.ZodString>;
1926
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1927
+ }, z.core.$strip>;
1928
+ type CreateContactDto = z.infer<typeof createContactSchema>;
1929
+ type UpdateContactDto = z.infer<typeof updateContactSchema>;
1930
+ //#endregion
1931
+ //#region src/validators/account.schema.d.ts
1932
+ declare const createAccountSchema: z.ZodObject<{
1933
+ name: z.ZodString;
1934
+ domain: z.ZodOptional<z.ZodString>;
1935
+ industry: z.ZodOptional<z.ZodString>;
1936
+ sizeBucket: z.ZodOptional<z.ZodString>;
1937
+ annualRevenueAmount: z.ZodOptional<z.ZodNumber>;
1938
+ annualRevenueCurrency: z.ZodOptional<z.ZodString>;
1939
+ ownerId: z.ZodOptional<z.ZodString>;
1940
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1941
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1942
+ }, z.core.$strip>;
1943
+ declare const updateAccountSchema: z.ZodObject<{
1944
+ name: z.ZodOptional<z.ZodString>;
1945
+ domain: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1946
+ industry: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1947
+ sizeBucket: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1948
+ annualRevenueAmount: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
1949
+ annualRevenueCurrency: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1950
+ ownerId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1951
+ tags: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
1952
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
1953
+ }, z.core.$strip>;
1954
+ declare const accountFilterSchema: z.ZodObject<{
1955
+ domain: z.ZodOptional<z.ZodString>;
1956
+ industry: z.ZodOptional<z.ZodString>;
1957
+ ownerId: z.ZodOptional<z.ZodString>;
1958
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1959
+ }, z.core.$strip>;
1960
+ type CreateAccountDto = z.infer<typeof createAccountSchema>;
1961
+ type UpdateAccountDto = z.infer<typeof updateAccountSchema>;
1962
+ //#endregion
1963
+ //#region src/validators/campaign.schema.d.ts
1964
+ declare const createCampaignSchema: z.ZodObject<{
1965
+ name: z.ZodString;
1966
+ description: z.ZodOptional<z.ZodString>;
1967
+ utmSource: z.ZodOptional<z.ZodString>;
1968
+ utmMedium: z.ZodOptional<z.ZodString>;
1969
+ utmCampaign: z.ZodOptional<z.ZodString>;
1970
+ startDate: z.ZodOptional<z.ZodCoercedDate<unknown>>;
1971
+ endDate: z.ZodOptional<z.ZodCoercedDate<unknown>>;
1972
+ budgetAmount: z.ZodOptional<z.ZodNumber>;
1973
+ expectedRevenueAmount: z.ZodOptional<z.ZodNumber>;
1974
+ currency: z.ZodOptional<z.ZodString>;
1975
+ ownerId: z.ZodOptional<z.ZodString>;
1976
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1977
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1978
+ }, z.core.$strip>;
1979
+ declare const updateCampaignSchema: z.ZodObject<{
1980
+ name: z.ZodOptional<z.ZodString>;
1981
+ description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1982
+ utmSource: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1983
+ utmMedium: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1984
+ utmCampaign: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1985
+ startDate: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
1986
+ endDate: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
1987
+ budgetAmount: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
1988
+ expectedRevenueAmount: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
1989
+ currency: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1990
+ ownerId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1991
+ tags: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
1992
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
1993
+ }, z.core.$strip>;
1994
+ declare const completeCampaignSchema: z.ZodObject<{
1995
+ by: z.ZodOptional<z.ZodString>;
1996
+ note: z.ZodOptional<z.ZodString>;
1997
+ actualRevenueAmount: z.ZodOptional<z.ZodNumber>;
1998
+ }, z.core.$strip>;
1999
+ declare const campaignFilterSchema: z.ZodObject<{
2000
+ status: z.ZodOptional<z.ZodEnum<{
2001
+ draft: "draft";
2002
+ active: "active";
2003
+ paused: "paused";
2004
+ completed: "completed";
2005
+ archived: "archived";
2006
+ }>>;
2007
+ ownerId: z.ZodOptional<z.ZodString>;
2008
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
2009
+ startDateFrom: z.ZodOptional<z.ZodCoercedDate<unknown>>;
2010
+ startDateTo: z.ZodOptional<z.ZodCoercedDate<unknown>>;
2011
+ }, z.core.$strip>;
2012
+ type CreateCampaignDto = z.infer<typeof createCampaignSchema>;
2013
+ type UpdateCampaignDto = z.infer<typeof updateCampaignSchema>;
2014
+ type CompleteCampaignDto = z.infer<typeof completeCampaignSchema>;
2015
+ //#endregion
2016
+ //#region src/validators/subscription.schema.d.ts
2017
+ declare const subscribeSchema: z.ZodObject<{
2018
+ contactId: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
2019
+ campaignId: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
2020
+ source: z.ZodOptional<z.ZodString>;
2021
+ consentIpAddress: z.ZodOptional<z.ZodString>;
2022
+ consentUserAgent: z.ZodOptional<z.ZodString>;
2023
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2024
+ requireDoubleOptIn: z.ZodOptional<z.ZodBoolean>;
2025
+ }, z.core.$strip>;
2026
+ declare const confirmSubscriptionSchema: z.ZodObject<{
2027
+ token: z.ZodString;
2028
+ }, z.core.$strip>;
2029
+ declare const unsubscribeSchema: z.ZodObject<{
2030
+ token: z.ZodString;
2031
+ reason: z.ZodOptional<z.ZodString>;
2032
+ }, z.core.$strip>;
2033
+ declare const subscriptionFilterSchema: z.ZodObject<{
2034
+ status: z.ZodOptional<z.ZodEnum<{
2035
+ pending: "pending";
2036
+ confirmed: "confirmed";
2037
+ unsubscribed: "unsubscribed";
2038
+ bounced: "bounced";
2039
+ complained: "complained";
2040
+ }>>;
2041
+ contactId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
2042
+ campaignId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
2043
+ }, z.core.$strip>;
2044
+ type SubscribeDto = z.infer<typeof subscribeSchema>;
2045
+ type ConfirmSubscriptionDto = z.infer<typeof confirmSubscriptionSchema>;
2046
+ type UnsubscribeDto = z.infer<typeof unsubscribeSchema>;
2047
+ //#endregion
2048
+ //#region src/validators/activity.schema.d.ts
2049
+ declare const planActivitySchema: z.ZodObject<{
2050
+ type: z.ZodEnum<{
2051
+ call: "call";
2052
+ email: "email";
2053
+ meeting: "meeting";
2054
+ task: "task";
2055
+ note: "note";
2056
+ sms: "sms";
2057
+ social: "social";
2058
+ demo: "demo";
2059
+ other: "other";
2060
+ }>;
2061
+ subjectKind: z.ZodEnum<{
2062
+ lead: "lead";
2063
+ opportunity: "opportunity";
2064
+ contact: "contact";
2065
+ account: "account";
2066
+ }>;
2067
+ subjectId: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
2068
+ title: z.ZodString;
2069
+ description: z.ZodOptional<z.ZodString>;
2070
+ ownerId: z.ZodOptional<z.ZodString>;
2071
+ participantIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
2072
+ dueDate: z.ZodOptional<z.ZodCoercedDate<unknown>>;
2073
+ externalRef: z.ZodOptional<z.ZodString>;
2074
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2075
+ }, z.core.$strip>;
2076
+ declare const updateActivitySchema: z.ZodObject<{
2077
+ type: z.ZodOptional<z.ZodEnum<{
2078
+ call: "call";
2079
+ email: "email";
2080
+ meeting: "meeting";
2081
+ task: "task";
2082
+ note: "note";
2083
+ sms: "sms";
2084
+ social: "social";
2085
+ demo: "demo";
2086
+ other: "other";
2087
+ }>>;
2088
+ subjectKind: z.ZodOptional<z.ZodEnum<{
2089
+ lead: "lead";
2090
+ opportunity: "opportunity";
2091
+ contact: "contact";
2092
+ account: "account";
2093
+ }>>;
2094
+ subjectId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
2095
+ title: z.ZodOptional<z.ZodString>;
2096
+ description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
2097
+ ownerId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
2098
+ participantIds: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
2099
+ dueDate: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
2100
+ externalRef: z.ZodOptional<z.ZodOptional<z.ZodString>>;
2101
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
2102
+ }, z.core.$strip>;
2103
+ declare const cancelActivitySchema: z.ZodObject<{
2104
+ reason: z.ZodOptional<z.ZodString>;
2105
+ }, z.core.$strip>;
2106
+ declare const activityFilterSchema: z.ZodObject<{
2107
+ type: z.ZodOptional<z.ZodEnum<{
2108
+ call: "call";
2109
+ email: "email";
2110
+ meeting: "meeting";
2111
+ task: "task";
2112
+ note: "note";
2113
+ sms: "sms";
2114
+ social: "social";
2115
+ demo: "demo";
2116
+ other: "other";
2117
+ }>>;
2118
+ status: z.ZodOptional<z.ZodEnum<{
2119
+ completed: "completed";
2120
+ planned: "planned";
2121
+ in_progress: "in_progress";
2122
+ cancelled: "cancelled";
2123
+ }>>;
2124
+ subjectKind: z.ZodOptional<z.ZodEnum<{
2125
+ lead: "lead";
2126
+ opportunity: "opportunity";
2127
+ contact: "contact";
2128
+ account: "account";
2129
+ }>>;
2130
+ subjectId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
2131
+ ownerId: z.ZodOptional<z.ZodString>;
2132
+ dueDateFrom: z.ZodOptional<z.ZodCoercedDate<unknown>>;
2133
+ dueDateTo: z.ZodOptional<z.ZodCoercedDate<unknown>>;
2134
+ }, z.core.$strip>;
2135
+ type PlanActivityDto = z.infer<typeof planActivitySchema>;
2136
+ type CancelActivityDto = z.infer<typeof cancelActivitySchema>;
2137
+ //#endregion
2138
+ //#region src/validators/note.schema.d.ts
2139
+ declare const addNoteSchema: z.ZodObject<{
2140
+ subjectKind: z.ZodEnum<{
2141
+ lead: "lead";
2142
+ opportunity: "opportunity";
2143
+ contact: "contact";
2144
+ account: "account";
2145
+ }>;
2146
+ subjectId: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
2147
+ body: z.ZodString;
2148
+ authorId: z.ZodOptional<z.ZodString>;
2149
+ pinned: z.ZodOptional<z.ZodBoolean>;
2150
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2151
+ }, z.core.$strip>;
2152
+ declare const updateNoteSchema: z.ZodObject<{
2153
+ body: z.ZodOptional<z.ZodString>;
2154
+ pinned: z.ZodOptional<z.ZodBoolean>;
2155
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2156
+ }, z.core.$strip>;
2157
+ declare const noteFilterSchema: z.ZodObject<{
2158
+ subjectKind: z.ZodOptional<z.ZodEnum<{
2159
+ lead: "lead";
2160
+ opportunity: "opportunity";
2161
+ contact: "contact";
2162
+ account: "account";
2163
+ }>>;
2164
+ subjectId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
2165
+ authorId: z.ZodOptional<z.ZodString>;
2166
+ pinned: z.ZodOptional<z.ZodCoercedBoolean<unknown>>;
2167
+ }, z.core.$strip>;
2168
+ type AddNoteDto = z.infer<typeof addNoteSchema>;
2169
+ type UpdateNoteDto = z.infer<typeof updateNoteSchema>;
2170
+ //#endregion
2171
+ //#region src/validators/loss-reason.schema.d.ts
2172
+ declare const createLossReasonSchema: z.ZodObject<{
2173
+ name: z.ZodString;
2174
+ description: z.ZodOptional<z.ZodString>;
2175
+ isActive: z.ZodOptional<z.ZodBoolean>;
2176
+ sequence: z.ZodOptional<z.ZodNumber>;
2177
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2178
+ }, z.core.$strip>;
2179
+ declare const updateLossReasonSchema: z.ZodObject<{
2180
+ name: z.ZodOptional<z.ZodString>;
2181
+ description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
2182
+ isActive: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
2183
+ sequence: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
2184
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
2185
+ }, z.core.$strip>;
2186
+ declare const lossReasonFilterSchema: z.ZodObject<{
2187
+ isActive: z.ZodOptional<z.ZodCoercedBoolean<unknown>>;
2188
+ }, z.core.$strip>;
2189
+ type CreateLossReasonDto = z.infer<typeof createLossReasonSchema>;
2190
+ type UpdateLossReasonDto = z.infer<typeof updateLossReasonSchema>;
2191
+ //#endregion
2192
+ //#region src/validators/email-event.schema.d.ts
2193
+ declare const recordEmailEventSchema: z.ZodObject<{
2194
+ subjectKind: z.ZodEnum<{
2195
+ contact: "contact";
2196
+ subscription: "subscription";
2197
+ }>;
2198
+ subjectId: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
2199
+ campaignId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
2200
+ messageId: z.ZodOptional<z.ZodString>;
2201
+ url: z.ZodOptional<z.ZodString>;
2202
+ userAgent: z.ZodOptional<z.ZodString>;
2203
+ ip: z.ZodOptional<z.ZodString>;
2204
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2205
+ }, z.core.$strip>;
2206
+ declare const emailEventFilterSchema: z.ZodObject<{
2207
+ kind: z.ZodOptional<z.ZodEnum<{
2208
+ open: "open";
2209
+ click: "click";
2210
+ bounce: "bounce";
2211
+ complaint: "complaint";
2212
+ unsubscribe: "unsubscribe";
2213
+ }>>;
2214
+ subjectKind: z.ZodOptional<z.ZodEnum<{
2215
+ contact: "contact";
2216
+ subscription: "subscription";
2217
+ }>>;
2218
+ subjectId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
2219
+ campaignId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
2220
+ messageId: z.ZodOptional<z.ZodString>;
2221
+ }, z.core.$strip>;
2222
+ type RecordEmailEventDto = z.infer<typeof recordEmailEventSchema>;
2223
+ declare namespace index_d_exports {
2224
+ export { AddNoteDto, CancelActivityDto, CloseLossDto, CloseWinDto, CompleteCampaignDto, ConfirmSubscriptionDto, ConvertLeadDto, CreateAccountDto, CreateCampaignDto, CreateContactDto, CreateLeadDto, CreateLossReasonDto, CreatePipelineDto, LeadFilterDto, MoveStageDto, OpenOpportunityDto, OpportunityFilterDto, PlanActivityDto, RecordEmailEventDto, StageInputDto, SubscribeDto, UnsubscribeDto, UpdateAccountDto, UpdateCampaignDto, UpdateContactDto, UpdateLeadDto, UpdateLossReasonDto, UpdateNoteDto, UpdatePipelineDto, accountFilterSchema, activityFilterSchema, addNoteSchema, campaignFilterSchema, cancelActivitySchema, closeLossSchema, closeWinSchema, completeCampaignSchema, confirmSubscriptionSchema, contactFilterSchema, convertLeadSchema, createAccountSchema, createCampaignSchema, createContactSchema, createLeadSchema, createLossReasonSchema, createPipelineSchema, currencyCodeSchema, emailEventFilterSchema, leadFilterSchema, lossReasonFilterSchema, metadataSchema, moneyAmountSchema, moveStageSchema, noteFilterSchema, objectIdLike, openOpportunitySchema, opportunityFilterSchema, pipelineFilterSchema, planActivitySchema, recordEmailEventSchema, stageInputSchemaExport, subscribeSchema, subscriptionFilterSchema, tagsSchema, unsubscribeSchema, updateAccountSchema, updateActivitySchema, updateCampaignSchema, updateContactSchema, updateLeadSchema, updateLossReasonSchema, updateNoteSchema, updatePipelineSchema };
1485
2225
  }
1486
2226
  //#endregion
1487
- export { IMessageAttachment as $, ContactUpdated as $n, CAMPAIGN_TRANSITIONS as $t, AccountRepository as A, SchemaBuildConfig as An, PipelineArchived as Ar, buildActivitySchema as At, OpportunityRepositoryDeps as B, ActivityOutcomeRecorded as Bn, ISubscriptionDocument as Bt, ActivityRepository as C, LEAD_TRANSITIONS as Cn, OpportunityAssigned as Cr, ILossReasonDocument as Ct, SubscriptionRepositoryDeps as D, IStageDocument as Dn, OpportunityStageAdvanced as Dr, buildNoteSchema as Dt, SubscriptionRepository as E, IPipelineDocument as En, OpportunityLost as Er, INoteDocument as Et, MergeContactInput as F, AccountEnriched as Fn, SubscriptionCreated as Fr, ActivityStatus as Ft, composeScorers as G, CampaignCompleted as Gn, SUBSCRIPTION_TRANSITIONS as Gt, LeadRepositoryDeps as H, ActivityRescheduled as Hn, buildSubscriptionSchema as Ht, CloseInput as I, AccountMerged as In, SubscriptionUnsubscribed as Ir, ActivityType as It, PipelineRepositoryDeps as J, CampaignResumed as Jn, ICampaignDocument as Jt, defaultLeadScorer as K, CampaignCreated as Kn, SubscriptionStatus as Kt, MoveStageInput as L, AccountUpdated as Ln, crmEventDefinitions as Lr, SUBJECT_KINDS as Lt, MergeAccountInput as M, tenantFieldDef as Mn, SubscriptionBounced as Mr, ACTIVITY_STATUSES as Mt, ContactRepository as N, AccountAssigned as Nn, SubscriptionComplained as Nr, ACTIVITY_TRANSITIONS as Nt, CampaignRepository as O, buildPipelineSchema as On, OpportunityStageRegressed as Or, createNoteModel as Ot, ContactRepositoryDeps as P, AccountCreated as Pn, SubscriptionConfirmed as Pr, ACTIVITY_TYPES as Pt, createCrmModels as Q, ContactMerged as Qn, CAMPAIGN_STATUSES as Qt, OpenOpportunityInput as R, ActivityCancelled as Rn, CRM_EVENTS as Rr, SubjectKind as Rt, NoteRepositoryDeps as S, LEAD_STATUSES as Sn, OpportunityAmountChanged as Sr, EmailEventKind as St, SubscribeInput as T, canTransitionLead as Tn, OpportunityExtended as Tr, createLossReasonModel as Tt, LeadInput as U, CampaignActivated as Un, createSubscriptionModel as Ut, LeadRepository as V, ActivityPlanned as Vn, ISubscriptionStatusEntry as Vt, LeadScorer as W, CampaignArchived as Wn, SUBSCRIPTION_STATUSES as Wt, CreateModelsOptions as X, ContactCreated as Xn, buildCampaignSchema as Xt, CRM_MODEL_NAMES as Y, ContactAssigned as Yn, ICampaignStatusEntry as Yt, CrmModels as Z, ContactEnriched as Zn, createCampaignModel as Zt, EmailEventRepositoryDeps as _, canTransitionOpportunity as _n, LeadStatusChanged as _r, EmailEventSubjectKind as _t, CrmEngine as a, IContactDocument as an, CrmEventSchema as ar, createConversationModel as at, LossReasonRepositoryDeps as b, buildLeadSchema as bn, NoteAdded as br, createEmailEventModel as bt, ResolvedCrmConfig as c, buildContactSchema as cn, EmailEventComplained as cr, CONVERSATION_STATUSES as ct, MessageRepositoryDeps as d, IOpportunityStatusEntry as dn, LeadAssigned as dr, ConversationStatus as dt, CampaignStatus as en, ConversationAssigned as er, IMessageDocument as et, RecordMessageInput as f, buildOpportunitySchema as fn, LeadConverted as fr, MESSAGE_DELIVERY_STATUSES as ft, EmailEventRepository as g, OpportunityStatus as gn, LeadScored as gr, EMAIL_EVENT_SUBJECT_KINDS as gt, OpenConversationInput as h, OPPORTUNITY_TRANSITIONS as hn, LeadEnriched as hr, MessageDirection as ht, CrmContext as i, createAccountModel as in, CrmEventDefinition as ir, buildConversationSchema as it, AccountRepositoryDeps as j, TenantFieldType as jn, PipelineCreated as jr, createActivityModel as jt, CampaignRepositoryDeps as k, createPipelineModel as kn, OpportunityWon as kr, IActivityDocument as kt, _ModelTypes as l, createContactModel as ln, EmailEventOpened as lr, ConversationChannel as lt, ConversationRepositoryDeps as m, OPPORTUNITY_STATUSES as mn, LeadDisqualified as mr, MessageDeliveryStatus as mt, createEvent$1 as n, IAccountDocument as nn, ConversationReopened as nr, createMessageModel as nt, CrmLogger as o, IContactInfoEmbedded as on, EmailEventBounced as or, CONVERSATION_CHANNELS as ot, ConversationRepository as p, createOpportunityModel as pn, LeadCreated as pr, MESSAGE_DIRECTIONS as pt, PipelineRepository as q, CampaignPaused as qn, canTransitionSubscription as qt, CrmConfig as r, buildAccountSchema as rn, ConversationResolved as rr, IConversationDocument as rt, CrmRepositories as s, IContactName as sn, EmailEventClicked as sr, CONVERSATION_PARTICIPANT_KINDS as st, InProcessCrmBus as t, canTransitionCampaign as tn, ConversationCreated as tr, buildMessageSchema as tt, MessageRepository as u, IOpportunityDocument as un, EmailEventUnsubscribed as ur, ConversationParticipantKind as ut, RecordEmailEventInput as v, ILeadDocument as vn, MessageReceived as vr, IEmailEventDocument as vt, ActivityRepositoryDeps as w, LeadStatus as wn, OpportunityCreated as wr, buildLossReasonSchema as wt, NoteRepository as x, createLeadModel as xn, OpportunityAbandoned as xr, EMAIL_EVENT_KINDS as xt, LossReasonRepository as y, ILeadStatusEntry as yn, MessageSent as yr, buildEmailEventSchema as yt, OpportunityRepository as z, ActivityCompleted as zn, CrmEventName as zr, canTransitionActivity as zt };
2227
+ export { ACTIVITY_MACHINE, ACTIVITY_STATUSES, ACTIVITY_TRANSITIONS, ACTIVITY_TYPES, AccountAssigned, AccountCreated, AccountEnriched, AccountMerged, AccountRepository, AccountRepositoryDeps, AccountUpdated, ActivityCancelled, ActivityCompleted, ActivityOutcomeRecorded, ActivityPlanned, ActivityRepository, ActivityRepositoryDeps, ActivityRescheduled, type ActivityStatus, type ActivityType, CAMPAIGN_MACHINE, CAMPAIGN_STATUSES, CAMPAIGN_TRANSITIONS, CONVERSATION_CHANNELS, CONVERSATION_PARTICIPANT_KINDS, CONVERSATION_STATUSES, CRM_EVENTS, CRM_MODEL_NAMES, CampaignActivated, CampaignArchived, CampaignCompleted, CampaignCreated, CampaignPaused, CampaignRepository, CampaignRepositoryDeps, CampaignResumed, type CampaignStatus, CloseInput, ContactAssigned, ContactCreated, ContactEnriched, ContactMerged, ContactRepository, ContactRepositoryDeps, ContactUpdated, ConversationAssigned, type ConversationChannel, ConversationCreated, type ConversationParticipantKind, ConversationReopened, ConversationRepository, ConversationRepositoryDeps, ConversationResolved, type ConversationStatus, ConversionRow, ConvertLeadInput, ConvertResult, CreateCrmRepositoriesDeps, CreateModelsOptions, CrmConfig, CrmContext, CrmEngine, CrmError, CrmEventDefinition, CrmEventName, CrmEventSchema, CrmLogger, CrmModels, CrmRepositories, DuplicateCampaignError, DuplicateLeadError, DuplicateSubscriptionError, EMAIL_EVENT_KINDS, EMAIL_EVENT_SUBJECT_KINDS, EmailEventBounced, EmailEventClicked, EmailEventComplained, type EmailEventKind, EmailEventOpened, EmailEventRepository, EmailEventRepositoryDeps, EmailEventSubjectKind, EmailEventUnsubscribed, EmptyPipelineError, ForecastOptions, ForecastRow, type IAccountDocument, type IActivityDocument, type ICampaignDocument, ICampaignStatusEntry, type IContactDocument, IContactInfoEmbedded, IContactName, type IConversationDocument, type IEmailEventDocument, type ILeadDocument, ILeadStatusEntry, type ILossReasonDocument, IMessageAttachment, type IMessageDocument, type INoteDocument, type IOpportunityDocument, IOpportunityStatusEntry, type IPipelineDocument, IStageDocument, type ISubscriptionDocument, ISubscriptionStatusEntry, InProcessCrmBus, InvalidActivityTransitionError, InvalidCampaignTransitionError, InvalidConfirmationTokenError, InvalidLeadTransitionError, InvalidOpportunityTransitionError, InvalidSubscriptionTransitionError, InvalidUnsubscribeTokenError, LEAD_MACHINE, LEAD_STATUSES, LEAD_TRANSITIONS, LeadAlreadyConvertedError, LeadAssigned, LeadConverted, LeadCreated, LeadDisqualified, LeadEnriched, LeadInput, LeadRepository, LeadRepositoryDeps, LeadScored, LeadScorer, LeadService, LeadServiceDeps, type LeadStatus, LeadStatusChanged, LossReasonRepository, LossReasonRepositoryDeps, MESSAGE_DELIVERY_STATUSES, MESSAGE_DIRECTIONS, MergeAccountInput, MergeContactInput, type MessageDeliveryStatus, type MessageDirection, MessageReceived, MessageRepository, MessageRepositoryDeps, MessageSent, MoveStageInput, NotFoundError, NoteAdded, NoteRepository, NoteRepositoryDeps, OPPORTUNITY_MACHINE, OPPORTUNITY_STATUSES, OPPORTUNITY_TRANSITIONS, OpenConversationInput, OpenOpportunityInput, OpportunityAbandoned, OpportunityAmountChanged, OpportunityAssigned, OpportunityCreated, OpportunityExtended, OpportunityForecast, OpportunityLost, OpportunityRepository, OpportunityRepositoryDeps, OpportunityStageAdvanced, OpportunityStageRegressed, type OpportunityStatus, OpportunityWon, PipelineArchived, PipelineCreated, PipelineRepository, PipelineRepositoryDeps, RecordEmailEventInput, RecordMessageInput, ResolvedCrmConfig, SUBJECT_KINDS, SUBSCRIPTION_MACHINE, SUBSCRIPTION_STATUSES, SUBSCRIPTION_TRANSITIONS, SchemaBuildConfig, StageNotInPipelineError, type StatusChangeEntry, type StatusHistory, type SubjectKind, SubscribeInput, SubscriptionBounced, SubscriptionComplained, SubscriptionConfirmed, SubscriptionCreated, SubscriptionRepository, SubscriptionRepositoryDeps, type SubscriptionStatus, SubscriptionUnsubscribed, TenantFieldType, _ModelTypes, appendStatus, buildAccountSchema, buildActivitySchema, buildCampaignSchema, buildContactSchema, buildConversationSchema, buildEmailEventSchema, buildLeadSchema, buildLossReasonSchema, buildMessageSchema, buildNoteSchema, buildOpportunitySchema, buildPipelineSchema, buildSubscriptionSchema, canTransitionActivity, canTransitionCampaign, canTransitionLead, canTransitionOpportunity, canTransitionSubscription, composeScorers, createAccountModel, createActivityModel, createCampaignModel, createContactModel, createConversationModel, createCrm, createCrmModels, createCrmRepositories, createEmailEventModel, createEvent, createLeadModel, createLossReasonModel, createMessageModel, createNoteModel, createOpportunityModel, createPipelineModel, createSubscriptionModel, crmEventDefinitions, defaultLeadScorer, forecast, lastTransitionTo, latestEntry, pipelineConversion, tenantFieldDef, timeInStatus, index_d_exports as validators };