first commit
This commit is contained in:
93
docs/commerce/contacts/audience-rules/src/store/store.md
Normal file
93
docs/commerce/contacts/audience-rules/src/store/store.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# store
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`store.ts` defines the `SegmentStore` interface that abstracts segment
|
||||
persistence behind a six-method contract (`create`, `getById`, `update`,
|
||||
`delete`, `list`, `updateCache`) and ships `InMemorySegmentStore` — a
|
||||
single-process, map-backed implementation suitable for development, tests,
|
||||
and lightweight production deployments. The in-memory store is built around
|
||||
injectable `Clock` and `IdGenerator` primitives from `@suaveplan/types`, so
|
||||
production paths never call `Date.now()` / `new Date()` directly or mutate a
|
||||
module-scope counter.
|
||||
|
||||
## Features
|
||||
|
||||
- `SegmentStore` interface — six async methods, all returning the persisted
|
||||
`Segment` (or `undefined` when the identifier does not exist).
|
||||
- `InMemorySegmentStore` — single-process map-backed implementation.
|
||||
- `InMemorySegmentStoreOptions { clock?, idGenerator? }` — both injection
|
||||
points are optional with sensible defaults.
|
||||
- Zod boundary on `create` and `update` — invalid input raises
|
||||
`AudienceRulesError` with code `AUDIENCE_RULES.INVALID_INPUT` (never a raw
|
||||
`ZodError`).
|
||||
- Multi-tenant isolation on `list(tenantId)` — segments owned by other
|
||||
tenants are invisible.
|
||||
- `updateCache(id, contactIds)` updates `cachedContactIds`, `cachedCount`,
|
||||
`lastRefreshedAt`, and `updatedAt` atomically.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { InMemorySegmentStore } from "@suaveplan/audience-rules";
|
||||
|
||||
const store = new InMemorySegmentStore();
|
||||
const segment = await store.create({
|
||||
tenantId: "tenant-1",
|
||||
name: "Active VIPs",
|
||||
rules: [{ field: "tags", operator: "contains", value: "vip" }],
|
||||
refreshMode: "manual",
|
||||
});
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { InMemorySegmentStore } from "@suaveplan/audience-rules";
|
||||
|
||||
// Deterministic store for tests: pinned clock + monotonic ID generator
|
||||
let n = 0;
|
||||
const store = new InMemorySegmentStore({
|
||||
clock: () => 1_700_000_000_000,
|
||||
idGenerator: () => {
|
||||
n += 1;
|
||||
return `test_seg_${n}`;
|
||||
},
|
||||
});
|
||||
|
||||
const a = await store.create({
|
||||
tenantId: "t1",
|
||||
name: "A",
|
||||
rules: [],
|
||||
refreshMode: "manual",
|
||||
});
|
||||
// a.id === "test_seg_1"; a.createdAt.getTime() === 1_700_000_000_000
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `interface SegmentStore` — see Features.
|
||||
- `interface InMemorySegmentStoreOptions` — `clock?: Clock`,
|
||||
`idGenerator?: IdGenerator` (both from `@suaveplan/types`).
|
||||
- `class InMemorySegmentStore implements SegmentStore` — constructor accepts
|
||||
`InMemorySegmentStoreOptions`. Throws `AudienceRulesError` with
|
||||
`AUDIENCE_RULES.INVALID_INPUT` on Zod failure in `create` / `update`, and
|
||||
on `list` with an empty `tenantId`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The default `IdGenerator` is a per-instance closure, so two separate stores
|
||||
in the same process produce independent ID sequences. This matches the
|
||||
`@suaveplan/contacts` `InMemoryContactStore` convention.
|
||||
- `create` and `update` validate input with `parseOrThrow` before mutating
|
||||
the internal map — failure leaves the store untouched.
|
||||
- `list` takes an `O(n)` scan; the package is a development-tier store and
|
||||
multi-tenant filtering happens in-memory. Production stores backed by a
|
||||
database can index on `tenantId` directly.
|
||||
- Every mutation updates `updatedAt` via the injected clock, so OTel
|
||||
histograms and snapshot diffs in consumers stay deterministic under
|
||||
`FakeClock`.
|
||||
Reference in New Issue
Block a user