Files
2026-05-27 23:29:53 +01:00

28 lines
1.5 KiB
Markdown

# Capability Spec: dedup
**Package**: `@suaveplan/dedup`
**Version**: 0.0.0 (genesis)
**Status**: ADDED
---
## ADDED Requirements
### DD-01 — Match keys
`MatchKey` MUST be `{ field, extract?, normaliser?, weight }`. The engine MUST support multiple match keys per config and combine their contributions by weighted sum, normalised to `[0, 1]`.
### DD-02 — Similarity primitives
`exactMatch(a, b)` MUST be `a === b`. `levenshteinDistance` MUST compute edit distance in O(|a|·|b|). `jaroWinklerSimilarity` MUST return a value in `[0, 1]`. `computeSimilarity(a, b, rules)` MUST apply the configured `ScoringRule[]` and return a composite score in `[0, 1]`.
### DD-03 — Detect contract
`DedupEngine.detect(entities, config)` MUST return `DuplicateGroup[]` where each group has `{ representative, members, scores }`. Every entity MUST belong to at most one group. Entities below `config.threshold` MUST NOT be grouped.
### DD-04 — Merge strategies
`latestWinsStrategy` MUST pick the entity with the most recent `updatedAt`. `manualStrategy` MUST defer to the caller via a resolver callback. `scoredMergeStrategy` MUST merge fields per-field using the highest-scored source. All strategies MUST return `MergeResult { merged, sources }`.
### DD-05 — Observability
Every `detect` call MUST record `dedup.detect.duration_ms` histogram and `dedup.groups.total` counter. Every merge MUST record `dedup.merge.total{strategy}`.
### DD-06 — Configuration validation
`DedupConfig` MUST be validated via Zod. Invalid configs MUST surface as `DEDUP.INVALID_CONFIG`.