Integrate PFAPI's validation/repair with operation logs to prevent
corruption and automatically recover from invalid states.
Key features:
- REPAIR operation type with full repaired state + summary
- 4 validation checkpoints (A: before write, B: after snapshot load,
C: after replay, D: after sync)
- Payload validation before IndexedDB write (lenient structural checks)
- Full Typia + cross-model validation at state checkpoints
- User notification when auto-repair occurs
- Infinite loop prevention during repair
New files:
- validate-state.service.ts: wraps PFAPI validation + repair
- validate-operation-payload.ts: checkpoint A payload validation
- repair-operation.service.ts: REPAIR operation creation
Replace custom UUID v7 implementations with the standard uuidv7 library.
The custom implementation had a bug with JavaScript bitwise operators
not handling 48-bit timestamps correctly.
Add filterLocalAction() operator to filter out remote actions from sync.
Effects that handle UI feedback (snackbars, sounds) or derive additional
actions should not run for operations replayed from other clients.
- Update architecture doc to reflect actual implementation state:
- Replace action blacklist with isPersistent pattern
- Mark Part C (server sync) as complete (was incorrectly "not started")
- Update file reference section with all current files
- Update compaction config to show 7-day retention window
- Remove obsolete "models requiring migration" section
- Fix compaction service:
- Use PfapiStoreDelegateService for consistency
- Add schemaVersion to state cache saves
A.6: Disaster Recovery
- Add snapshot validation in hydrateStore()
- Implement _attemptRecovery() to restore from legacy 'pf' database
- Add _hasUsableData() and _recoverFromLegacyData() helpers
- Add 'RECOVERY' entity type for recovery operations
A.7: Schema Migration Service
- Create SchemaMigrationService with migration infrastructure
- Define MigratableStateCache interface with schemaVersion
- Integrate migrations into hydration flow
- Update state_cache schema to include schemaVersion
Also updates architecture doc to reflect Part A/B completion.
Mark Phase 0.1, 0.2, and 0.2.5 as complete:
- Legacy sync stale data: Implemented PfapiStoreDelegateService
- Feature flag: useOperationLogSync already existed
- SaveToDbEffects gating: Now filtered by feature flag
Update architecture to reflect B-Lite delegate pattern:
- Exclusive persistence based on feature flag
- PfapiStoreDelegateService reads from NgRx store
- Backward compatibility flush when disabling op-log mode
When useOperationLogSync is enabled:
- SaveToDbEffects is completely disabled (no writes to 'pf' database)
- Legacy sync (WebDAV/Dropbox) reads from NgRx store via delegate
- Non-NgRx models (reminders, archives, plugins) are loaded from 'pf' DB on-demand
Key changes:
- Add PfapiStoreDelegateService to read sync data from NgRx store
- Wire up delegate in PfapiService based on useOperationLogSync config
- Flush NgRx state to 'pf' database when disabling op-log mode
This approach simplifies PFAPI/OpLog integration by making SUP_OPS
the write path while keeping PFAPI functional for legacy sync.
- Add useOperationLogSync feature flag to SyncConfig (default: false)
- Restore and gate SaveToDbEffects by feature flag
- Add provider gating in sync.service.ts (op-log disabled for all providers)
- Add delegate pattern in Pfapi.getAllSyncModelData() for NgRx reads
- Add dependency retry queue in OperationApplierService (max 3 retries)
- Update tests to provide required mocks
When useOperationLogSync is false (default), legacy sync behavior is
preserved. This ensures backward compatibility while laying groundwork
for future operation log sync support.