Files
daily-notification-plugin/doc/progress/P2.1-SCHEMA-VERSIONING-DRAFT.md

5.2 KiB

P2.1: Schema Versioning Strategy - Documentation Draft

Purpose: Draft documentation for iOS schema versioning strategy (ready to integrate into ios/Plugin/README.md)
Status: Draft for review
Date: 2025-12-22


Section to Add to ios/Plugin/README.md

Schema Versioning Strategy

Current Schema Version: 1 (initial schema)

The iOS implementation uses explicit schema versioning to achieve parity with Android's Room database versioning approach. This provides observability and migration tracking without interfering with CoreData's automatic migration capabilities.

Versioning Approach

CoreData Auto-Migration Remains Authoritative

The schema version is a logical contract, not a forced migration trigger. CoreData auto-migration (shouldMigrateStoreAutomatically = true) remains the authoritative mechanism for schema changes. Version mismatches are logged, not blocked.

Version Tracking

Schema version is stored in CoreData persistent store metadata using NSPersistentStore metadata dictionary. This approach:

  • Non-intrusive (does not require schema changes)
  • Observable (version can be read at any time)
  • Compatible with CoreData auto-migration
  • Matches Android's explicit versioning pattern

Current Implementation

  • Schema Version: 1 (initial schema, established 2025-09-22)
  • Version Storage: NSPersistentStore metadata key "schema_version"
  • Version Check: Performed during PersistenceController initialization
  • Logging: Version logged on store load; mismatches logged as warnings

Migration Contract

When to Bump Schema Version

The schema version should be incremented when:

  1. Entity changes:

    • Adding new entities
    • Removing entities (rare, requires data migration)
    • Renaming entities (requires explicit migration)
  2. Attribute changes:

    • Adding new required attributes (requires default values or migration)
    • Removing attributes (requires data cleanup)
    • Changing attribute types (requires type conversion)
    • Renaming attributes (requires explicit migration)
  3. Relationship changes:

    • Adding/removing relationships
    • Changing relationship cardinality
    • Renaming relationships

When NOT to Bump

  • Adding optional attributes (CoreData handles automatically)
  • Adding optional relationships (CoreData handles automatically)
  • Changing default values (no schema change required)
  • Adding indexes (metadata change, not schema change)

Version Bump Process

  1. Update CoreData model in Xcode (add/remove/modify entities/attributes)
  2. Increment schema version constant in PersistenceController
  3. Update metadata on next store load
  4. Document migration in changelog
  5. Update parity matrix if versioning strategy changes

Android Parity

Android: Room database with explicit version = 2 and Migration objects
iOS: CoreData with explicit schema version 1 in metadata + auto-migration

Both platforms now have:

  • Explicit version tracking
  • Migration documentation
  • Version observability
  • Migration contract defined

Parity Status: Explicit versioning (P2.1 complete)


Implementation Notes

Version Check Utility

A simple version check is performed during PersistenceController initialization:

// In PersistenceController.init()
private func checkSchemaVersion() {
    guard let store = container?.persistentStoreCoordinator.persistentStores.first else {
        return
    }
    
    let currentVersion = store.metadata["schema_version"] as? Int ?? 1
    let expectedVersion = SCHEMA_VERSION
    
    if currentVersion != expectedVersion {
        print("DNP-PLUGIN: Schema version mismatch - current: \(currentVersion), expected: \(expectedVersion)")
        // Log warning, but do not block (CoreData auto-migration handles actual migration)
    } else {
        print("DNP-PLUGIN: Schema version verified: \(currentVersion)")
    }
    
    // Update metadata if needed
    if currentVersion != expectedVersion {
        var metadata = store.metadata
        metadata["schema_version"] = expectedVersion
        // Note: Metadata update happens on next store save
    }
}

Constants

// In PersistenceController
private static let SCHEMA_VERSION = 1  // Current schema version

Testing

Version handling is verified through:

  1. Unit tests: Verify version metadata is set correctly
  2. Integration tests: Verify version check runs on store load
  3. Migration tests: Verify version tracking survives migrations

Test Coverage:

  • Version metadata is set on initial store creation
  • Version check runs during initialization
  • Version mismatches are logged (not blocked)
  • Version metadata persists across app restarts

  • Android Schema Versioning: android/src/main/java/com/timesafari/dailynotification/DatabaseSchema.kt (Room version = 2)
  • CoreData Model: ios/Plugin/DailyNotificationModel.xcdatamodeld
  • PersistenceController: ios/Plugin/DailyNotificationModel.swift
  • Parity Matrix: docs/progress/04-PARITY-MATRIX.md

Last Updated: 2025-12-22
Status: Draft for integration