95 lines
5.0 KiB
Markdown
95 lines
5.0 KiB
Markdown
# @suaveplan/campaigns - Universal campaign orchestration — engine, state machine, batch planner, workflow, and pluggable store with injectable Clock/IdGenerator/TimersLike/LoggerLike, CAMPAIGNS_CODES error registry, and OTel self-telemetry
|
|
|
|
Universal campaign orchestration.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [batch-planner](./src/batch-planner/batch-planner.md) — Deterministic batch-planning engine for campaign sends. Splits a contact list into sized batches with throttle-aware sc…
|
|
- [batch-planner](./src/batch-planner/batch-planner.md) — Deterministic batch-planning engine for campaign sends. Splits a contact list into sized batches with throttle-aware sc…
|
|
- [engine](./src/engine/engine.md) — Top-level orchestrator for campaign CRUD and lifecycle. `CampaignEngine` accepts an injectable `CampaignStore` and expo…
|
|
- [engine](./src/engine/engine.md) — Top-level orchestrator for campaign CRUD and lifecycle. `CampaignEngine` accepts an injectable `CampaignStore` and expo…
|
|
- [error-codes](./src/error-codes/error-codes.md) — Defines the stable, machine-readable error namespace for `@suaveplan/campaigns`. Every failure path in the package — fr…
|
|
- [error-codes](./src/error-codes/error-codes.md) — Defines the stable, machine-readable error namespace for `@suaveplan/campaigns`. Every failure path in the package — fr…
|
|
- [state-machine](./src/state-machine/state-machine.md) — Strictly typed lifecycle state machine for campaigns. Owns the set of nine legal transitions between the seven `Campaig…
|
|
- [state-machine](./src/state-machine/state-machine.md) — Strictly typed lifecycle state machine for campaigns. Owns the set of nine legal transitions between the seven `Campaig…
|
|
- [store](./src/store/store.md) — Defines the `CampaignStore` persistence contract and ships an `InMemoryCampaignStore` reference implementation. Every s…
|
|
- [store](./src/store/store.md) — Defines the `CampaignStore` persistence contract and ships an `InMemoryCampaignStore` reference implementation. Every s…
|
|
- [telemetry](./src/telemetry/telemetry.md) — OTel self-telemetry for `@suaveplan/campaigns`. Exposes a small set of counters and histograms that are emitted from ev…
|
|
- [telemetry](./src/telemetry/telemetry.md) — OTel self-telemetry for `@suaveplan/campaigns`. Exposes a small set of counters and histograms that are emitted from ev…
|
|
- [workflow](./src/workflow/workflow.md) — Composable multi-step send pipeline for campaigns. `CampaignWorkflow.buildSendPipeline` returns a canonical six-step pi…
|
|
- [workflow](./src/workflow/workflow.md) — Composable multi-step send pipeline for campaigns. `CampaignWorkflow.buildSendPipeline` returns a canonical six-step pi…
|
|
<!-- end:auto-docs -->
|
|
|
|
## Modules
|
|
|
|
- [`engine/`](./src/engine/engine.md) — `CampaignEngine`: CRUD + lifecycle methods over an injectable `CampaignStore`.
|
|
- [`state-machine/`](./src/state-machine/state-machine.md) — `CampaignStateMachine`: nine canonical transitions, typed event union.
|
|
- [`batch-planner/`](./src/batch-planner/batch-planner.md) — `BatchPlanner`: throttle-aware splitter + duration estimator.
|
|
- [`workflow/`](./src/workflow/workflow.md) — `CampaignWorkflow`: composable 6-step send pipeline + sequential runner.
|
|
- [`store/`](./src/store/store.md) — `CampaignStore` interface + `InMemoryCampaignStore` reference.
|
|
- [`error-codes/`](./src/error-codes/error-codes.md) — `CAMPAIGNS_CODES` + `CampaignsError`.
|
|
- [`telemetry/`](./src/telemetry/telemetry.md) — OTel meter, counters, histograms.
|
|
- [`types/`](./src/types/) — shared types.
|
|
|
|
## Install
|
|
|
|
```bash
|
|
bun add @suaveplan/campaigns
|
|
```
|
|
|
|
## Quick start
|
|
|
|
```ts
|
|
import { CampaignEngine, InMemoryCampaignStore } from "@suaveplan/campaigns";
|
|
|
|
const engine = new CampaignEngine(new InMemoryCampaignStore());
|
|
|
|
const campaign = await engine.create({
|
|
tenantId: "tenant-1",
|
|
name: "Spring Sale Announcement",
|
|
type: "broadcast",
|
|
channel: "email",
|
|
audienceConfig: {
|
|
groupIds: ["all-subscribers"],
|
|
excludeGroupIds: ["unsubscribed"],
|
|
},
|
|
templateId: "spring-sale-v1",
|
|
});
|
|
|
|
await engine.schedule(campaign.id, {
|
|
type: "scheduled",
|
|
sendAt: new Date("2026-05-01T09:00:00Z"),
|
|
timezone: "America/New_York",
|
|
});
|
|
|
|
await engine.send(campaign.id);
|
|
```
|
|
|
|
## Throttle-aware batch planning
|
|
|
|
```ts
|
|
import { BatchPlanner, type ThrottleConfig } from "@suaveplan/campaigns";
|
|
|
|
const planner = new BatchPlanner();
|
|
const throttle: ThrottleConfig = { messagesPerSecond: 50 };
|
|
const batches = planner.planBatches(contactIds, { batchSize: 200 }, throttle);
|
|
const etaMs = planner.calculateTotalDuration(contactIds.length, { batchSize: 200 }, throttle);
|
|
```
|
|
|
|
## Architecture
|
|
|
|
```
|
|
CampaignEngine ──┬── CampaignStateMachine (validation)
|
|
├── CampaignStore (persistence)
|
|
├── BatchPlanner (throttle-aware planning)
|
|
└── CampaignWorkflow (6-step pipeline)
|
|
```
|
|
|
|
All callers see `CampaignsError` with codes from `CAMPAIGNS_CODES`. All operations record OTel counters/histograms via the `telemetry/` module.
|
|
|
|
## License
|
|
|
|
MIT.
|
|
|