@classytic/crm 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -6,7 +6,59 @@ import * as _$_classytic_primitives_state_machine0 from "@classytic/primitives/s
6
6
  import { z } from "zod";
7
7
  import { StatusChangeEntry, StatusHistory, appendStatus, lastTransitionTo, latestEntry, timeInStatus } from "@classytic/primitives/status-history";
8
8
  import { OperationContext } from "@classytic/primitives/context";
9
+ import { OutboxStore } from "@classytic/primitives/outbox";
9
10
 
11
+ //#region src/events/dispatch.d.ts
12
+ /**
13
+ * Context key for the post-commit event queue. `Symbol.for` so the host
14
+ * and the package agree on the key even across duplicated installs.
15
+ */
16
+ declare const PENDING_EVENTS: unique symbol;
17
+ /** CrmContext as seen inside a unit of work — carries the deferred queue. */
18
+ type InternalCrmContext = CrmContext & {
19
+ [PENDING_EVENTS]?: DomainEvent[];
20
+ };
21
+ interface CrmEventDispatcherOptions {
22
+ /** Underlying transport (host-supplied or the in-process bus). */
23
+ transport: EventTransport;
24
+ /**
25
+ * Transactional outbox. When wired, every domain event is persisted via
26
+ * `outbox.save(event, { session })` in the SAME session as the business
27
+ * write; the host's relay publishes committed rows.
28
+ */
29
+ outbox?: OutboxStore | undefined;
30
+ logger?: CrmLogger | undefined;
31
+ }
32
+ /**
33
+ * EventTransport-compatible wrapper the engine hands to repositories.
34
+ * `publish`/`subscribe` delegate straight to the underlying transport
35
+ * (host-facing surface unchanged); domain verbs call `dispatch(ctx, event)`
36
+ * so session/outbox/queue routing happens in ONE place.
37
+ */
38
+ declare class CrmEventDispatcher implements EventTransport {
39
+ readonly transport: EventTransport;
40
+ private readonly outbox;
41
+ private readonly logger;
42
+ constructor(options: CrmEventDispatcherOptions);
43
+ get name(): string;
44
+ /** Raw immediate publish — post-commit flushes and host-side use only. */
45
+ publish(event: DomainEvent): Promise<void>;
46
+ subscribe(pattern: string, handler: EventHandler): Promise<() => void>;
47
+ close(): Promise<void>;
48
+ /**
49
+ * Session-bound dispatch (see module doc for the full contract).
50
+ * `ctx` comes first so call sites read `dispatch(ctx, createEvent(...))`.
51
+ */
52
+ dispatch(ctx: CrmContext | undefined, event: DomainEvent): Promise<void>;
53
+ }
54
+ /**
55
+ * Drain a `[PENDING_EVENTS]` queue through a transport after commit,
56
+ * swallowing per-event errors (durable delivery is the outbox's job).
57
+ * Hosts composing their own outer transaction call this after commit;
58
+ * most should use `engine.withTransaction(ctx, fn)` instead.
59
+ */
60
+ declare function flushPending(transport: Pick<EventTransport, 'publish'> | undefined, events: DomainEvent[], logger?: CrmLogger): Promise<void>;
61
+ //#endregion
10
62
  //#region src/models/tenant-field.d.ts
11
63
  type TenantFieldType = 'objectId' | 'string';
12
64
  interface SchemaBuildConfig {
@@ -302,6 +354,31 @@ interface ISubscriptionDocument {
302
354
  declare function buildSubscriptionSchema(config: SchemaBuildConfig): Schema<ISubscriptionDocument>;
303
355
  declare function createSubscriptionModel(connection: Connection, config: SchemaBuildConfig): Model<ISubscriptionDocument>;
304
356
  //#endregion
357
+ //#region src/enums/suppression-reason.d.ts
358
+ /** Reasons derived 1:1 from an email engagement event kind. */
359
+ declare const EVENT_DERIVED_SUPPRESSION_REASONS: readonly ["bounce", "complaint", "unsubscribe"];
360
+ declare const SUPPRESSION_REASONS: readonly ["bounce", "complaint", "unsubscribe", "manual"];
361
+ type SuppressionReason = (typeof SUPPRESSION_REASONS)[number];
362
+ //#endregion
363
+ //#region src/models/suppression.schema.d.ts
364
+ interface ISuppressionDocument {
365
+ _id: _$mongoose.Types.ObjectId;
366
+ organizationId: _$mongoose.Types.ObjectId | string;
367
+ /** Stored lowercase-normalized (schema `lowercase: true` + repo trims). */
368
+ email: string;
369
+ reason: SuppressionReason;
370
+ /** Free-form origin: 'campaign:<id>', 'sequence:<id>', 'api', 'import', … */
371
+ source?: string;
372
+ /** Optional polymorphic external ref to the suppressed party (rule 7). */
373
+ subjectKind?: string;
374
+ subjectId?: string;
375
+ suppressedAt: Date;
376
+ metadata?: Record<string, unknown>;
377
+ createdAt: Date;
378
+ updatedAt: Date;
379
+ }
380
+ declare function buildSuppressionSchema(config: SchemaBuildConfig): Schema<ISuppressionDocument>;
381
+ //#endregion
305
382
  //#region src/enums/activity.d.ts
306
383
  /**
307
384
  * Activity type vocabulary. The package stores `type` as free-form
@@ -502,6 +579,124 @@ interface IMessageDocument {
502
579
  declare function buildMessageSchema(config: SchemaBuildConfig): Schema<IMessageDocument>;
503
580
  declare function createMessageModel(connection: Connection, config: SchemaBuildConfig): Model<IMessageDocument>;
504
581
  //#endregion
582
+ //#region src/enums/sequence-status.d.ts
583
+ /**
584
+ * Email sequence lifecycle.
585
+ *
586
+ * draft — being built; no enrollments can be created
587
+ * active — accepting new enrollments; steps are executing
588
+ * paused — no new enrollments; running enrollments pause at next step
589
+ * archived — soft-hidden; historical data preserved
590
+ */
591
+ declare const SEQUENCE_STATUSES: readonly ["draft", "active", "paused", "archived"];
592
+ type SequenceStatus = (typeof SEQUENCE_STATUSES)[number];
593
+ declare const SEQUENCE_TRANSITIONS: Record<SequenceStatus, readonly SequenceStatus[]>;
594
+ declare function canTransitionSequence(from: SequenceStatus, to: SequenceStatus): boolean;
595
+ //#endregion
596
+ //#region src/models/sequence.schema.d.ts
597
+ interface ISendEmailStep {
598
+ id: string;
599
+ type: 'SEND_EMAIL';
600
+ name?: string;
601
+ subject: string;
602
+ htmlBody: string;
603
+ fromName?: string;
604
+ fromEmail?: string;
605
+ }
606
+ interface IDelayStep {
607
+ id: string;
608
+ type: 'DELAY';
609
+ name?: string;
610
+ settings: {
611
+ days?: number;
612
+ hours?: number;
613
+ minutes?: number;
614
+ };
615
+ }
616
+ type SequenceStep = ISendEmailStep | IDelayStep;
617
+ interface ISequenceStatusEntry {
618
+ status: SequenceStatus;
619
+ occurredAt: Date;
620
+ by?: string;
621
+ note?: string;
622
+ }
623
+ interface ISequenceDocument {
624
+ _id: _$mongoose.Types.ObjectId;
625
+ organizationId: _$mongoose.Types.ObjectId | string;
626
+ name: string;
627
+ description?: string;
628
+ status: SequenceStatus;
629
+ fromName?: string;
630
+ fromEmail?: string;
631
+ /** Ordered list of steps — each step has a unique `id`. */
632
+ steps: SequenceStep[];
633
+ /** Exit enrollment when a reply is detected. Default true. */
634
+ replyDetectionEnabled: boolean;
635
+ tags: string[];
636
+ ownerId?: string;
637
+ metadata?: Record<string, unknown>;
638
+ statusHistory: ISequenceStatusEntry[];
639
+ createdAt: Date;
640
+ updatedAt: Date;
641
+ }
642
+ declare function buildSequenceSchema(config: SchemaBuildConfig): Schema<ISequenceDocument>;
643
+ //#endregion
644
+ //#region src/enums/enrollment-status.d.ts
645
+ /**
646
+ * Enrollment lifecycle.
647
+ *
648
+ * active — steps are executing (or waiting on a delay)
649
+ * paused — execution halted; can be resumed
650
+ * completed — all steps ran to completion
651
+ * exited — removed early (reply, unsubscribe, bounce, manual)
652
+ */
653
+ declare const ENROLLMENT_STATUSES: readonly ["active", "paused", "completed", "exited"];
654
+ type EnrollmentStatus = (typeof ENROLLMENT_STATUSES)[number];
655
+ declare const ENROLLMENT_TRANSITIONS: Record<EnrollmentStatus, readonly EnrollmentStatus[]>;
656
+ declare function canTransitionEnrollment(from: EnrollmentStatus, to: EnrollmentStatus): boolean;
657
+ //#endregion
658
+ //#region src/models/enrollment.schema.d.ts
659
+ type EnrollmentExitReason = 'completed' | 'reply' | 'unsubscribe' | 'bounce' | 'manual';
660
+ type StepResultStatus = 'pending' | 'sent' | 'failed' | 'skipped';
661
+ declare const ENROLLMENT_SUBJECT_KINDS: readonly ["lead", "contact"];
662
+ type EnrollmentSubjectKind = (typeof ENROLLMENT_SUBJECT_KINDS)[number];
663
+ interface IStepResult {
664
+ stepId: string;
665
+ stepType: string;
666
+ status: StepResultStatus;
667
+ sentAt?: Date;
668
+ error?: string;
669
+ }
670
+ interface IEnrollmentStatusEntry {
671
+ status: EnrollmentStatus;
672
+ occurredAt: Date;
673
+ by?: string;
674
+ }
675
+ interface IEnrollmentDocument {
676
+ _id: _$mongoose.Types.ObjectId;
677
+ organizationId: _$mongoose.Types.ObjectId | string;
678
+ sequenceId: _$mongoose.Types.ObjectId | string;
679
+ subjectKind: EnrollmentSubjectKind;
680
+ subjectId: _$mongoose.Types.ObjectId | string;
681
+ status: EnrollmentStatus;
682
+ /** Index into sequence.steps[] — 0-based. */
683
+ currentStepIndex: number;
684
+ stepResults: IStepResult[];
685
+ /** When a DELAY step will expire (informational — streamline owns the actual timer). */
686
+ resumeAt?: Date;
687
+ /** Streamline workflow run ID — used for idempotency checks. */
688
+ workflowRunId?: string;
689
+ exitReason?: EnrollmentExitReason;
690
+ enrolledAt: Date;
691
+ completedAt?: Date;
692
+ ownerId?: string;
693
+ metadata?: Record<string, unknown>;
694
+ statusHistory: IEnrollmentStatusEntry[];
695
+ createdAt: Date;
696
+ updatedAt: Date;
697
+ }
698
+ declare function buildEnrollmentSchema(config: SchemaBuildConfig): Schema<IEnrollmentDocument>;
699
+ //#endregion
505
700
  //#region src/models/create-models.d.ts
506
701
  interface CrmModels {
507
702
  Pipeline: Model<IPipelineDocument>;
@@ -511,15 +706,18 @@ interface CrmModels {
511
706
  Account: Model<IAccountDocument>;
512
707
  Campaign: Model<ICampaignDocument>;
513
708
  Subscription: Model<ISubscriptionDocument>;
709
+ Suppression: Model<ISuppressionDocument>;
514
710
  Activity: Model<IActivityDocument>;
515
711
  Note: Model<INoteDocument>;
516
712
  LossReason: Model<ILossReasonDocument>;
517
713
  EmailEvent: Model<IEmailEventDocument>;
518
714
  Conversation: Model<IConversationDocument>;
519
715
  Message: Model<IMessageDocument>;
716
+ Sequence: Model<ISequenceDocument>;
717
+ Enrollment: Model<IEnrollmentDocument>;
520
718
  }
521
719
  /** Mongoose model names this package registers — drives the §21 collision check. */
522
- declare const CRM_MODEL_NAMES: readonly ["Pipeline", "Lead", "Opportunity", "Contact", "Account", "Campaign", "EmailSubscription", "Activity", "Note", "LossReason", "EmailEvent", "Conversation", "Message"];
720
+ declare const CRM_MODEL_NAMES: readonly ["Pipeline", "Lead", "Opportunity", "Contact", "Account", "Campaign", "EmailSubscription", "Suppression", "Activity", "Note", "LossReason", "EmailEvent", "Conversation", "Message", "Sequence", "Enrollment"];
523
721
  interface CreateModelsOptions extends SchemaBuildConfig {
524
722
  /**
525
723
  * On a model-name collision: `false` (default) throws
@@ -534,7 +732,7 @@ declare function createCrmModels(connection: Connection, config: CreateModelsOpt
534
732
  //#endregion
535
733
  //#region src/repositories/pipeline.repository.d.ts
536
734
  interface PipelineRepositoryDeps {
537
- events: EventTransport;
735
+ events: CrmEventDispatcher;
538
736
  }
539
737
  declare class PipelineRepository extends Repository<IPipelineDocument> {
540
738
  private readonly events;
@@ -572,7 +770,7 @@ declare function composeScorers(...rules: readonly LeadScorer[]): LeadScorer;
572
770
  //#endregion
573
771
  //#region src/repositories/lead.repository.d.ts
574
772
  interface LeadRepositoryDeps {
575
- events: EventTransport;
773
+ events: CrmEventDispatcher;
576
774
  /** Override the default lead scorer. */
577
775
  scorer?: LeadScorer;
578
776
  /** Reject `create()` when an email already exists in-tenant (default true). */
@@ -634,7 +832,7 @@ declare class LeadRepository extends Repository<ILeadDocument> {
634
832
  //#endregion
635
833
  //#region src/repositories/opportunity.repository.d.ts
636
834
  interface OpportunityRepositoryDeps {
637
- events: EventTransport;
835
+ events: CrmEventDispatcher;
638
836
  /** Cross-repo reference: read embedded stages from Pipeline. */
639
837
  pipelines: PipelineRepository;
640
838
  }
@@ -727,7 +925,7 @@ declare class OpportunityRepository extends Repository<IOpportunityDocument> {
727
925
  //#endregion
728
926
  //#region src/repositories/contact.repository.d.ts
729
927
  interface ContactRepositoryDeps {
730
- events: EventTransport;
928
+ events: CrmEventDispatcher;
731
929
  }
732
930
  interface MergeContactInput {
733
931
  /** Surviving contact id. Receives merged fields. */
@@ -776,7 +974,7 @@ declare class ContactRepository extends Repository<IContactDocument> {
776
974
  //#endregion
777
975
  //#region src/repositories/account.repository.d.ts
778
976
  interface AccountRepositoryDeps {
779
- events: EventTransport;
977
+ events: CrmEventDispatcher;
780
978
  }
781
979
  interface MergeAccountInput {
782
980
  primaryId: string;
@@ -796,7 +994,7 @@ declare class AccountRepository extends Repository<IAccountDocument> {
796
994
  //#endregion
797
995
  //#region src/repositories/campaign.repository.d.ts
798
996
  interface CampaignRepositoryDeps {
799
- events: EventTransport;
997
+ events: CrmEventDispatcher;
800
998
  /** Reject `createCampaign` on duplicate names per-tenant (default true). */
801
999
  rejectDuplicates?: boolean;
802
1000
  }
@@ -820,7 +1018,7 @@ declare class CampaignRepository extends Repository<ICampaignDocument> {
820
1018
  //#endregion
821
1019
  //#region src/repositories/subscription.repository.d.ts
822
1020
  interface SubscriptionRepositoryDeps {
823
- events: EventTransport;
1021
+ events: CrmEventDispatcher;
824
1022
  /** Default DOI policy when `subscribe` doesn't pass `requireDoubleOptIn`. */
825
1023
  defaultRequireDoubleOptIn?: boolean;
826
1024
  }
@@ -846,9 +1044,53 @@ declare class SubscriptionRepository extends Repository<ISubscriptionDocument> {
846
1044
  private _transition;
847
1045
  }
848
1046
  //#endregion
1047
+ //#region src/repositories/suppression.repository.d.ts
1048
+ interface SuppressionRepositoryDeps {
1049
+ events: CrmEventDispatcher;
1050
+ }
1051
+ interface SuppressInput {
1052
+ reason: SuppressionReason;
1053
+ /** Free-form origin: 'campaign:<id>', 'sequence:<id>', 'api', 'import', … */
1054
+ source?: string;
1055
+ /** Optional polymorphic external ref to the suppressed party (rule 7). */
1056
+ subjectKind?: string;
1057
+ subjectId?: string;
1058
+ metadata?: Record<string, unknown>;
1059
+ }
1060
+ declare class SuppressionRepository extends Repository<ISuppressionDocument> {
1061
+ private readonly events;
1062
+ constructor(model: Model<ISuppressionDocument>, plugins: PluginType[], deps: SuppressionRepositoryDeps, pagination?: PaginationConfig);
1063
+ /**
1064
+ * Idempotently add `email` to the org's suppression list. Atomic
1065
+ * `getOrCreate` on the unique (org, email) index — of N concurrent
1066
+ * calls exactly one inserts. Emits `crm:suppression.added` only for
1067
+ * the inserting call; an existing row is returned unchanged, no event.
1068
+ */
1069
+ suppress(email: string, input: SuppressInput, ctx?: CrmContext): Promise<ISuppressionDocument>;
1070
+ /** True when `email` is on the org's suppression list. */
1071
+ isSuppressed(email: string, ctx?: CrmContext): Promise<boolean>;
1072
+ /**
1073
+ * Return the suppressed subset of `emails` (normalized) as a Set —
1074
+ * ONE `$in` query, built for the campaign-fanout hot path:
1075
+ *
1076
+ * ```ts
1077
+ * const blocked = await suppression.filterSuppressed(recipients, ctx);
1078
+ * const sendable = recipients.filter((e) => !blocked.has(e.toLowerCase()));
1079
+ * ```
1080
+ */
1081
+ filterSuppressed(emails: string[], ctx?: CrmContext): Promise<Set<string>>;
1082
+ /**
1083
+ * Remove `email` from the org's suppression list. Single atomic
1084
+ * `deleteMany` on the (unique) email key — emits
1085
+ * `crm:suppression.removed` only when a row was actually removed.
1086
+ * Returns whether a row was removed.
1087
+ */
1088
+ unsuppress(email: string, ctx?: CrmContext): Promise<boolean>;
1089
+ }
1090
+ //#endregion
849
1091
  //#region src/repositories/activity.repository.d.ts
850
1092
  interface ActivityRepositoryDeps {
851
- events: EventTransport;
1093
+ events: CrmEventDispatcher;
852
1094
  }
853
1095
  declare class ActivityRepository extends Repository<IActivityDocument> {
854
1096
  private readonly events;
@@ -885,7 +1127,7 @@ declare class ActivityRepository extends Repository<IActivityDocument> {
885
1127
  //#endregion
886
1128
  //#region src/repositories/note.repository.d.ts
887
1129
  interface NoteRepositoryDeps {
888
- events: EventTransport;
1130
+ events: CrmEventDispatcher;
889
1131
  }
890
1132
  declare class NoteRepository extends Repository<INoteDocument> {
891
1133
  private readonly events;
@@ -895,7 +1137,7 @@ declare class NoteRepository extends Repository<INoteDocument> {
895
1137
  //#endregion
896
1138
  //#region src/repositories/loss-reason.repository.d.ts
897
1139
  interface LossReasonRepositoryDeps {
898
- events: EventTransport;
1140
+ events: CrmEventDispatcher;
899
1141
  }
900
1142
  declare class LossReasonRepository extends Repository<ILossReasonDocument> {
901
1143
  private readonly events;
@@ -906,7 +1148,7 @@ declare class LossReasonRepository extends Repository<ILossReasonDocument> {
906
1148
  //#endregion
907
1149
  //#region src/repositories/email-event.repository.d.ts
908
1150
  interface EmailEventRepositoryDeps {
909
- events: EventTransport;
1151
+ events: CrmEventDispatcher;
910
1152
  }
911
1153
  interface RecordEmailEventInput {
912
1154
  subjectKind: EmailEventSubjectKind;
@@ -931,7 +1173,7 @@ declare class EmailEventRepository extends Repository<IEmailEventDocument> {
931
1173
  //#endregion
932
1174
  //#region src/repositories/conversation.repository.d.ts
933
1175
  interface ConversationRepositoryDeps {
934
- events: EventTransport;
1176
+ events: CrmEventDispatcher;
935
1177
  }
936
1178
  interface OpenConversationInput {
937
1179
  channel: ConversationChannel;
@@ -965,7 +1207,7 @@ declare class ConversationRepository extends Repository<IConversationDocument> {
965
1207
  //#endregion
966
1208
  //#region src/repositories/message.repository.d.ts
967
1209
  interface MessageRepositoryDeps {
968
- events: EventTransport;
1210
+ events: CrmEventDispatcher;
969
1211
  conversations: ConversationRepository;
970
1212
  }
971
1213
  interface RecordMessageInput {
@@ -991,6 +1233,81 @@ declare class MessageRepository extends Repository<IMessageDocument> {
991
1233
  findRecentForFeed(limit: number, ctx?: CrmContext): Promise<IMessageDocument[]>;
992
1234
  }
993
1235
  //#endregion
1236
+ //#region src/repositories/sequence.repository.d.ts
1237
+ interface SequenceRepositoryDeps {
1238
+ events: CrmEventDispatcher;
1239
+ }
1240
+ declare class SequenceRepository extends Repository<ISequenceDocument> {
1241
+ private readonly events;
1242
+ constructor(model: Model<ISequenceDocument>, plugins: PluginType[], deps: SequenceRepositoryDeps, pagination?: PaginationConfig);
1243
+ activate(id: string, ctx?: CrmContext): Promise<ISequenceDocument>;
1244
+ activateFromPaused(id: string, ctx?: CrmContext): Promise<ISequenceDocument>;
1245
+ pause(id: string, ctx?: CrmContext): Promise<ISequenceDocument>;
1246
+ archive(id: string, ctx?: CrmContext): Promise<ISequenceDocument>;
1247
+ private _transition;
1248
+ }
1249
+ //#endregion
1250
+ //#region src/repositories/enrollment.repository.d.ts
1251
+ interface EnrollmentRepositoryDeps {
1252
+ events: CrmEventDispatcher;
1253
+ /** Cross-repo reference: read `replyDetectionEnabled` from Sequence. */
1254
+ sequences: SequenceRepository;
1255
+ }
1256
+ /** A subject that just replied — input to `exitActiveOnReply()`. */
1257
+ interface ReplySubject {
1258
+ subjectKind: EnrollmentSubjectKind;
1259
+ subjectId: string;
1260
+ }
1261
+ interface EnrollInput {
1262
+ sequenceId: string;
1263
+ subjectKind: EnrollmentSubjectKind;
1264
+ subjectId: string;
1265
+ workflowRunId?: string;
1266
+ ownerId?: string;
1267
+ metadata?: Record<string, unknown>;
1268
+ }
1269
+ declare class EnrollmentRepository extends Repository<IEnrollmentDocument> {
1270
+ private readonly events;
1271
+ private readonly sequences;
1272
+ constructor(model: Model<IEnrollmentDocument>, plugins: PluginType[], deps: EnrollmentRepositoryDeps, pagination?: PaginationConfig);
1273
+ /** Create a new enrollment — throws AlreadyEnrolledError if an active one exists. */
1274
+ enroll(input: EnrollInput, ctx?: CrmContext): Promise<IEnrollmentDocument>;
1275
+ /** Set workflowRunId after the workflow has started. */
1276
+ setWorkflowRunId(id: string, workflowRunId: string, ctx?: CrmContext): Promise<void>;
1277
+ /** Atomically advance to the next step and record the result (CAS). */
1278
+ advanceStep(id: string, nextStepIndex: number, stepResult: IStepResult | null, ctx?: CrmContext): Promise<IEnrollmentDocument | null>;
1279
+ pause(id: string, ctx?: CrmContext): Promise<IEnrollmentDocument>;
1280
+ resume(id: string, ctx?: CrmContext): Promise<IEnrollmentDocument>;
1281
+ complete(id: string, ctx?: CrmContext): Promise<IEnrollmentDocument>;
1282
+ exit(id: string, exitReason: IEnrollmentDocument['exitReason'], ctx?: CrmContext): Promise<IEnrollmentDocument>;
1283
+ /**
1284
+ * Reply detection: exit every ACTIVE enrollment of the given subjects
1285
+ * with reason `'reply'` — the one method a host's
1286
+ * `crm:message.received` subscriber calls:
1287
+ *
1288
+ * ```ts
1289
+ * crm.events.subscribe('crm:message.received', async (e) => {
1290
+ * await crm.repositories.enrollment.exitActiveOnReply(
1291
+ * [{ subjectKind: 'contact', subjectId: e.payload.participantId }],
1292
+ * { organizationId: e.meta.organizationId },
1293
+ * );
1294
+ * });
1295
+ * ```
1296
+ *
1297
+ * Sequences are batch-loaded in ONE `$in` query; enrollments whose
1298
+ * sequence has `replyDetectionEnabled === false` are skipped (a missing
1299
+ * sequence — e.g. deleted — does NOT skip: the default is to exit).
1300
+ * Each exit goes through `exit()` (state-machine CAS + statusHistory +
1301
+ * ENROLLMENT_EXITED event). An enrollment that a concurrent transition
1302
+ * already moved out of `active` loses the CAS and is skipped — the
1303
+ * desired end state ("not active") already holds.
1304
+ *
1305
+ * Returns the enrollments this call actually exited.
1306
+ */
1307
+ exitActiveOnReply(subjects: ReplySubject[], ctx?: CrmContext): Promise<IEnrollmentDocument[]>;
1308
+ private _transition;
1309
+ }
1310
+ //#endregion
994
1311
  //#region src/engine/engine-types.d.ts
995
1312
  interface CrmLogger {
996
1313
  info?(msg: string, meta?: Record<string, unknown>): void;
@@ -1016,6 +1333,14 @@ interface CrmConfig {
1016
1333
  multiTenant?: boolean;
1017
1334
  /** Arc-compatible event transport. Default: in-process bus. */
1018
1335
  eventTransport?: EventTransport;
1336
+ /**
1337
+ * Transactional outbox (PACKAGE_RULES §P8). When wired, every domain
1338
+ * event is persisted via `outbox.save(event, { session })` in the SAME
1339
+ * session as the business write — the host's relay publishes committed
1340
+ * rows. Without it, events publish post-write (or defer to a
1341
+ * `ctx[PENDING_EVENTS]` queue inside `engine.withTransaction`).
1342
+ */
1343
+ outbox?: OutboxStore;
1019
1344
  /** Logger surface used by the in-process bus + repositories. */
1020
1345
  logger?: CrmLogger;
1021
1346
  /** Pagination defaults for every repository (mongokit). */
@@ -1059,22 +1384,43 @@ interface CrmRepositories {
1059
1384
  account: AccountRepository;
1060
1385
  campaign: CampaignRepository;
1061
1386
  subscription: SubscriptionRepository;
1387
+ suppression: SuppressionRepository;
1062
1388
  activity: ActivityRepository;
1063
1389
  note: NoteRepository;
1064
1390
  lossReason: LossReasonRepository;
1065
1391
  emailEvent: EmailEventRepository;
1066
1392
  conversation: ConversationRepository;
1067
1393
  message: MessageRepository;
1394
+ sequence: SequenceRepository;
1395
+ enrollment: EnrollmentRepository;
1068
1396
  }
1069
1397
  interface CrmEngine {
1070
1398
  /** Repositories ARE the API surface (PACKAGE_RULES §1). */
1071
1399
  readonly repositories: Readonly<CrmRepositories>;
1072
- /** Arc-compatible event transport. */
1073
- readonly events: EventTransport;
1400
+ /**
1401
+ * Arc-compatible event transport (a `CrmEventDispatcher` wrapping the
1402
+ * configured transport — `publish`/`subscribe` behave exactly like the
1403
+ * raw transport for hosts).
1404
+ */
1405
+ readonly events: CrmEventDispatcher;
1074
1406
  /** Mongoose models — for arc adapter wiring. */
1075
1407
  readonly models: Readonly<CrmModels>;
1076
1408
  /** Resolved configuration (frozen). */
1077
1409
  readonly config: Readonly<ResolvedCrmConfig>;
1410
+ /**
1411
+ * Run `body` inside a MongoDB transaction with post-commit event
1412
+ * discipline (PACKAGE_RULES §P8.1): events dispatched through `txCtx`
1413
+ * are queued and flushed to the transport only AFTER commit — an abort
1414
+ * leaks nothing to in-process subscribers. When `ctx.session` is already
1415
+ * set, the caller's transaction (and queue, if attached) is reused.
1416
+ *
1417
+ * ```ts
1418
+ * await engine.withTransaction(ctx, async (txCtx) => {
1419
+ * return leadService.convert(leadId, input, txCtx);
1420
+ * });
1421
+ * ```
1422
+ */
1423
+ withTransaction<T>(ctx: CrmContext, body: (txCtx: CrmContext) => Promise<T>): Promise<T>;
1078
1424
  /**
1079
1425
  * Build/align every model's indexes against its schema. Call once per
1080
1426
  * deploy when booted with `autoIndex: false` (§35). Idempotent.
@@ -1102,7 +1448,7 @@ declare function createCrm(config: CrmConfig): Promise<CrmEngine>;
1102
1448
  //#endregion
1103
1449
  //#region src/repositories/create-repositories.d.ts
1104
1450
  interface CreateCrmRepositoriesDeps {
1105
- events: EventTransport;
1451
+ events: CrmEventDispatcher;
1106
1452
  config: ResolvedCrmConfig;
1107
1453
  }
1108
1454
  declare function createCrmRepositories(models: CrmModels, deps: CreateCrmRepositoriesDeps): CrmRepositories;
@@ -1135,7 +1481,7 @@ interface LeadServiceDeps {
1135
1481
  contact: ContactRepository;
1136
1482
  account: AccountRepository;
1137
1483
  opportunity: OpportunityRepository;
1138
- events: EventTransport;
1484
+ events: CrmEventDispatcher;
1139
1485
  }
1140
1486
  declare class LeadService {
1141
1487
  private readonly leads;
@@ -1208,6 +1554,16 @@ declare const CRM_EVENTS: {
1208
1554
  readonly SUBSCRIPTION_UNSUBSCRIBED: "crm:subscription.unsubscribed";
1209
1555
  readonly SUBSCRIPTION_BOUNCED: "crm:subscription.bounced";
1210
1556
  readonly SUBSCRIPTION_COMPLAINED: "crm:subscription.complained";
1557
+ readonly SEQUENCE_CREATED: "crm:sequence.created";
1558
+ readonly SEQUENCE_ACTIVATED: "crm:sequence.active";
1559
+ readonly SEQUENCE_PAUSED: "crm:sequence.paused";
1560
+ readonly SEQUENCE_ARCHIVED: "crm:sequence.archived";
1561
+ readonly ENROLLMENT_CREATED: "crm:enrollment.created";
1562
+ readonly ENROLLMENT_STEP_SENT: "crm:enrollment.step_sent";
1563
+ readonly ENROLLMENT_PAUSED: "crm:enrollment.paused";
1564
+ readonly ENROLLMENT_RESUMED: "crm:enrollment.resumed";
1565
+ readonly ENROLLMENT_COMPLETED: "crm:enrollment.completed";
1566
+ readonly ENROLLMENT_EXITED: "crm:enrollment.exited";
1211
1567
  readonly EMAIL_EVENT_OPENED: "crm:email_event.opened";
1212
1568
  readonly EMAIL_EVENT_CLICKED: "crm:email_event.clicked";
1213
1569
  readonly EMAIL_EVENT_BOUNCED: "crm:email_event.bounced";
@@ -1226,6 +1582,8 @@ declare const CRM_EVENTS: {
1226
1582
  readonly OPPORTUNITY_EXTENDED: "crm:opportunity.extended";
1227
1583
  readonly ACTIVITY_RESCHEDULED: "crm:activity.rescheduled";
1228
1584
  readonly ACTIVITY_OUTCOME_RECORDED: "crm:activity.outcome_recorded";
1585
+ readonly SUPPRESSION_ADDED: "crm:suppression.added";
1586
+ readonly SUPPRESSION_REMOVED: "crm:suppression.removed";
1229
1587
  readonly CONVERSATION_CREATED: "crm:conversation.created";
1230
1588
  readonly CONVERSATION_ASSIGNED: "crm:conversation.assigned";
1231
1589
  readonly CONVERSATION_RESOLVED: "crm:conversation.resolved";
@@ -1474,6 +1832,19 @@ declare const SubscriptionComplained: CrmEventDefinition<z.ZodObject<{
1474
1832
  contactId: z.ZodString;
1475
1833
  campaignId: z.ZodString;
1476
1834
  }, z.core.$strip>>;
1835
+ declare const SuppressionAdded: CrmEventDefinition<z.ZodObject<{
1836
+ email: z.ZodString;
1837
+ reason: z.ZodEnum<{
1838
+ bounce: "bounce";
1839
+ complaint: "complaint";
1840
+ unsubscribe: "unsubscribe";
1841
+ manual: "manual";
1842
+ }>;
1843
+ source: z.ZodOptional<z.ZodString>;
1844
+ }, z.core.$strip>>;
1845
+ declare const SuppressionRemoved: CrmEventDefinition<z.ZodObject<{
1846
+ email: z.ZodString;
1847
+ }, z.core.$strip>>;
1477
1848
  declare const EmailEventOpened: CrmEventDefinition<z.ZodObject<{
1478
1849
  eventId: z.ZodString;
1479
1850
  kind: z.ZodString;
@@ -1542,6 +1913,44 @@ declare const MessageSent: CrmEventDefinition<z.ZodObject<{
1542
1913
  direction: z.ZodString;
1543
1914
  externalMessageId: z.ZodOptional<z.ZodString>;
1544
1915
  }, z.core.$strip>>;
1916
+ declare const SequenceCreated: CrmEventDefinition<z.ZodObject<{
1917
+ sequenceId: z.ZodString;
1918
+ name: z.ZodOptional<z.ZodString>;
1919
+ }, z.core.$strip>>;
1920
+ declare const SequenceActivated: CrmEventDefinition<z.ZodObject<{
1921
+ sequenceId: z.ZodString;
1922
+ }, z.core.$strip>>;
1923
+ declare const SequencePaused: CrmEventDefinition<z.ZodObject<{
1924
+ sequenceId: z.ZodString;
1925
+ }, z.core.$strip>>;
1926
+ declare const SequenceArchived: CrmEventDefinition<z.ZodObject<{
1927
+ sequenceId: z.ZodString;
1928
+ }, z.core.$strip>>;
1929
+ declare const EnrollmentCreated: CrmEventDefinition<z.ZodObject<{
1930
+ enrollmentId: z.ZodString;
1931
+ sequenceId: z.ZodString;
1932
+ subjectId: z.ZodString;
1933
+ subjectKind: z.ZodString;
1934
+ }, z.core.$strip>>;
1935
+ declare const EnrollmentStepSent: CrmEventDefinition<z.ZodObject<{
1936
+ enrollmentId: z.ZodString;
1937
+ sequenceId: z.ZodOptional<z.ZodString>;
1938
+ stepIndex: z.ZodNumber;
1939
+ channel: z.ZodOptional<z.ZodString>;
1940
+ }, z.core.$strip>>;
1941
+ declare const EnrollmentPaused: CrmEventDefinition<z.ZodObject<{
1942
+ enrollmentId: z.ZodString;
1943
+ }, z.core.$strip>>;
1944
+ declare const EnrollmentResumed: CrmEventDefinition<z.ZodObject<{
1945
+ enrollmentId: z.ZodString;
1946
+ }, z.core.$strip>>;
1947
+ declare const EnrollmentCompleted: CrmEventDefinition<z.ZodObject<{
1948
+ enrollmentId: z.ZodString;
1949
+ }, z.core.$strip>>;
1950
+ declare const EnrollmentExited: CrmEventDefinition<z.ZodObject<{
1951
+ enrollmentId: z.ZodString;
1952
+ exitReason: z.ZodOptional<z.ZodString>;
1953
+ }, z.core.$strip>>;
1545
1954
  declare const crmEventDefinitions: ReadonlyArray<CrmEventDefinition>;
1546
1955
  //#endregion
1547
1956
  //#region src/events/helpers.d.ts
@@ -1560,6 +1969,17 @@ declare class InProcessCrmBus implements EventTransport {
1560
1969
  close(): Promise<void>;
1561
1970
  }
1562
1971
  //#endregion
1972
+ //#region src/engine/run-unit.d.ts
1973
+ interface RunUnitConfig {
1974
+ connection: Connection;
1975
+ /** Transport used for the post-commit flush. */
1976
+ events: Pick<EventTransport, 'publish'> | undefined;
1977
+ logger?: CrmLogger | undefined;
1978
+ /** Standalone-Mongo fallback (local dev) — partial-write risk, explicit opt-in. */
1979
+ allowNonTransactional: boolean;
1980
+ }
1981
+ declare function runUnit<T>(config: RunUnitConfig, ctx: CrmContext, body: (innerCtx: CrmContext) => Promise<T>): Promise<T>;
1982
+ //#endregion
1563
1983
  //#region src/core/state-machines.d.ts
1564
1984
  /**
1565
1985
  * Declarative state machines for every CRM aggregate that has lifecycle
@@ -1581,6 +2001,8 @@ declare const OPPORTUNITY_MACHINE: _$_classytic_primitives_state_machine0.StateM
1581
2001
  declare const CAMPAIGN_MACHINE: _$_classytic_primitives_state_machine0.StateMachine<"draft" | "active" | "paused" | "completed" | "archived">;
1582
2002
  declare const SUBSCRIPTION_MACHINE: _$_classytic_primitives_state_machine0.StateMachine<"pending" | "confirmed" | "unsubscribed" | "bounced" | "complained">;
1583
2003
  declare const ACTIVITY_MACHINE: _$_classytic_primitives_state_machine0.StateMachine<"completed" | "planned" | "in_progress" | "cancelled">;
2004
+ declare const SEQUENCE_MACHINE: _$_classytic_primitives_state_machine0.StateMachine<"draft" | "active" | "paused" | "archived">;
2005
+ declare const ENROLLMENT_MACHINE: _$_classytic_primitives_state_machine0.StateMachine<"active" | "paused" | "completed" | "exited">;
1584
2006
  //#endregion
1585
2007
  //#region src/core/errors.d.ts
1586
2008
  /**
@@ -1630,6 +2052,9 @@ declare class DuplicateLeadError extends CrmError {
1630
2052
  phone?: string;
1631
2053
  });
1632
2054
  }
2055
+ declare class UnmanagedSessionError extends CrmError {
2056
+ constructor(eventType?: string);
2057
+ }
1633
2058
  declare class EmptyPipelineError extends CrmError {
1634
2059
  constructor(pipelineId: string);
1635
2060
  }
@@ -1662,6 +2087,26 @@ declare class InvalidConfirmationTokenError extends CrmError {
1662
2087
  declare class InvalidUnsubscribeTokenError extends CrmError {
1663
2088
  constructor();
1664
2089
  }
2090
+ declare class InvalidSequenceTransitionError extends CrmError {
2091
+ constructor(details: {
2092
+ from: string;
2093
+ to: string;
2094
+ sequenceId: string;
2095
+ });
2096
+ }
2097
+ declare class InvalidEnrollmentTransitionError extends CrmError {
2098
+ constructor(details: {
2099
+ from: string;
2100
+ to: string;
2101
+ enrollmentId: string;
2102
+ });
2103
+ }
2104
+ declare class AlreadyEnrolledError extends CrmError {
2105
+ constructor(details: {
2106
+ sequenceId: string;
2107
+ subjectId: string;
2108
+ });
2109
+ }
1665
2110
  //#endregion
1666
2111
  //#region src/shared/calculators/forecast.d.ts
1667
2112
  type OpportunityForecast = Pick<IOpportunityDocument, 'amount' | 'currency' | 'probability' | 'status' | 'expectedCloseAt' | 'stageId' | 'statusHistory'>;
@@ -1681,6 +2126,14 @@ interface ForecastOptions {
1681
2126
  bucket?: (o: OpportunityForecast) => string;
1682
2127
  /** Filter before bucketing. Default: open + has amount + has expectedCloseAt. */
1683
2128
  include?: (o: OpportunityForecast) => boolean;
2129
+ /**
2130
+ * IANA zone for the default month bucket (e.g. `'Asia/Dhaka'`). Without
2131
+ * it, months are cut at UTC boundaries — a deal expected to close
2132
+ * July 1, 02:00 Dhaka time (June 30, 20:00 UTC) lands in the JUNE
2133
+ * bucket. Ignored when a custom `bucket` fn is supplied. Invalid zones
2134
+ * throw (same contract as `@classytic/primitives/timezone`).
2135
+ */
2136
+ timeZone?: string;
1684
2137
  }
1685
2138
  /**
1686
2139
  * Aggregate opportunities into a forecast table — one row per bucket.
@@ -2045,6 +2498,35 @@ type SubscribeDto = z.infer<typeof subscribeSchema>;
2045
2498
  type ConfirmSubscriptionDto = z.infer<typeof confirmSubscriptionSchema>;
2046
2499
  type UnsubscribeDto = z.infer<typeof unsubscribeSchema>;
2047
2500
  //#endregion
2501
+ //#region src/validators/suppression.schema.d.ts
2502
+ declare const suppressSchema: z.ZodObject<{
2503
+ email: z.ZodString;
2504
+ reason: z.ZodEnum<{
2505
+ bounce: "bounce";
2506
+ complaint: "complaint";
2507
+ unsubscribe: "unsubscribe";
2508
+ manual: "manual";
2509
+ }>;
2510
+ source: z.ZodOptional<z.ZodString>;
2511
+ subjectKind: z.ZodOptional<z.ZodString>;
2512
+ subjectId: z.ZodOptional<z.ZodString>;
2513
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2514
+ }, z.core.$strip>;
2515
+ declare const unsuppressSchema: z.ZodObject<{
2516
+ email: z.ZodString;
2517
+ }, z.core.$strip>;
2518
+ declare const suppressionFilterSchema: z.ZodObject<{
2519
+ email: z.ZodOptional<z.ZodString>;
2520
+ reason: z.ZodOptional<z.ZodEnum<{
2521
+ bounce: "bounce";
2522
+ complaint: "complaint";
2523
+ unsubscribe: "unsubscribe";
2524
+ manual: "manual";
2525
+ }>>;
2526
+ }, z.core.$strip>;
2527
+ type SuppressDto = z.infer<typeof suppressSchema>;
2528
+ type UnsuppressDto = z.infer<typeof unsuppressSchema>;
2529
+ //#endregion
2048
2530
  //#region src/validators/activity.schema.d.ts
2049
2531
  declare const planActivitySchema: z.ZodObject<{
2050
2532
  type: z.ZodEnum<{
@@ -2220,8 +2702,101 @@ declare const emailEventFilterSchema: z.ZodObject<{
2220
2702
  messageId: z.ZodOptional<z.ZodString>;
2221
2703
  }, z.core.$strip>;
2222
2704
  type RecordEmailEventDto = z.infer<typeof recordEmailEventSchema>;
2705
+ //#endregion
2706
+ //#region src/validators/sequence.schema.d.ts
2707
+ declare const sequenceStepSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2708
+ id: z.ZodString;
2709
+ type: z.ZodLiteral<"SEND_EMAIL">;
2710
+ name: z.ZodOptional<z.ZodString>;
2711
+ subject: z.ZodString;
2712
+ htmlBody: z.ZodString;
2713
+ fromName: z.ZodOptional<z.ZodString>;
2714
+ fromEmail: z.ZodOptional<z.ZodString>;
2715
+ }, z.core.$strip>, z.ZodObject<{
2716
+ id: z.ZodString;
2717
+ type: z.ZodLiteral<"DELAY">;
2718
+ name: z.ZodOptional<z.ZodString>;
2719
+ settings: z.ZodObject<{
2720
+ days: z.ZodOptional<z.ZodNumber>;
2721
+ hours: z.ZodOptional<z.ZodNumber>;
2722
+ minutes: z.ZodOptional<z.ZodNumber>;
2723
+ }, z.core.$strip>;
2724
+ }, z.core.$strip>], "type">;
2725
+ declare const createSequenceSchema: z.ZodObject<{
2726
+ name: z.ZodString;
2727
+ description: z.ZodOptional<z.ZodString>;
2728
+ fromName: z.ZodOptional<z.ZodString>;
2729
+ fromEmail: z.ZodOptional<z.ZodString>;
2730
+ steps: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
2731
+ id: z.ZodString;
2732
+ type: z.ZodLiteral<"SEND_EMAIL">;
2733
+ name: z.ZodOptional<z.ZodString>;
2734
+ subject: z.ZodString;
2735
+ htmlBody: z.ZodString;
2736
+ fromName: z.ZodOptional<z.ZodString>;
2737
+ fromEmail: z.ZodOptional<z.ZodString>;
2738
+ }, z.core.$strip>, z.ZodObject<{
2739
+ id: z.ZodString;
2740
+ type: z.ZodLiteral<"DELAY">;
2741
+ name: z.ZodOptional<z.ZodString>;
2742
+ settings: z.ZodObject<{
2743
+ days: z.ZodOptional<z.ZodNumber>;
2744
+ hours: z.ZodOptional<z.ZodNumber>;
2745
+ minutes: z.ZodOptional<z.ZodNumber>;
2746
+ }, z.core.$strip>;
2747
+ }, z.core.$strip>], "type">>>;
2748
+ replyDetectionEnabled: z.ZodDefault<z.ZodBoolean>;
2749
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
2750
+ ownerId: z.ZodOptional<z.ZodString>;
2751
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2752
+ }, z.core.$strip>;
2753
+ declare const updateSequenceSchema: z.ZodObject<{
2754
+ name: z.ZodOptional<z.ZodString>;
2755
+ description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
2756
+ fromName: z.ZodOptional<z.ZodOptional<z.ZodString>>;
2757
+ fromEmail: z.ZodOptional<z.ZodOptional<z.ZodString>>;
2758
+ steps: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
2759
+ id: z.ZodString;
2760
+ type: z.ZodLiteral<"SEND_EMAIL">;
2761
+ name: z.ZodOptional<z.ZodString>;
2762
+ subject: z.ZodString;
2763
+ htmlBody: z.ZodString;
2764
+ fromName: z.ZodOptional<z.ZodString>;
2765
+ fromEmail: z.ZodOptional<z.ZodString>;
2766
+ }, z.core.$strip>, z.ZodObject<{
2767
+ id: z.ZodString;
2768
+ type: z.ZodLiteral<"DELAY">;
2769
+ name: z.ZodOptional<z.ZodString>;
2770
+ settings: z.ZodObject<{
2771
+ days: z.ZodOptional<z.ZodNumber>;
2772
+ hours: z.ZodOptional<z.ZodNumber>;
2773
+ minutes: z.ZodOptional<z.ZodNumber>;
2774
+ }, z.core.$strip>;
2775
+ }, z.core.$strip>], "type">>>>;
2776
+ replyDetectionEnabled: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
2777
+ tags: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
2778
+ ownerId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
2779
+ metadata: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
2780
+ }, z.core.$strip>;
2781
+ declare const sequenceFilterSchema: z.ZodObject<{
2782
+ status: z.ZodOptional<z.ZodEnum<{
2783
+ draft: "draft";
2784
+ active: "active";
2785
+ paused: "paused";
2786
+ archived: "archived";
2787
+ }>>;
2788
+ ownerId: z.ZodOptional<z.ZodString>;
2789
+ tags: z.ZodOptional<z.ZodString>;
2790
+ search: z.ZodOptional<z.ZodString>;
2791
+ page: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
2792
+ limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
2793
+ sort: z.ZodOptional<z.ZodString>;
2794
+ }, z.core.$strip>;
2795
+ type CreateSequenceInput = z.infer<typeof createSequenceSchema>;
2796
+ type UpdateSequenceInput = z.infer<typeof updateSequenceSchema>;
2797
+ type SequenceFilterInput = z.infer<typeof sequenceFilterSchema>;
2223
2798
  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 };
2799
+ export { AddNoteDto, CancelActivityDto, CloseLossDto, CloseWinDto, CompleteCampaignDto, ConfirmSubscriptionDto, ConvertLeadDto, CreateAccountDto, CreateCampaignDto, CreateContactDto, CreateLeadDto, CreateLossReasonDto, CreatePipelineDto, CreateSequenceInput, LeadFilterDto, MoveStageDto, OpenOpportunityDto, OpportunityFilterDto, PlanActivityDto, RecordEmailEventDto, SequenceFilterInput, StageInputDto, SubscribeDto, SuppressDto, UnsubscribeDto, UnsuppressDto, UpdateAccountDto, UpdateCampaignDto, UpdateContactDto, UpdateLeadDto, UpdateLossReasonDto, UpdateNoteDto, UpdatePipelineDto, UpdateSequenceInput, accountFilterSchema, activityFilterSchema, addNoteSchema, campaignFilterSchema, cancelActivitySchema, closeLossSchema, closeWinSchema, completeCampaignSchema, confirmSubscriptionSchema, contactFilterSchema, convertLeadSchema, createAccountSchema, createCampaignSchema, createContactSchema, createLeadSchema, createLossReasonSchema, createPipelineSchema, createSequenceSchema, currencyCodeSchema, emailEventFilterSchema, leadFilterSchema, lossReasonFilterSchema, metadataSchema, moneyAmountSchema, moveStageSchema, noteFilterSchema, objectIdLike, openOpportunitySchema, opportunityFilterSchema, pipelineFilterSchema, planActivitySchema, recordEmailEventSchema, sequenceFilterSchema, sequenceStepSchema, stageInputSchemaExport, subscribeSchema, subscriptionFilterSchema, suppressSchema, suppressionFilterSchema, tagsSchema, unsubscribeSchema, unsuppressSchema, updateAccountSchema, updateActivitySchema, updateCampaignSchema, updateContactSchema, updateLeadSchema, updateLossReasonSchema, updateNoteSchema, updatePipelineSchema, updateSequenceSchema };
2225
2800
  }
2226
2801
  //#endregion
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 };
2802
+ 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, AlreadyEnrolledError, 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, CrmEventDispatcher, type CrmEventDispatcherOptions, CrmEventName, CrmEventSchema, CrmLogger, CrmModels, CrmRepositories, DuplicateCampaignError, DuplicateLeadError, DuplicateSubscriptionError, EMAIL_EVENT_KINDS, EMAIL_EVENT_SUBJECT_KINDS, ENROLLMENT_MACHINE, ENROLLMENT_STATUSES, ENROLLMENT_SUBJECT_KINDS, ENROLLMENT_TRANSITIONS, EVENT_DERIVED_SUPPRESSION_REASONS, EmailEventBounced, EmailEventClicked, EmailEventComplained, type EmailEventKind, EmailEventOpened, EmailEventRepository, EmailEventRepositoryDeps, EmailEventSubjectKind, EmailEventUnsubscribed, EmptyPipelineError, EnrollInput, EnrollmentCompleted, EnrollmentCreated, EnrollmentExitReason, EnrollmentExited, EnrollmentPaused, EnrollmentRepository, EnrollmentRepositoryDeps, EnrollmentResumed, type EnrollmentStatus, EnrollmentStepSent, EnrollmentSubjectKind, ForecastOptions, ForecastRow, type IAccountDocument, type IActivityDocument, type ICampaignDocument, ICampaignStatusEntry, type IContactDocument, IContactInfoEmbedded, IContactName, type IConversationDocument, IDelayStep, type IEmailEventDocument, type IEnrollmentDocument, IEnrollmentStatusEntry, type ILeadDocument, ILeadStatusEntry, type ILossReasonDocument, IMessageAttachment, type IMessageDocument, type INoteDocument, type IOpportunityDocument, IOpportunityStatusEntry, type IPipelineDocument, ISendEmailStep, type ISequenceDocument, ISequenceStatusEntry, IStageDocument, IStepResult, type ISubscriptionDocument, ISubscriptionStatusEntry, type ISuppressionDocument, InProcessCrmBus, type InternalCrmContext, InvalidActivityTransitionError, InvalidCampaignTransitionError, InvalidConfirmationTokenError, InvalidEnrollmentTransitionError, InvalidLeadTransitionError, InvalidOpportunityTransitionError, InvalidSequenceTransitionError, 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, PENDING_EVENTS, PipelineArchived, PipelineCreated, PipelineRepository, PipelineRepositoryDeps, RecordEmailEventInput, RecordMessageInput, ReplySubject, ResolvedCrmConfig, type RunUnitConfig, SEQUENCE_MACHINE, SEQUENCE_STATUSES, SEQUENCE_TRANSITIONS, SUBJECT_KINDS, SUBSCRIPTION_MACHINE, SUBSCRIPTION_STATUSES, SUBSCRIPTION_TRANSITIONS, SUPPRESSION_REASONS, SchemaBuildConfig, SequenceActivated, SequenceArchived, SequenceCreated, SequencePaused, SequenceRepository, SequenceRepositoryDeps, type SequenceStatus, SequenceStep, StageNotInPipelineError, type StatusChangeEntry, type StatusHistory, StepResultStatus, type SubjectKind, SubscribeInput, SubscriptionBounced, SubscriptionComplained, SubscriptionConfirmed, SubscriptionCreated, SubscriptionRepository, SubscriptionRepositoryDeps, type SubscriptionStatus, SubscriptionUnsubscribed, SuppressInput, SuppressionAdded, type SuppressionReason, SuppressionRemoved, SuppressionRepository, SuppressionRepositoryDeps, TenantFieldType, UnmanagedSessionError, _ModelTypes, appendStatus, buildAccountSchema, buildActivitySchema, buildCampaignSchema, buildContactSchema, buildConversationSchema, buildEmailEventSchema, buildEnrollmentSchema, buildLeadSchema, buildLossReasonSchema, buildMessageSchema, buildNoteSchema, buildOpportunitySchema, buildPipelineSchema, buildSequenceSchema, buildSubscriptionSchema, buildSuppressionSchema, canTransitionActivity, canTransitionCampaign, canTransitionEnrollment, canTransitionLead, canTransitionOpportunity, canTransitionSequence, canTransitionSubscription, composeScorers, createAccountModel, createActivityModel, createCampaignModel, createContactModel, createConversationModel, createCrm, createCrmModels, createCrmRepositories, createEmailEventModel, createEvent, createLeadModel, createLossReasonModel, createMessageModel, createNoteModel, createOpportunityModel, createPipelineModel, createSubscriptionModel, crmEventDefinitions, defaultLeadScorer, flushPending, forecast, lastTransitionTo, latestEntry, pipelineConversion, runUnit, tenantFieldDef, timeInStatus, index_d_exports as validators };