Skip to main content

Documentation Index

Fetch the complete documentation index at: https://grantmaster.dev/llms.txt

Use this file to discover all available pages before exploring further.

Data Migrations & Schema Evolution

Because Firestore is schemaless, managing data evolution requires a specific strategy to ensure the application doesn’t crash when encountering legacy document structures.

1. Migration Strategy: “Lazy” vs. “Eager”

Lazy Migration (Preferred)

Instead of running a script across millions of documents, we migrate data on-read.
  1. Frontend/Service reads a document.
  2. A Zod schema with .default() or .transform() handles the legacy structure.
  3. The next time the document is saved, it is written in the new format.

Eager Migration (Bulk)

Required for searchable fields or major re-architecting.
  • Tool: Custom scripts in scripts/migrations/.
  • Pattern:
    • Always use batches (limit 500 operations per batch).
    • Use transaction if atomicity is required.
    • Log every migrated record to a temporary CSV for audit verification.

2. Standard Migration Script Template

import { db } from '../../src/core/firebase';
import { collection, getDocs, writeBatch } from 'firebase/firestore';

async function migrateGrants() {
  const querySnapshot = await getDocs(collection(db, 'activeGrants'));
  const batch = writeBatch(db);
  let count = 0;

  querySnapshot.forEach((doc) => {
    const data = doc.data();
    if (!data.newField) {
      batch.update(doc.ref, { newField: 'default_value' });
      count++;
    }
    
    // Safety check for Firestore limits
    if (count >= 499) {
      // commit and start new batch...
    }
  });

  await batch.commit();
  console.log(`Migrated ${count} documents.`);
}

3. Breaking Changes Checklist

Before changing a key field in a major collection:
  1. Update the owning schema or feature contract module.
  2. Update the Zod schema in src/schemas/.
  3. Add a fallback in the Zod schema for legacy data.
  4. Search codebase for direct Firestore queries using the old field name and update them.
  5. Update Firestore Security Rules if the field is used for allow conditions.
  6. Update Firestore Indexes if the field is indexed.

Maintenance

Update this document when:
  • Establishing a new standardized migration tool.
  • Changing the batch size limit (e.g., if switching to a different database).
  • Introducing a formal schema registry.