- 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>
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
Option 1: Manual Push/Pull (Recommended for v2)
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
lastSyncedAttimestamp - 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
Recommended Implementation (v2)
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
-
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
-
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
-
Divergence Warning Badge
- Shows on diagram card in Manage Diagrams modal
- Indicates when local and public have diverged
-
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
publicCopyIdwhen sharing local → public - Track sharing relationship in directory
Phase 2: Push
- Implement push from local to public
- Overwrite public with local changes
- Update
lastPushedAttimestamp
Phase 3: Pull
- Implement pull from public to local
- Merge public changes into local
- Update
lastPulledAttimestamp
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