Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
# `repositories/suppression/suppression-internals`
## Purpose
This module owns the validation and mapping primitives shared by the two
`CampaignSuppressionStore` implementations — `ReasonSchema`,
`CreateInputSchema`, `QuerySchema`, the `requireTenant` guard, the
`rowToEntry` row mapper, and the `validateCreate` wrapper. Keeping these
helpers in a dedicated sibling module is what allows both the SurrealDB
implementation (`./suppression.ts`) and the in-memory reference
(`./suppression-memory.ts`) to stay under the 300-line hard cap without
duplicating their entry-validation logic.
## Features
- `ReasonSchema` — Zod enum guard over the five canonical
`CampaignSuppressionReason` values (`unsubscribe`, `bounce`,
`complaint`, `manual`, `compliance`).
- `CreateInputSchema` / `QuerySchema` — strict Zod object guards for the
two public input shapes.
- `requireTenant(tenantId)` — boundary check that throws
`CAMPAIGNS_API.TENANT_REQUIRED` for an empty string.
- `validateCreate(input)` — parses with `CreateInputSchema` and throws
`CAMPAIGNS_API.INVALID_INPUT` on failure with the underlying `ZodError`
attached as `cause`.
- `rowToEntry(row)` — maps `CampaignSuppressionRow` ↔ `CampaignSuppressionEntry`
with `Date` normalisation and `null` → `undefined` collapsing.
## Usage: Basic
```ts
import { validateCreate, requireTenant } from "./suppression-internals.js";
requireTenant("tenant-1");
const data = validateCreate({
tenantId: "tenant-1",
channel: "email",
channelValue: "user@example.com",
reason: "unsubscribe",
});
```
## Usage: Advanced
```ts
import { QuerySchema, rowToEntry } from "./suppression-internals.js";
const parsed = QuerySchema.safeParse({
tenantId: "t1",
channel: "sms",
limit: 25,
});
if (!parsed.success) {
// handle ZodError without going through the repository
}
const entry = rowToEntry({
id: "s1",
tenant_id: "t1",
channel: "sms",
channel_value: "+15551234567",
reason: "complaint",
metadata: null,
created_at: "2026-05-24T00:00:00.000Z",
});
```
## API Reference
- `const ReasonSchema: z.ZodEnum`
- `const CreateInputSchema: z.ZodObject`
- `const QuerySchema: z.ZodObject`
- `function requireTenant(tenantId: string): void` — throws on empty.
- `function rowToEntry(row: CampaignSuppressionRow): CampaignSuppressionEntry`
- `function validateCreate(input: CreateCampaignSuppressionInput): CreateCampaignSuppressionInput`
## Implementation Notes
`CreateInputSchema` and `QuerySchema` use `.strict()` so unknown keys
fail validation rather than silently flowing through to SurrealDB —
this keeps the repository contract honest against evolving HTTP payloads
and stops typos from becoming silent feature requests.
The schemas live here (not in `../../schemas/`) because they are
implementation details of the suppression repository, not part of the
plugin's public option surface. The plugin's `options` schema in
`../../schemas/options.ts` is the user-facing configuration contract; the
repository schemas are private guards at a different boundary.