Files
skills/docs/foundation/data/dedup/src/schemas/dedup.schema.md
2026-05-29 08:20:56 +01:00

3.4 KiB
Raw Blame History

Dedup Schemas

(no submodules)

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

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

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

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

z.object({
  name: z.string().min(1),
})

DedupConfigSchema

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.