Requirements & constraints:
- Support analytics and ML: unified customer profile, identity resolution, event enrichment.
- Low-latency reads for features; batch and streaming ingestion.
- Preserve auditability and provenance.
Canonical model (core entities):
- Customer (canonical_customer): customer_id (surrogate), ext_ids {crm_id, billing_id, device_ids}, name, primary_contact, lifecycle_status, created_at, updated_at, source_origin.
- Account/BillingAccount: account_id, canonical_customer_id, billing_status, billing_cycle, currency, last_payment_date.
- Product / Subscription: subscription_id, canonical_customer_id, sku, plan, start_date, end_date, status.
- CustomerEvent (event-level): event_id, canonical_customer_id (nullable until resolved), event_type, event_ts, properties (JSON), source_system, ingestion_ts.
- IdentityMapping: ext_id_type, ext_id, canonical_customer_id, confidence, last_seen.
- Metadata tables: schema_version, change_log, provenance.
Migration plan for producers:
- Define v1 schema + protobuf/Avro spec, publish in schema registry.
- Run dual-write: producers write original payload + canonical envelope (or event with ext_ids). Use streaming connector (Kafka) with topics per source.
- Build streaming enrichment job (Spark/Beam) that resolves ext_ids via IdentityMapping and emits canonical records to canonical topics and to downstream warehouse.
- Monitor drift and data quality; iterate.
Backward compatibility:
- Use schema evolution (Avro/Protobuf) with compatible additions (optional fields), avoid breaking renames.
- Keep source_id and raw_payload for replay.
- Support nullable canonical_customer_id until ETL resolves identities.
- Version fields: schema_version on every record; provide transformation adapters for older versions.
Governance:
- Central data contract team: approves schema changes, maintains registry, enforces semantic catalog.
- Automated CI: schema linting, compatibility checks, contract tests for producers/consumers.
- SLAs, onboarding docs, change approval flow (RFC), and a deprecation policy (staggered: notify > dual-write > migrate > retire).
- Observability: lineage (data catalog), DQ metrics, identity match rates, and alerting.
Trade-offs:
- Early identity resolution increases latency but improves downstream quality; keep both raw + resolved to support experimentation.
- Use surrogate canonical_customer for stable joins.
This approach balances incremental migration, backward compatibility, and strong governance to keep the canonical model consistent for analytics and ML.