[Feature] Add deduplication, merge, address quality, provenance, and audit history #10

Closed
opened 2026-07-13 00:53:46 +02:00 by zemion · 1 comment
Owner

Goal

Make reusable address directories maintainable, evidence-friendly, and safe enough for governed recipient selection. The AdreMa assessment confirms that hidden duplicate/exclusion logic must become explicit platform state.

Scope

  • Duplicate detection with explainable match features and bounded automatic suggestions.
  • Manual merge, split, undo/recovery evidence, and configurable survivorship rules.
  • Address/contact normalization and validation hooks with original-value preservation.
  • Invalid, returned, stale, and undeliverable contact-point states.
  • Field-level provenance, source history, and source-of-truth precedence.
  • Audit trail for contact, relationship, contact-point, merge, split, and quality decisions.
  • Field/row visibility and privacy decisions where needed.
  • Quality dashboards and correction queues without leaking inaccessible values.

Acceptance Criteria

  • Users can see where every retained field came from and why it won during a merge.
  • Merge and split operations preserve evidence of original records and stable redirects for authorized consumers.
  • Normalization never destroys the supplied source representation.
  • Audit events explain create, update, delete, restore, merge, split, and quality-state changes.
  • Recipient resolution can exclude or warn on invalid/stale targets with stable reason codes.
  • Optional Policy/Audit integrations enrich decisions without becoming hard dependencies.

Parent: #1. Related: #13 and #14.

## Goal Make reusable address directories maintainable, evidence-friendly, and safe enough for governed recipient selection. The [AdreMa assessment](https://git.add-ideas.de/GovOPlaN/govoplan-addresses/src/branch/main/docs/ADREMA_CAPABILITY_ASSESSMENT.md) confirms that hidden duplicate/exclusion logic must become explicit platform state. ## Scope - Duplicate detection with explainable match features and bounded automatic suggestions. - Manual merge, split, undo/recovery evidence, and configurable survivorship rules. - Address/contact normalization and validation hooks with original-value preservation. - Invalid, returned, stale, and undeliverable contact-point states. - Field-level provenance, source history, and source-of-truth precedence. - Audit trail for contact, relationship, contact-point, merge, split, and quality decisions. - Field/row visibility and privacy decisions where needed. - Quality dashboards and correction queues without leaking inaccessible values. ## Acceptance Criteria - Users can see where every retained field came from and why it won during a merge. - Merge and split operations preserve evidence of original records and stable redirects for authorized consumers. - Normalization never destroys the supplied source representation. - Audit events explain create, update, delete, restore, merge, split, and quality-state changes. - Recipient resolution can exclude or warn on invalid/stale targets with stable reason codes. - Optional Policy/Audit integrations enrich decisions without becoming hard dependencies. Parent: #1. Related: #13 and #14.
Author
Owner

Implemented and pushed in 19e9096.

Implemented:

  • preserved original plus normalized email, phone, and postal values;
  • append-only field provenance, source precedence, visibility markers, and provenance UI;
  • effective quality decisions for valid/invalid/returned/stale/undeliverable points;
  • stable quality reason/evidence projection into recipient resolution;
  • bounded, explainable duplicate suggestions and correction dashboard;
  • configurable scalar/contact-point survivorship;
  • transactional merge redirects and address-list membership repair;
  • evidence-hashed undo and split with post-merge tamper rejection;
  • value-free audit evidence for contact, contact-point, relationship, quality, merge, and recovery mutations;
  • migration, lifecycle metadata, operator/API documentation, and focused regression coverage.

Verification:

  • 35/35 Addresses tests;
  • Ruff and git diff --check;
  • existing-data SQLite migration drill from a3b5c6d7e8f9 to b4c6d7e8f9a0;
  • fresh SQLite migration head and table inspection;
  • full platform TypeScript/Vite production build, theme/i18n checks, and bundle budgets;
  • 64/64 manifest architecture declarations and strict cross-repository contract scan.

Policy remains an optional downstream decision layer; the optional Audit module is not imported or required.

Implemented and pushed in [`19e9096`](https://git.add-ideas.de/GovOPlaN/govoplan-addresses/commit/19e9096). Implemented: - preserved original plus normalized email, phone, and postal values; - append-only field provenance, source precedence, visibility markers, and provenance UI; - effective quality decisions for valid/invalid/returned/stale/undeliverable points; - stable quality reason/evidence projection into recipient resolution; - bounded, explainable duplicate suggestions and correction dashboard; - configurable scalar/contact-point survivorship; - transactional merge redirects and address-list membership repair; - evidence-hashed undo and split with post-merge tamper rejection; - value-free audit evidence for contact, contact-point, relationship, quality, merge, and recovery mutations; - migration, lifecycle metadata, operator/API documentation, and focused regression coverage. Verification: - 35/35 Addresses tests; - Ruff and `git diff --check`; - existing-data SQLite migration drill from `a3b5c6d7e8f9` to `b4c6d7e8f9a0`; - fresh SQLite migration head and table inspection; - full platform TypeScript/Vite production build, theme/i18n checks, and bundle budgets; - 64/64 manifest architecture declarations and strict cross-repository contract scan. Policy remains an optional downstream decision layer; the optional Audit module is not imported or required.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: GovOPlaN/govoplan-addresses#10