Overview & Onboarding
Project context, scope, and how the design documents fit together.
Meta Data Customer Onboarding
Execution Strategy & Rollout Plan
Multi-Tenant Platform Migration
Executive Summary
This document outlines the strategy to migrate our multi-tenant platform from MongoDB to PostgreSQL. The migration is structured in two phases: a controlled rollout for the first five tenants, followed by a bucketed delivery model for the remaining customer base.
The approach is designed to minimize risk, preserve every customer's production configuration exactly as it exists today, and validate the new platform end-to-end before any customer is moved live. Mocking and isolated environments ensure we never disturb external partners or production systems during validation.
Guiding Principle No customer goes live on PostgreSQL until their tenant-specific configuration, data, workflows, and integrations have been validated against production behaviour in a clean, isolated environment. |
Migration at a Glance
Phase | Scope | Approach | Outcome |
|---|---|---|---|
Phase 1 | First 5 tenants | Clean-state INTQA environments; each team mirrors production config as-is | Validated reference implementation |
Phase 2 | Remaining tenants | Customer bucketing based on configuration similarity | Bucket-by-bucket go-live |
1. Configuration & Operational Flow Extraction
Before any data moves, we need a complete inventory of how each tenant operates today. This is the foundation everything else depends on.
What we extract
- Tenant-level configurations — feature flags, environment-specific settings, branding, locale, and routing rules
- Workflows — business process definitions, state machines, approval chains, and trigger conditions
- Business rules — validation logic, eligibility criteria, calculation rules, and decision tables
- Integration settings — endpoints, credentials (referenced, not extracted), webhook subscriptions, and partner identifiers
- User and role mappings — RBAC definitions, team structures, and permission grants
Execution approach
We build a dedicated extraction utility that connects to each production tenant's MongoDB instance in read-only mode and produces a structured artifact per tenant — a single source of truth for that tenant's operational state. Each artifact is versioned, signed, and stored in a dedicated configuration repository. Sensitive values are tokenized; credentials are never copied, only referenced.
Deliverable
A per-tenant configuration manifest (one per tenant, five for Phase 1) that downstream teams use as the authoritative input for setting up the PostgreSQL environment. Any configuration drift between this manifest and what is actually configured in INTQA becomes an immediate flagged item.
2. Schema Mapping: MongoDB to PostgreSQL
The data models are fundamentally different. MongoDB's document model accommodates nested structures and flexible schemas; PostgreSQL is relational with strict typing. The mapping is not mechanical — it requires deliberate decisions about normalization, indexing, and how to handle existing flexibility.
Mapping principles
- Normalize where data is queried relationally — break embedded documents into related tables when joins are common
- Preserve as JSONB where data is genuinely schema-flexible or rarely queried by inner fields — PostgreSQL JSONB handles this well
- Establish primary key strategy — typically migrate Mongo ObjectIds to UUID columns, with the original ID preserved for traceability
- Define index parity — every query pattern that performs in MongoDB must have a corresponding index in PostgreSQL
- Handle nulls, defaults, and enums explicitly — MongoDB's permissiveness must become PostgreSQL's strictness without breaking existing records
Deliverable
A schema mapping specification, maintained as code, that defines for every MongoDB collection: the target PostgreSQL table(s), field-by-field type translation, normalization decisions, constraint rules, and index definitions. This document is reviewed and signed off by engineering before any transformation code is written.
MongoDB Element | Typical PostgreSQL Mapping |
|---|---|
Collection | Table (or set of related tables when normalized) |
Document _id (ObjectId) | UUID primary key + legacy_id column for traceability |
Embedded document | JSONB column OR separate related table (decision per case) |
Array of references | Junction table with foreign keys |
Array of values | JSONB array OR normalized child table |
Dynamic / sparse fields | JSONB column with documented expected keys |
Mongo indexes | B-tree, GIN (for JSONB), or partial indexes as appropriate |
3. Prod-to-Lower-Environment Sync Framework
Lower environments must reflect production configuration to make validation meaningful. Without this, teams test against a version of reality that does not match what customers actually use.
What gets synced
- Configurations, workflows, rules, and other operational settings — the same artifacts produced by the extraction step
- Reference data — lookup tables, code lists, and master data
- Selectively masked transactional data — only where required for realistic scenario coverage, with PII redacted
Execution approach
A sync framework is built as a one-way pipeline from production to lower environments. It runs on demand and on a schedule, with three modes:
- Full sync — used when standing up a fresh environment or after major configuration changes
- Delta sync — applies only changes since the last sync, used routinely to keep environments current
- Selective sync — operator chooses specific tenants or specific artifact types to refresh
All sync operations are audited, reversible (via snapshot before sync), and gated by approval for non-routine modes. PII handling rules are enforced at the framework level, not left to individual scripts.
Deliverable
A sync service with a simple operator interface, scheduled jobs for routine delta sync, and a full audit log of every sync operation. Lower environments converge to production within a defined SLA.
4. Data Validation Framework
Migrated data must be provably equivalent to source data. This is non-negotiable — financial, regulatory, and operational integrity all depend on it.
Validation layers
Layer | What It Checks | How |
|---|---|---|
Volumetric | Row counts match per tenant per entity | Automated count reconciliation |
Field-level | Every field migrated correctly with right type | Sampled deep comparison, plus 100% comparison on critical fields |
Referential | All relationships intact post-normalization | Foreign key integrity checks |
Business-rule | Aggregates, calculations, and derived values match | Targeted queries on both sides, results compared |
Temporal | Created/updated timestamps preserved | Direct comparison |
Execution approach
Validation runs as part of the migration pipeline, not as a separate afterthought. A migration is not considered complete for a tenant until all five validation layers pass. Discrepancies are logged with full context, classified by severity, and routed to the responsible team.
Deliverable
A validation report per tenant, produced automatically at the end of each migration run. The report is the formal artifact that signs off data correctness before a tenant proceeds to use-case validation.
5. End-to-End Use Case Validation Framework
Data correctness is necessary but not sufficient. The system must behave correctly under real-world operational flows. This framework validates that customer journeys work end-to-end on PostgreSQL.
What gets validated
- Critical customer journeys — every workflow that a tenant uses in production
- Cross-system flows — operations that touch multiple services or external partners
- Edge cases and known production scenarios — including historical incidents and complex configurations
- Performance baselines — response times under representative load
Execution approach
Each tenant's team builds a use-case catalogue from their production operational flows. These become automated end-to-end test suites that run in INTQA against the migrated environment. The same suites run pre-migration against MongoDB and post-migration against PostgreSQL — pass/fail parity is the gate.
Test suites are tenant-aware: each suite runs against its specific tenant configuration, ensuring that customer-specific behaviour is preserved, not just the platform default.
Deliverable
A use-case catalogue and automated test suite per tenant, with a pass/fail dashboard that leadership can review. A tenant does not move to production cutover until their suite is green and matches MongoDB behaviour.
6. Mocking Framework for External Integrations
During migration validation, we cannot call production third-party systems — doing so would create real-world side effects (payments, notifications, partner submissions). At the same time, we must validate that our integration code works correctly against the new database.
Approach
- A dedicated mocking service replicates the behaviour of every external integration our platform depends on
- Mocks are configured per scenario — happy path, error responses, timeout, partial success, etc.
- All outbound calls from INTQA are routed to the mocking layer; no production partner is ever called from a non-production environment
- Mock behaviour is captured from real production interactions (anonymized) so it reflects actual partner contracts, not idealized assumptions
Deliverable
A mocking service with a catalogue of scenarios for every integration. Teams can switch scenarios per test run to validate both happy-path and failure-mode behavior without external impact.
7. Integration Payload Validation with Mocking
Beyond mocking responses, we validate that our system sends the correct payloads and handles responses correctly — both sides of the wire.
What gets validated
- Request payloads — schema, required fields, data types, business field correctness
- Response handling — successful parsing, correct mapping to internal state, error handling
- Contract conformance — payloads match the published contract with each partner
- Behavior under partner failure modes — timeouts, 5xx errors, malformed responses
Execution approach
The mocking framework records every request/response pair during validation runs. These are diffed against a baseline captured from MongoDB production behavior. Any deviation in payload structure or values is flagged. This catches subtle issues where the migration changes a field's representation in a way that breaks downstream contracts.
Deliverable
A payload validation report per integration per tenant, with diffs against the production baseline. Zero unexplained deviations is the bar for cutover.
8. Phase 1 — Clean-State INTQA for First 5 Tenants
The first five tenants are migrated through dedicated, isolated INTQA environments — one per tenant — set up from a clean slate. Each tenant's team owns its environment and is responsible for configuring it to mirror production exactly as-is.
Setup model
Element | Description |
|---|---|
Environment isolation | Each tenant gets its own INTQA environment — separate database, separate service instances, no cross-tenant contamination |
Configuration source | Tenant team uses the configuration manifest from Section 1 as the authoritative source |
Mirror-as-is principle | No 'cleanup' or 'optimization' during setup — production is replicated faithfully, including known quirks |
Team ownership | Each tenant's team owns setup, validation, and sign-off for their environment |
Shared infrastructure | Mocking layer and validation framework are shared across all five environments |
Why clean-state matters
Starting from a clean state — rather than copying an existing test environment — eliminates inherited drift. Every configuration in INTQA exists because it was deliberately put there based on the production manifest. This makes drift detection meaningful and gives us a true representation of what each customer experiences.
Phase 1 success criteria
- All five tenant environments configured and signed off by their respective teams
- Data validation framework reports green for all five tenants
- End-to-end use case suites pass at parity with MongoDB
- Integration payload validation shows zero unexplained deviations
- Tenant team sign-off — the team that owns the customer relationship confirms readiness
Phase 1 Outcome Five tenants live on PostgreSQL, with a proven playbook covering extraction, mapping, sync, validation, mocking, and tenant-team ownership. This becomes the template for everything that follows. |
9. Phase 2 — Customer Bucketing & Bucketed Go-Live
After the first five tenants are live, we shift from per-tenant treatment to bucketed delivery. Migrating the remaining customers one at a time would be too slow; treating them all the same would be too risky. Bucketing balances both.
How buckets are defined
Customers are grouped into buckets based on the configurations, workflows, rules, and other settings extracted in Section 1. Customers with similar operational profiles share a bucket, because they share migration risk and validation needs.
Bucketing Dimension | What It Captures |
|---|---|
Workflow complexity | Number, depth, and customization level of business workflows |
Integration footprint | Count and type of external integrations active |
Custom rule density | Volume of tenant-specific business rules and logic |
Data volume | Scale of records — affects migration runtime and validation cost |
Compliance / regulatory profile | Special handling requirements that affect migration approach |
Bucketed delivery
- Each bucket gets a tailored migration playbook derived from Phase 1 learnings but adapted to the bucket's profile
- Within a bucket, customers are migrated in parallel where capacity allows, sequentially where risk requires it
- Validation thresholds are bucket-specific — high-complexity buckets get more rigorous gates
- Each bucket is fully delivered to live before the next bucket begins, unless explicitly parallelized with leadership approval
Bucket delivery cadence
After each bucket goes live, we hold a structured retrospective. Findings feed into the next bucket's playbook. This means the migration gets faster and lower-risk with each bucket, not just more numerous.
Deliverable
A bucket assignment for every remaining customer, a tailored playbook per bucket, and a sequenced delivery plan with milestones leadership can track. Each bucket completion is a clean checkpoint with a customer count moved, a risk summary, and lessons applied to the next.
Summary of Deliverables
Component | Deliverable |
|---|---|
Configuration extraction | Per-tenant configuration manifest |
Schema mapping | Mapping specification maintained as code |
Prod-to-lower sync | Sync service with audit log and operator interface |
Data validation | Per-tenant validation report from automated pipeline |
Use case validation | Per-tenant test suite and pass/fail dashboard |
External integration mocking | Mocking service with scenario catalog |
Payload validation | Per-integration payload diff report |
Phase 1 — first 5 tenants | Five clean-state INTQA environments, signed off by tenant teams, live on PostgreSQL |
Phase 2 — bucketed delivery | Bucket assignments, per-bucket playbooks, sequenced go-live plan |
Bottom Line The migration is structured to make risk visible and manageable at every step. We validate before we move. We move five customers through a deliberate, hands-on process to prove the approach. Then we scale through bucketing, with each bucket making the next one safer and faster. |