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

121 lines
9.7 KiB
Markdown

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