Skip to main content

CRM Tenant UUID Migration (Draft)

Status: Draft Owner: @digiwedge/engineering Scope: CRM only

Goals

  • Introduce a canonical Tenant registry with UUID primary keys.
  • Migrate CRM data from string tenant IDs (slugs) to UUID tenant IDs.
  • Preserve tenant slugs for human-readable routing and external references.
  • Keep CRM public endpoints stable with a clear transition path.

Non-goals

  • No changes to non-CRM services in this phase (except integration updates where required).
  • No changes to branding, UI, or frontend UX in this migration.

Current State (Audit Summary)

  • CRM uses a string tenantId across all models.
  • There is no Tenant table in libs/prisma/crm-client/prisma/schema.prisma.
  • Public lead intake expects tenantId as a slug (example: digiwedge).
  • Seeded system segments are club-centric and not tenant-specific.

Target Model

Create a Tenant model with a UUID primary key and slug:

  • Tenant.id (UUID, primary key)
  • Tenant.slug (unique, human-readable)
  • Tenant.displayName
  • Tenant.status (ACTIVE, DISABLED)
  • Tenant.createdAt, Tenant.updatedAt

All CRM models should reference Tenant.id via a UUID tenantId field.

Migration Strategy (Phased)

Phase 1: Introduce Tenant Registry

  • Add Tenant model to CRM Prisma schema.
  • Seed existing tenants with UUIDs and slugs (initial: digiwedge, yolo).
  • Add new column tenantUuid (UUID, nullable) to all CRM tables.
  • Backfill tenantUuid using tenantId slug -> Tenant.slug mapping.
  • Keep existing tenantId (slug) for compatibility.

Phase 2: Dual Write + Read Migration

  • Update CRM services to write both:
    • tenantUuid (UUID, canonical)
    • tenantId (slug, compatibility)
  • Update queries to use tenantUuid and fallback to tenantId when missing.
  • Emit events containing both tenantId (UUID) and tenantSlug (string).

Phase 3: Cutover

  • Require tenantUuid for all new writes.
  • Update public endpoints to accept:
    • tenantSlug for external calls (mapped to UUID)
    • tenantId for internal UUID usage
  • Update documentation to reflect new API fields.

Phase 4: Cleanup

  • Rename slug field to tenantSlug (if needed for clarity).
  • Drop legacy slug-only indexes and constraints.
  • Remove deprecated code paths after stable period.

API Contract Changes

Public lead intake currently accepts tenantId as a slug. Post-migration:

  • Accept tenantSlug in public endpoints.
  • Accept tenantId (UUID) for internal calls.
  • Return tenantId (UUID) in events and internal responses.

Seed & Onboarding Templates

  • System segments must be tenant-specific.
  • Add a YOLO segment template pack (B2B lifecycle) distinct from club templates.
  • Ensure onboarding journeys differ per tenant.

Data Validation Queries

  • Verify all rows have tenantUuid after backfill.
  • Validate join integrity between CRM tables and Tenant.

Risks

  • External integrations assuming slug-only tenantId.
  • Data backfill mistakes due to unknown tenant slugs in the database.
  • Breaking public lead intake if tenant mapping fails.

Rollback Plan

  • Keep slug columns and old query paths until cutover is proven stable.
  • Disable UUID enforcement in Prisma until backfill verified.