Files
skills/plugins/document-navigator/docs/commerce/contacts/audience-rules/README.md
admin 9bf56a806b Move docs/ package mirror into document-navigator plugin
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>
2026-05-30 01:10:00 +01:00

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.ts defines the stable, namespaced error-code registry for the @suaveplan/audience-rules package, alongs…
    • error-codes — error-codes.ts defines the stable, namespaced error-code registry for the @suaveplan/audience-rules package, alongs…
  • predicates — predicates.ts ships seven factory functions that produce SegmentRule values for the most common audience filters: t…
    • predicates — predicates.ts ships seven factory functions that produce SegmentRule values for the most common audience filters: t…
  • schemas — schemas.ts exposes the Zod validators that guard every public input boundary on the @suaveplan/audience-rules store…
    • schemas — schemas.ts exposes the Zod validators that guard every public input boundary on the @suaveplan/audience-rules store…
  • segment-evaluator — segment-evaluator.ts provides the pure-function rule engine that decides, for a given Segment and a tenant's `Conta…
    • segment-evaluator — segment-evaluator.ts provides the pure-function rule engine that decides, for a given Segment and a tenant's `Conta…
  • segment-refresher — segment-refresher.ts orchestrates re-evaluation of one or many segments and persists the resulting contactIds back…
    • segment-refresher — segment-refresher.ts orchestrates re-evaluation of one or many segments and persists the resulting contactIds back…
  • store — store.ts defines the SegmentStore interface that abstracts segment persistence behind a six-method contract (`creat…
    • store — store.ts defines the SegmentStore interface that abstracts segment persistence behind a six-method contract (`creat…

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_CODES registry + AudienceRulesError.
  • schemas — Zod validators + parseOrThrow.
  • store — SegmentStore interface + InMemorySegmentStore with Clock + IdGenerator injection.
  • segment-evaluator — 14-operator rule engine with dot-notation field resolution and AND/OR chaining.
  • segment-refresher — re-evaluation orchestrator with typed EventBus emission.
  • predicates — seven SegmentRule factory 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 logicalOp on 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 tenantId on Segment and list.
  • Predicate factories for the seven most common audience filters.
  • Pluggable storage — provide a SegmentStore implementation backed by the persistence layer of your choice. InMemorySegmentStore is the reference implementation.
  • Typed event emission via EventBus<SegmentRefresherEventMap> from @suaveplan/events.
  • Stable AUDIENCE_RULES.* code registry with INVALID_INPUT, SEGMENT_NOT_FOUND, UNKNOWN_OPERATOR, PROVIDER_FAILED.

See also

  • @suaveplan/contacts — contact and group management, provides the ContactData consumed by audience-rules.
  • @suaveplan/events — typed EventBus<TMap> substrate.
  • @suaveplan/error — SuaveplanError + defineCodes.