docker-compose.e2e.yaml was failing when used standalone because the
supersync service only had a port override without a base definition.
Split into separate files so e2e:docker:webdav works without errors.
- Update CLAUDE.md to reference /src/app/op-log/persistence/ instead
of deleted /src/app/pfapi/ directory
- Fix boolean coercion in archive-migration.service.ts (same pattern
as bug fixed in 183bf2c18 for LegacyPfDbService)
- Replace deprecated .toPromise() with firstValueFrom() in
archive.service.ts for RxJS 8 compatibility
- Add null checks in simple-counter.reducer.ts to prevent crashes when
entity doesn't exist (fixes "Cannot read properties of undefined")
- Add missing entityIds to updateAllSimpleCounters action - was causing
operation log to skip persistence
- Add try-catch in operation-log-upload.service.ts to show alert when
storage quota exceeded (413 error)
- Fix supersync-network-failure.spec.ts test timing - route interception
must happen before task creation
- Add documentation to CLAUDE.md for running supersync tests with
real-time output using --reporter=line
- Fix CLAUDE.md path reference from docs/op-log/ to docs/sync-and-op-log/
- Rewrite section 2c in architecture diagrams to reflect actual implementation:
- Was: UUIDv7 timestamp replay (removed feature)
- Now: Vector clock filtering with clean slate semantics
- Update service reference from removed _replayLocalSyncedOpsAfterImport()
to SyncImportFilterService.filterOpsInvalidatedBySyncImport()
- Clarify that CONCURRENT ops are dropped, not replayed
Move scattered architecture docs into centralized locations:
- Move operation-log docs from src/app/core/persistence/operation-log/docs/
to docs/op-log/
- Flatten docs/sync/sync/ nested structure to docs/sync/
- Move supersync-encryption-architecture.md from docs/ai/ to docs/sync/
- Copy pfapi sync README to docs/sync/pfapi-sync-overview.md
- Update all cross-references to use new paths
This improves discoverability and keeps architecture documentation
separate from source code.
SYNC_IMPORT and BACKUP_IMPORT now represent a complete fresh start:
- All operations without knowledge of the import are dropped
- CONCURRENT ops from "unknown clients" are no longer preserved
- Local synced ops are NOT replayed after import
This ensures a true "restore to point in time" semantic where all
clients start fresh from the imported state, with no concurrent
work preserved.
Changes:
- Simplify SyncImportFilterService to filter ALL CONCURRENT/LESS_THAN ops
- Remove _replayLocalSyncedOpsAfterImport() method and related code
- Remove _checkOperationEntitiesExist() helper method
- Update tests to expect new behavior
- Document semantics in CLAUDE.md
Document the pattern of yielding to the event loop after bulk NgRx
dispatches to prevent state updates from being lost during rapid
dispatch sequences (50+ operations).
Selector-based effects (like preventParentAndSubTaskInTodayList$) were
firing during operation replay because they subscribe directly to store
selectors rather than actions. LOCAL_ACTIONS filtering only works for
action-based effects.
This caused duplicate operations to be captured during hydration, growing
the operation queue unnecessarily and impacting performance.
- Add HydrationStateService to track when remote ops are being applied
- Wrap OperationApplierService.applyOperations() with hydration state
- Filter preventParentAndSubTaskInTodayList$ during hydration
- Document selector-based effects anti-pattern in CLAUDE.md
Establish general rule: effects should NEVER run for remote operations.
Side effects happen exactly once on the originating client.
- Create ArchiveOperationHandler service for remote archive side effects
- Integrate handler into OperationApplierService (called after dispatch)
- Change archive.effects.ts to use LOCAL_ACTIONS only
- Update CLAUDE.md with the general rule about effects
- Add Section 8 to architecture diagrams documenting the pattern
For archive operations:
- moveToArchive: local writes BEFORE dispatch, remote via handler AFTER
- restoreTask: local via effect, remote via handler
- flushYoungToOld: local via effect, remote via handler
Tasks created without explicit dueDay don't appear in TODAY view
due to recent selector changes. Add sd:today short syntax to ensure
tasks have dueDay set and appear correctly in tests.
- Add clientId validation before persisting operations
- Track compaction failures and notify user after 3 consecutive failures
- Add hydration recovery notification when both hydration and recovery fail
- Wrap conflict resolution in try-catch for atomicity
- Add HYDRATION_FAILED, COMPACTION_FAILED, CONFLICT_RESOLUTION_FAILED translations
- Update CLAUDE.md: only edit en.json for translations
- Keep only the most useful commands:
- e2e:playwright - run all tests with minimal output
- e2e:playwright:file - run single file with detailed output
- e2e:playwright:ui/debug/headed/report - existing useful commands
- Remove complexity: test-summary.js, minimal config, redundant commands
- Use line reporter by default for cleaner output
- Update CLAUDE.md documentation
BREAKING CHANGE: Removed e2e:playwright:quick, e2e:playwright:failures, and e2e:playwright:summary commands
- Add npm run e2e:playwright:file command for running individual test files
- Update CLAUDE.md documentation with all Playwright commands
- Example usage: npm run e2e:playwright:file tests/work-view/work-view.spec.ts
- Add 'npm run checkFile <file>' to run prettier and lint on a single file
- Add 'npm run prettier:file <file>' for formatting individual files
- Add 'npm run lint:file <file>' for linting individual files
- Add 'npm run test:file <file>' for running tests on individual spec files
- Create wrapper scripts that show minimal output on success, full output on errors
- Update CLAUDE.md to emphasize using checkFile command frequently
- Add 25-second timeout for test execution to prevent hanging
* feat/merge-issue-provider-logic: (42 commits)
docs: add comment explaining GitLab issue ID format and remove debug logs
fix: extract numeric issue ID from malformed GitLab issue IDs
debug: add logging to GitLab issueLink to debug URL construction
fix: update all references from searchIssues$ to searchIssues Promise method
fix: update all references from issueLink$ to issueLink Promise method
fix: correct GitLab issue URL format
fix: change ISSUE_REFRESH_MAP to use issueProviderId as key
outline
refactor: convert pollTimer$ to simple pollInterval number
refactor: convert searchIssues$ to return Promise instead of Observable
refactor: convert getById$ to return Promise instead of Observable
refactor: convert issueLink$ to return Promise instead of Observable
refactor: convert testConnection$ to return Promise instead of Observable
feat(issue): further improve
refactor: improve typing for comment parameters in issue-content component
feat(issue): further simplify and make some conditions work as they should
refactor(issue): merge IssueFieldConfig field and getValue into unified value property
refactor(issue): use proper issue interface types instead of any casts
feat(issue): more adjustments
feat(issue): more adjustments
...