# Migration Guide **Migrating from JSONB entity_versions to relational version tables** ## Status ✅ **Migration Complete** - The relational versioning system is now active. This guide documents the migration for reference. ## Overview The old system stored versions in a single `entity_versions` table using JSONB: - ❌ Not queryable - ❌ No type safety - ❌ Poor performance - ❌ Complex RLS The new system uses dedicated relational tables: - ✅ Fully queryable - ✅ Type-safe with foreign keys - ✅ Indexed and performant - ✅ Standard RLS policies ## Migration Timeline 1. **Phase 1: Create relational tables** ✅ Complete 2. **Phase 2: Enable triggers** ✅ Complete 3. **Phase 3: Dual-write period** ✅ Complete 4. **Phase 4: Backfill historical data** ⏸️ Optional 5. **Phase 5: Monitor** 🔄 Ongoing 6. **Phase 6: Deprecate JSONB table** 📅 Future ## Current State - ✅ All new versions written to relational tables - ✅ Triggers active on all entity tables - ⚠️ Old `entity_versions` table retained for backward compatibility - ⚠️ `src/lib/versioningHelpers.ts` deprecated but not removed ## Backfill Script (Optional) If you need to migrate historical JSONB versions to relational: ```sql -- Backfill park versions INSERT INTO park_versions ( version_id, park_id, version_number, created_at, created_by, change_type, submission_id, is_current, name, slug, description, park_type, status, opening_date, opening_date_precision, closing_date, closing_date_precision, location_id, operator_id, property_owner_id, website_url, phone, email, banner_image_url, banner_image_id, card_image_url, card_image_id ) SELECT ev.id, ev.entity_id, ev.version_number, ev.changed_at, ev.changed_by, ev.change_type, ev.submission_id, ev.is_current, ev.version_data->>'name', ev.version_data->>'slug', ev.version_data->>'description', ev.version_data->>'park_type', ev.version_data->>'status', (ev.version_data->>'opening_date')::date, ev.version_data->>'opening_date_precision', (ev.version_data->>'closing_date')::date, ev.version_data->>'closing_date_precision', (ev.version_data->>'location_id')::uuid, (ev.version_data->>'operator_id')::uuid, (ev.version_data->>'property_owner_id')::uuid, ev.version_data->>'website_url', ev.version_data->>'phone', ev.version_data->>'email', ev.version_data->>'banner_image_url', ev.version_data->>'banner_image_id', ev.version_data->>'card_image_url', ev.version_data->>'card_image_id' FROM entity_versions ev WHERE ev.entity_type = 'park' ON CONFLICT DO NOTHING; ``` ## Cleanup (Future) When ready to fully deprecate JSONB system: ```sql -- 1. Verify all versions migrated SELECT COUNT(*) FROM entity_versions; -- Should match relational tables -- 2. Drop old table (IRREVERSIBLE) DROP TABLE IF EXISTS entity_versions CASCADE; -- 3. Remove deprecated helpers -- Delete src/lib/versioningHelpers.ts ``` ## Rollback Plan If issues arise, rollback steps: 1. Disable triggers on entity tables 2. Revert edge functions to use old JSONB system 3. Keep relational tables for future retry **Note:** Not recommended - new system is production-ready.