first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
# Dedup Schemas
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Zod schemas for the `@suaveplan/dedup` package's configuration types. These schemas serve as the single source of truth for runtime validation of `DedupConfig`, `MatchKey`, and `ScoringRule` objects supplied by callers. All engine constructors run inputs through these schemas before use, ensuring invalid configurations fail fast with clear error messages.
## Features
- `MatchKeySchema` — validates field path, weight (0–1), strategy, and optional case-sensitivity flag
- `ScoringRuleSchema` — validates the name string of a scoring rule
- `DedupConfigSchema` — composes the above with threshold and max-group-size defaults
- Coerced defaults: `mergeThreshold` defaults to `0.85`, `maxGroupSize` to `100`
- All schemas export inferred TypeScript types via `z.infer`
## Usage: Basic Example
```ts
import { DedupConfigSchema } from '@suaveplan/dedup';
import type { DedupConfig } from '@suaveplan/dedup';
const raw = {
matchKeys: [{ field: 'email', weight: 1, strategy: 'exact' }],
scoringRules: [],
};
const config: DedupConfig = DedupConfigSchema.parse(raw);
```
## Usage: Advanced Example
```ts
import { DedupConfigSchema } from '@suaveplan/dedup';
// Validate at API boundary before constructing engine
function createEngine(raw: unknown) {
const result = DedupConfigSchema.safeParse(raw);
if (!result.success) {
throw new Error(`Invalid dedup config: ${result.error.message}`);
}
return new DedupEngine(result.data);
}
// Multi-key config with custom thresholds
const config = DedupConfigSchema.parse({
matchKeys: [
{ field: 'email', weight: 0.6, strategy: 'exact' },
{ field: 'firstName', weight: 0.2, strategy: 'jaro-winkler' },
{ field: 'lastName', weight: 0.2, strategy: 'jaro-winkler' },
],
scoringRules: [],
mergeThreshold: 0.75,
maxGroupSize: 50,
});
```
## API Reference
### `MatchKeySchema`
```ts
z.object({
field: z.string().min(1),
weight: z.number().min(0).max(1),
strategy: z.enum(['exact', 'jaro-winkler', 'levenshtein', 'phonetic']),
caseSensitive: z.boolean().optional(),
})
```
### `ScoringRuleSchema`
```ts
z.object({
name: z.string().min(1),
})
```
### `DedupConfigSchema`
```ts
z.object({
matchKeys: z.array(MatchKeySchema).min(1),
scoringRules: z.array(ScoringRuleSchema),
mergeThreshold: z.number().min(0).max(1).optional().default(0.85),
maxGroupSize: z.number().int().positive().optional().default(100),
})
```
Inferred types (`MatchKey`, `ScoringRule`, `DedupConfig`) are exported from the package root alongside the schemas.
## Implementation Notes
Schemas are defined in a dedicated `.schema.ts` file and excluded from coverage reporting (per project convention). The `ScoringRuleSchema` currently only validates `name` because the `evaluate` function is a runtime interface — Zod cannot validate function types. Callers providing custom scoring rules must implement the `ScoringRule` interface directly.
The `weight` field on `MatchKeySchema` is validated to the range `[0, 1]` but the engine does not enforce that all weights sum to exactly 1.0 — this is intentional. Weights below 1 produce a score ceiling below the default threshold, which is a valid configuration for partial-match scenarios. Callers should set `mergeThreshold` accordingly when using sub-unity weight sums.