immersive2/SYNC_PLAN.md
Michael Mainguy 1e174e81d3
Some checks failed
Node.js CI / build (push) Waiting to run
Build / build (push) Failing after 15m8s
Add local database mode for browser-only diagrams
- Add /db/local/:db path type that stores diagrams locally without syncing
- New diagrams now default to local storage (browser-only)
- Share button creates public copy when sharing local diagrams
- Add storage type badges (Local/Public/Private) in diagram manager
- Add GitHub Actions workflow for automated builds
- Block local- database requests at server with 404

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 18:13:43 -06:00

5.0 KiB

Future Sync Strategy: Keeping Local and Public Clones in Sync

Current State (v1)

  • Sharing creates a ONE-TIME COPY from local to public
  • Copies diverge independently after sharing
  • No automatic sync between local and public versions
  • Local diagrams are browser-only (IndexedDB via PouchDB)
  • Public diagrams sync with server via express-pouchdb

URL Scheme

Route Sync Access Status
/db/local/:id None Browser-only Implemented
/db/public/:id Yes Anyone Implemented
/db/private/:id Yes Authorized users Route only (no auth)

Future Options

Add explicit user-triggered sync between local and public copies.

Features:

  • "Push to Public" button - sends local changes to public copy
  • "Pull from Public" button - gets public changes into local
  • Track lastSyncedAt timestamp
  • Show indicator when copies have diverged
  • Conflict resolution: Last write wins (simple) or user choice (advanced)

Pros:

  • User stays in control
  • Clear mental model
  • Simple to implement incrementally

Cons:

  • Manual effort required
  • Risk of forgetting to sync

Option 2: Automatic Background Sync

Continuous bidirectional sync between local and public copies.

Features:

  • Real-time sync like Google Docs
  • Works across devices
  • Offline-first with automatic merge

Pros:

  • Seamless experience
  • Always up to date

Cons:

  • Complex conflict resolution (may need CRDTs)
  • Higher performance overhead
  • Harder to reason about state

Option 3: Fork/Branch Model

One-way relationship: local is "draft", public is "published".

Features:

  • Push only (local → public)
  • No pull mechanism
  • Public is the "source of truth" once published

Pros:

  • Clear mental model
  • No merge conflicts
  • Simple implementation

Cons:

  • Cannot incorporate public changes back to local
  • Multiple people can't collaborate on draft

Implement Option 1 (Manual Push/Pull) as it provides the best balance of user control and simplicity.

Data Model Changes

Add to diagram directory entry:

interface DiagramEntry {
  _id: string;
  name: string;
  description: string;
  storageType: 'local' | 'public' | 'private';
  createdAt: string;

  // New fields for sync tracking
  publicCopyId?: string;      // ID of the public clone (if shared)
  lastPushedAt?: string;      // When changes were last pushed to public
  lastPulledAt?: string;      // When public changes were last pulled
  publicVersion?: number;     // Version number of public copy at last sync
}

API Endpoints

// Push local changes to public
POST /api/sync/push
Body: { localDbName: string, publicDbName: string }
Response: { success: boolean, documentsUpdated: number }

// Pull public changes to local
POST /api/sync/pull
Body: { localDbName: string, publicDbName: string }
Response: { success: boolean, documentsUpdated: number }

// Check if copies have diverged
GET /api/sync/status?local={localDbName}&public={publicDbName}
Response: {
  diverged: boolean,
  localChanges: number,
  publicChanges: number,
  lastSyncedAt: string
}

UI Components

  1. Sync Status Indicator

    • Shows in header when viewing a local diagram that has a public copy
    • Green check: In sync
    • Orange dot: Changes pending
    • Red warning: Conflicts detected
  2. Push/Pull Buttons

    • In hamburger menu under "Share" section
    • "Push to Public" - shows confirmation with change count
    • "Pull from Public" - shows confirmation with change count
  3. Divergence Warning Badge

    • Shows on diagram card in Manage Diagrams modal
    • Indicates when local and public have diverged
  4. Conflict Resolution Dialog

    • Shows when both local and public have changes to same entity
    • Options: Keep Local, Keep Public, Keep Both (creates duplicate)

Implementation Phases

Phase 1: Tracking

  • Add publicCopyId when sharing local → public
  • Track sharing relationship in directory

Phase 2: Push

  • Implement push from local to public
  • Overwrite public with local changes
  • Update lastPushedAt timestamp

Phase 3: Pull

  • Implement pull from public to local
  • Merge public changes into local
  • Update lastPulledAt timestamp

Phase 4: Status

  • Implement divergence detection
  • Add UI indicators
  • Show sync status in Manage Diagrams

Phase 5: Conflict Resolution

  • Detect entity-level conflicts
  • Show resolution dialog
  • Allow user to choose resolution strategy

Migration Notes

Existing diagrams without storageType are treated as public for backwards compatibility. When such diagrams are loaded, the UI should work correctly but sync tracking features won't be available until the diagram metadata is updated.

Security Considerations

  • Push/pull operations should validate that the user has access to both databases
  • Public databases remain world-readable/writable
  • Private database sync will require authentication tokens
  • Rate limiting should be applied to sync operations