Files
skills/docs/commerce/contacts/contacts/README.md
2026-05-29 08:20:56 +01:00

9.7 KiB

@suaveplan/contacts - Universal contact and group management: hierarchical n-level groups (adjacency + materialized path), channel-agnostic contacts with dedup, many-to-many memberships with ancestor count propagation, audience resolution with descendant walk + dedup + filters, contact merger, CSV/JSON import-export, injectable Clock + IdGenerator, Zod input boundaries, six OTel counters and three histograms, and typed ContactsError hierarchy with stable CONTACTS.* code registry.

Universal contact and group management with hierarchical nesting, audience resolution, contact merger, and CSV/JSON import-export. Multi-tenant, channel-agnostic, deterministic (injectable Clock + IdGenerator), Zod-validated at every public boundary, OTel-instrumented via @suaveplan/opentelemetry, and ships a typed ContactsError hierarchy with a stable CONTACTS.* code registry.

Documentation tree

  • audience-resolver — AudienceResolver flattens a set of groups into a deduplicated, filtered contact list — the typical "send this campaig…
    • audience-resolver — AudienceResolver flattens a set of groups into a deduplicated, filtered contact list — the typical "send this campaig…
  • contact-manager — ContactManager is the public CRUD surface for contacts. It validates inputs against the corresponding Zod schemas (`c…
    • contact-manager — ContactManager is the public CRUD surface for contacts. It validates inputs against the corresponding Zod schemas (`c…
  • contact-merger — ContactMerger consolidates duplicate contacts into a single primary record. It merges channels (dedup-by-type:value…
    • contact-merger — ContactMerger consolidates duplicate contacts into a single primary record. It merges channels (dedup-by-type:value…
  • group-manager — GroupManager is the public surface for hierarchical groups. It manages n-level nesting via a hybrid adjacency-list +…
    • group-manager — GroupManager is the public surface for hierarchical groups. It manages n-level nesting via a hybrid adjacency-list +…
  • membership-manager — MembershipManager orchestrates many-to-many contact-group memberships. It owns the integrity guarantee that `Group.co…
    • membership-manager — MembershipManager orchestrates many-to-many contact-group memberships. It owns the integrity guarantee that `Group.co…
  • error-codes — Defines the stable error-code registry and typed ContactsError class for @suaveplan/contacts. Every failure path th…
    • error-codes — Defines the stable error-code registry and typed ContactsError class for @suaveplan/contacts. Every failure path th…
  • contact-exporter — ContactExporter serializes contacts to JSON or CSV with optional field inclusion flags. CSV output follows RFC 4180 q…
    • contact-exporter — ContactExporter serializes contacts to JSON or CSV with optional field inclusion flags. CSV output follows RFC 4180 q…
  • contact-importer — ContactImporter ingests contacts from already-parsed record arrays or raw CSV content. It applies caller-supplied fie…
    • contact-importer — ContactImporter ingests contacts from already-parsed record arrays or raw CSV content. It applies caller-supplied fie…
  • otel — Exposes the bundle of OpenTelemetry metric instruments emitted by @suaveplan/contacts. The bundle binds lazily agains…
    • instruments — Exposes the bundle of OpenTelemetry metric instruments emitted by @suaveplan/contacts. The bundle binds lazily agains…
  • schemas — Zod schemas for every public input boundary of @suaveplan/contacts plus the parseOrThrow helper that converts Zod v…
    • schemas — Zod schemas for every public input boundary of @suaveplan/contacts plus the parseOrThrow helper that converts Zod v…
  • contact-store — Defines the ContactStore storage interface that ContactManager and AudienceResolver consume, plus the `InMemoryCo…
    • contact-store — Defines the ContactStore storage interface that ContactManager and AudienceResolver consume, plus the `InMemoryCo…
  • group-store — Defines the GroupStore storage interface that GroupManager and AudienceResolver consume, plus the `InMemoryGroupS…
    • group-store — Defines the GroupStore storage interface that GroupManager and AudienceResolver consume, plus the `InMemoryGroupS…
  • membership-store — Defines the MembershipStore storage interface that MembershipManager, ContactMerger, and AudienceResolver consu…
    • membership-store — Defines the MembershipStore storage interface that MembershipManager, ContactMerger, and AudienceResolver consu…
  • tree — Pure tree utilities for building, flattening, traversing, and inspecting GroupTreeNode<TMeta> hierarchies. None of th…
    • tree-utils — Pure tree utilities for building, flattening, traversing, and inspecting GroupTreeNode<TMeta> hierarchies. None of th…

Install

bun add @suaveplan/contacts

Quick start

import {
 AudienceResolver,
 ContactManager,
 GroupManager,
 InMemoryContactStore,
 InMemoryGroupStore,
 InMemoryMembershipStore,
 MembershipManager,
} from "@suaveplan/contacts";

const contactStore = new InMemoryContactStore();
const groupStore = new InMemoryGroupStore();
const membershipStore = new InMemoryMembershipStore();

const contacts = new ContactManager({ store: contactStore });
const groups = new GroupManager({ store: groupStore });
const memberships = new MembershipManager({
 contactStore,
 groupStore,
 membershipStore,
});
const resolver = new AudienceResolver({
 contactStore,
 groupStore,
 membershipStore,
});

const vip = await groups.create({ tenantId: "acme", name: "VIP Customers" });
const alice = await contacts.create({
 tenantId: "acme",
 displayName: "Alice",
 channels: [
  { type: "email", value: "alice@example.com", primary: true, verified: true },
 ],
});
await memberships.addContactToGroup(vip.id, alice.id);
const audience = await resolver.resolve({ groupIds: [vip.id] });
console.log(audience.totalCount); // 1

Architecture

ContactStore  GroupStore  MembershipStore   <- pluggable storage
       │            │             │
       └─── ContactManager / GroupManager / MembershipManager  <- CRUD + validation + OTel
                              │
                ┌─────────────┴─────────────┐
                │                           │
       AudienceResolver            ContactMerger / ContactImporter / ContactExporter
       (group walk + dedup)        (data ops + import/export pipelines)

Every public mutating method validates via Zod, raises a typed ContactsError (never a bare Error), and emits on at least one OTel instrument. All temporal and id-generating paths accept injectable Clock and IdGenerator from @suaveplan/types.

Modules

Module Documentation
Error codes (CONTACTS_CODES, ContactsError) src/error-codes/error-codes.md
OTel instruments (getContactsInstruments) src/otel/instruments.md
Zod schemas (createContactInputSchema, …, parseOrThrow) src/schemas/schemas.md
Contact store (InMemoryContactStore) src/stores/contact-store/contact-store.md
Group store (InMemoryGroupStore) src/stores/group-store/group-store.md
Membership store (InMemoryMembershipStore) src/stores/membership-store/membership-store.md
ContactManager src/core/contact-manager/contact-manager.md
GroupManager src/core/group-manager/group-manager.md
MembershipManager src/core/membership-manager/membership-manager.md
ContactMerger src/core/contact-merger/contact-merger.md
AudienceResolver src/core/audience-resolver/audience-resolver.md
ContactExporter src/import-export/contact-exporter/contact-exporter.md
ContactImporter src/import-export/contact-importer/contact-importer.md
Tree utilities (buildGroupTree, …) src/tree/tree-utils.md