first commit
This commit is contained in:
97
docs/foundation/data/dedup/src/schemas/dedup.schema.md
Normal file
97
docs/foundation/data/dedup/src/schemas/dedup.schema.md
Normal 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.
|
||||
Reference in New Issue
Block a user