Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.9 KiB
5.9 KiB
@suaveplan/audience-rules - Universal audience segmentation: rule-based filtering with 14 comparison operators, AND/OR chaining, dot-notation field resolution including array indices, three refresh modes (realtime/scheduled/manual), seven predicate factories, pluggable SegmentStore with InMemorySegmentStore (Clock + IdGenerator injectable), SegmentRefresher with typed EventBus emission, Zod-validated boundaries, and AudienceRulesError with stable AUDIENCE_RULES.* code registry.
Universal audience segmentation: rule-based filtering on contact data
with 14 comparison operators, AND/OR chaining, dot-notation field
resolution including array indices, three refresh modes
(realtime/scheduled/manual), seven predicate factory helpers, a pluggable
SegmentStore with an InMemorySegmentStore (injectable Clock +
IdGenerator), and a SegmentRefresher that emits segment:refreshed
on a typed EventBus<SegmentRefresherEventMap>. Inputs are
Zod-validated; failures raise AudienceRulesError with a stable
AUDIENCE_RULES.* code registry.
Documentation tree
- error-codes —
error-codes.tsdefines the stable, namespaced error-code registry for the@suaveplan/audience-rulespackage, alongs…- error-codes —
error-codes.tsdefines the stable, namespaced error-code registry for the@suaveplan/audience-rulespackage, alongs…
- error-codes —
- predicates —
predicates.tsships seven factory functions that produceSegmentRulevalues for the most common audience filters: t…- predicates —
predicates.tsships seven factory functions that produceSegmentRulevalues for the most common audience filters: t…
- predicates —
- schemas —
schemas.tsexposes the Zod validators that guard every public input boundary on the@suaveplan/audience-rulesstore…- schemas —
schemas.tsexposes the Zod validators that guard every public input boundary on the@suaveplan/audience-rulesstore…
- schemas —
- segment-evaluator —
segment-evaluator.tsprovides the pure-function rule engine that decides, for a givenSegmentand a tenant's `Conta…- segment-evaluator —
segment-evaluator.tsprovides the pure-function rule engine that decides, for a givenSegmentand a tenant's `Conta…
- segment-evaluator —
- segment-refresher —
segment-refresher.tsorchestrates re-evaluation of one or many segments and persists the resultingcontactIdsback…- segment-refresher —
segment-refresher.tsorchestrates re-evaluation of one or many segments and persists the resultingcontactIdsback…
- segment-refresher —
- store —
store.tsdefines theSegmentStoreinterface that abstracts segment persistence behind a six-method contract (`creat…- store —
store.tsdefines theSegmentStoreinterface that abstracts segment persistence behind a six-method contract (`creat…
- store —
Install
bun add @suaveplan/audience-rules
Quick start
import {
InMemorySegmentStore,
SegmentEvaluator,
SegmentRefresher,
hasTag,
statusIs,
} from "@suaveplan/audience-rules";
const provider = async () => [
{ id: "c1", tags: ["vip"], status: "active" },
{ id: "c2", tags: ["basic"], status: "active" },
{ id: "c3", tags: ["vip"], status: "unsubscribed" },
];
const store = new InMemorySegmentStore();
const evaluator = new SegmentEvaluator(provider);
const refresher = new SegmentRefresher(store, evaluator);
const segment = await store.create({
tenantId: "tenant-1",
name: "Active VIPs",
rules: [hasTag("vip"), statusIs("active")],
refreshMode: "manual",
});
refresher.events.on("segment:refreshed", ({ segmentId, result }) => {
console.log(`${segmentId}: ${result.total} matches`);
});
await refresher.refresh(segment.id);
Modules
- error-codes —
AUDIENCE_RULES_CODESregistry +AudienceRulesError. - schemas — Zod validators +
parseOrThrow. - store —
SegmentStoreinterface +InMemorySegmentStorewithClock+IdGeneratorinjection. - segment-evaluator — 14-operator rule engine with dot-notation field resolution and AND/OR chaining.
- segment-refresher —
re-evaluation orchestrator with typed
EventBusemission. - predicates — seven
SegmentRulefactory helpers for tags, channels, status, activity dates, and metadata.
Features
- 14 operators:
eq,neq,gt,gte,lt,lte,contains,not_contains,in,not_in,exists,not_exists,starts_with,ends_with. - AND/OR logical chaining via
logicalOpon each rule. - Dot-notation field paths with numeric array indices
(
channels.0.type). - Three refresh modes for cache policy:
realtime,scheduled,manual. - Multi-tenant isolation via
tenantIdonSegmentandlist. - Predicate factories for the seven most common audience filters.
- Pluggable storage — provide a
SegmentStoreimplementation backed by the persistence layer of your choice.InMemorySegmentStoreis the reference implementation. - Typed event emission via
EventBus<SegmentRefresherEventMap>from@suaveplan/events. - Stable
AUDIENCE_RULES.*code registry withINVALID_INPUT,SEGMENT_NOT_FOUND,UNKNOWN_OPERATOR,PROVIDER_FAILED.
See also
@suaveplan/contacts— contact and group management, provides theContactDataconsumed by audience-rules.@suaveplan/events— typedEventBus<TMap>substrate.@suaveplan/error—SuaveplanError+defineCodes.