Elegant Sync Implementation Plan
Step-by-step plan to implement MongoDB Change Streams + autoFlashState solution
Elegant Sync Implementation Plan
Implementation Overview
Goal: Replace manual SyncEngineService with elegant MongoDB Change Streams + autoFlashState solution
Timeline: 2-3 hours
Risk: Low (can run both systems in parallel during migration)
Current State
✅ MongoDB HTTP Sync configured (app.config.ts)
✅ BroadcastChannel working (built into GgStorage)
✅ autoFlashState available
✅ MongoDBIntegrationService ready
❌ SpaceService using manual sync (SyncEngineService)
❌ MongoDB Change Streams not enabled
❌ Phantom universe cleanup hacks
Target State
✅ SpaceServiceV2 using autoFlashState
✅ MongoDB Change Streams enabled for spaces/universes
✅ Automatic cross-tab sync (BroadcastChannel)
✅ Automatic multi-user sync (Change Streams)
✅ Zero manual sync code
✅ No phantom ID issues (proper state management)
Implementation Steps
Phase 1: Enable MongoDB Change Streams (30 min)
Step 1.1: Create initialization function
// libs/libs-foundational/core-angular/src/lib/services/mongodb-realtime-init.ts
import { inject } from '@angular/core';
import { MongoDBIntegrationService } from '@storage-system';
import { LoggerService } from '@libs-core/log-system';
export async function initializeMongoDBRealtime(): Promise<void> {
const mongodb = inject(MongoDBIntegrationService);
const logger = inject(LoggerService);
try {
logger.info('[MongoDB Realtime] Initializing Change Streams...');
// Enable real-time sync for spaces
await mongodb.enableAutoSync('spaces', 'gograb-space', {
autoRealtimeSync: true
});
logger.info('[MongoDB Realtime] ✅ Spaces Change Stream enabled');
// Enable real-time sync for universes
await mongodb.enableAutoSync('universes', 'gograb-space', {
autoRealtimeSync: true
});
logger.info('[MongoDB Realtime] ✅ Universes Change Stream enabled');
} catch (error) {
logger.error('[MongoDB Realtime] Failed to initialize:', error);
// Don't throw - allow app to start even if Change Streams fail
}
}
Step 1.2: Add to app.config.ts
// apps/gograb-space/src/app/app.config.ts
import { provideAppInitializer } from '@angular/core';
import { initializeMongoDBRealtime } from '@libs-foundational/core-angular';
export const appConfig: ApplicationConfig = {
providers: [
// ... existing providers ...
// 📡 MongoDB Change Streams for Real-time Multi-User Sync
provideAppInitializer(() => {
return initializeMongoDBRealtime();
}),
// ... rest of providers ...
]
};
Verification:
- Check browser console for "Change Stream enabled" logs
- No errors during startup
- App loads normally
Phase 2: Run SpaceServiceV2 in Parallel (45 min)
Step 2.1: Export SpaceServiceV2 from barrel
// libs/libs-foundational/core-angular/src/index.ts
// Add to exports
export { SpaceServiceV2 } from './lib/services/space.service.v2';
Step 2.2: Create test component
// apps/gograb-space/src/app/components/test/space-service-comparison.component.ts
@Component({
selector: 'app-space-service-comparison',
template: `
<div class="comparison">
<div class="column">
<h3>Old SpaceService</h3>
<pre>{{ oldService() | json }}</pre>
</div>
<div class="column">
<h3>New SpaceServiceV2</h3>
<pre>{{ newService() | json }}</pre>
</div>
</div>
`
})
export class SpaceServiceComparisonComponent {
private oldSpace = inject(SpaceService);
private newSpace = inject(SpaceServiceV2);
oldService = computed(() => ({
space: this.oldSpace.currentSpace(),
universes: this.oldSpace.universes().length,
activeUniverse: this.oldSpace.activeUniverse()
}));
newService = computed(() => ({
space: this.newSpace.currentSpace(),
universes: this.newSpace.universes().length,
activeUniverse: this.newSpace.activeUniverse()
}));
}
Verification:
- Both services load same data
- Both services stay in sync
- No console errors
Phase 3: Migrate Components to SpaceServiceV2 (60 min)
Components to migrate (in order):
✅ GSpaceDashboardComponent
- Change injection from
SpaceServicetoSpaceServiceV2 - Test universe list displays correctly
- Test create/delete operations
- Change injection from
✅ UniverseCreationWizardComponent
- Update to use SpaceServiceV2
- Test universe creation flow
- Verify immediate UI update
✅ SpaceGuard
- Update to initialize SpaceServiceV2
- Test routing still works
- Verify authentication flow
✅ AppComponent
- Update any direct SpaceService usage
- Test app initialization
- Verify space loading
Migration Pattern:
// Before:
private spaceService = inject(SpaceService);
// After:
private spaceService = inject(SpaceServiceV2);
// That's it! API is compatible
Verification (for each component):
- Component loads without errors
- Data displays correctly
- Create/update/delete operations work
- Multi-tab sync works (open 2 tabs, make changes)
- Multi-browser sync works (open 2 browsers, make changes)
Phase 4: Remove Old SpaceService (30 min)
Step 4.1: Verify all migrations complete
# Search for any remaining SpaceService usage
grep -r "inject(SpaceService)" apps/gograb-space/src --exclude-dir=node_modules
Step 4.2: Rename files
# Backup old service
mv libs/libs-foundational/core-angular/src/lib/services/space.service.ts \
libs/libs-foundational/core-angular/src/lib/services/space.service.old.ts
# Promote V2 to main
mv libs/libs-foundational/core-angular/src/lib/services/space.service.v2.ts \
libs/libs-foundational/core-angular/src/lib/services/space.service.ts
Step 4.3: Update barrel exports
// libs/libs-foundational/core-angular/src/index.ts
// Remove V2 export, now it's the main one
export { SpaceService } from './lib/services/space.service';
Step 4.4: Delete old service (after testing period)
# After 1-2 weeks of stable operation
rm libs/libs-foundational/core-angular/src/lib/services/space.service.old.ts
Verification:
- All components still work
- No build errors
- No runtime errors
- Tests pass
Phase 5: Remove SyncEngineService (15 min)
Step 5.1: Check for SyncEngineService usage
grep -r "SyncEngineService" apps/gograb-space/src --exclude-dir=node_modules
Step 5.2: Remove from providers if not used
// apps/gograb-space/src/app/app.config.ts
// Remove if SyncEngineService is not used anymore
// (SpaceServiceV2 doesn't need it)
Step 5.3: Archive the file
# Don't delete yet, just move to archive
mkdir -p libs/libs-foundational/core-angular/src/lib/services/archive
mv libs/libs-foundational/core-angular/src/lib/services/sync-engine.service.ts \
libs/libs-foundational/core-angular/src/lib/services/archive/
Verification:
- App still runs
- No references to SyncEngineService
- Sync still works via HTTP MongoDB Sync + Change Streams
Testing Checklist
Functional Tests
- Create Universe: Works instantly, appears in all tabs/browsers
- Delete Universe: Removed from all tabs/browsers instantly
- Update Universe: Changes reflect everywhere
- Offline Create: Universe created offline, syncs when online
- Offline Delete: Universe deleted offline, syncs when online
- Conflict Resolution: Simultaneous edits merge correctly
Performance Tests
- Local Operations: < 50ms (5-10ms typical)
- Cross-Tab: < 100ms (< 1ms typical)
- Multi-User: < 500ms (< 100ms typical)
- Offline Queue: Syncs within 30 seconds of going online
Edge Cases
- Rapid Creates: Create 10 universes quickly, all sync
- Network Fluctuation: Toggle offline/online, data stays consistent
- Browser Restart: Data persists, loads correctly
- Multiple Devices: Laptop + Desktop + Mobile all stay in sync
Rollback Plan
If issues arise:
- Immediate: Comment out SpaceServiceV2 usage, revert to SpaceService
- Quick: Disable MongoDB Change Streams in app.config.ts
- Full: Restore backed-up files from archive/
Success Metrics
- ✅ Code Reduction: ~60% less sync-related code
- ✅ Performance: < 50ms for all operations
- ✅ Reliability: Zero phantom universe issues
- ✅ Sync Speed: < 100ms multi-user updates
- ✅ Developer Experience: Simpler, cleaner code
Post-Implementation
Documentation Updates
- Update architecture diagrams
- Update API documentation
- Add migration guide for future developers
- Document MongoDB Change Streams configuration
Monitoring
- Monitor Change Stream connection status
- Track sync latency metrics
- Watch for any phantom ID occurrences (should be zero)
- Monitor MongoDB usage (Change Streams use)
Future Optimizations
- Consider Delta Sync (Q2 2025) for bandwidth optimization
- Evaluate Redis for Phase 2 features (presence, cursors)
- Add conflict resolution UI for rare edge cases
Ready to Start?
Pre-flight Checklist:
- ✅ MongoDB Change Streams available in storage-system
- ✅ autoFlashState working
- ✅ SpaceServiceV2 created and tested
- ✅ HTTP MongoDB Sync configured
- ✅ BroadcastChannel working
- ✅ Documentation complete
- ✅ Redis placeholders removed
Let's implement! 🚀