super-productivity/packages/sync-core/tests
Johannes Millan 51bf689bd5
fix(sync): preserve multi-entity conflict recovery (#8990)
* chore: add project-scoped Angular MCP

* chore: update npm for release-age policy

* fix(sync): preserve LWW outcomes across clients

Distinguish replacement snapshots from partial merge operations, protect device-local sync configuration, recreate winning deletes, and resolve every conflicted entity in bulk operations.

Fixes #8956

* fix(sync): harden mixed LWW conflict replay

Preserve unaffected remote and local bulk intents, keep device-local sync settings during replacement replay, and gate replacement semantics behind schema v3.

* fix(sync): recover subtask subtree and harden LWW replay follow-ups

Follow-up hardening for #8956 after multi-agent review:

- Recreate a locally-winning parent's subtasks when a remote bulk delete
  is a mixed winner. The full remote delete is applied (cascade-deleting
  the parent's subtasks via handleDeleteTasks) but only the parent had a
  compensation op, so the subtree was silently lost across devices.
- extractUpdateChanges: scan array-valued payload props instead of guessing
  `${payloadKey}s`, so irregular bulk keys (e.g. taskUpdates) no longer
  return {} and drop a remote winner's changes.
- Degrade gracefully instead of throwing when a remote update wins over a
  local delete with no reconstructable base entity, matching the
  single-entity path (a permanent sync wedge is worse than the bounded
  divergence it already accepts).
- Remove dead code (unused `deleting` set + zero-caller wrapper), use the
  Set-based scoped-bulk-delete filter, type meta via LwwUpdateMode, and
  restore the withLocalOnlySyncSettings rationale comment.

Adds regression tests for the subtree-recovery and irregular-bulk-key paths.

* fix(sync): preserve conflict outcomes during replay

Persist replacement LWW operations and bulk-delete snapshots so reconstructed state matches the result applied live. Bump the op-log DB version to prevent older clients from opening the incompatible schema.

* fix(sync): persist conflict outcomes atomically

Write remote losers, local compensations, and final remote winners in one IndexedDB transaction so crashes cannot expose a partial replay order. Add real-store coverage for live/replay equivalence and transaction rollback.

* fix(sync): preserve multi-entity conflict recovery

* fix(sync): close review gaps in multi-entity conflict recovery

- recreate a winning parent's subtasks when a remote DELETE loses
  outright (single-entity or all-local-win bulk), so clients that
  applied the delete and status-blind hydration replay converge
- apply the combined resolution batch in durable seq order so a
  pending row reused from a prior failed attempt replays identically
  live and after a crash
- restamp converted remote updates carrying the v3 replacement
  envelope to the current schema version
- strip the virtual TODAY tag from LWW task payloads and shallow-merge
  patch-mode singleton payloads instead of replacing feature state
- pin the server snapshot fast-path spec to CURRENT_SCHEMA_VERSION
  (fixes the CI failure from the v2-to-v3 bump)

* test(sync): pin outright-losing delete convergence across clients

Three-way real-reducer/real-store convergence for the pure-loser path
(live == restart replay == originating client), covering both the
same-batch recreate exemption and the cross-batch recreate path.
Verified to fail against the pre-fix service.
2026-07-14 14:10:52 +02:00
..
compression.spec.ts refactor(sync): post-extraction review cleanup of @sp/sync-core and @sp/sync-providers (#7595) 2026-05-14 13:06:08 +02:00
conflict-resolution.spec.ts fix(sync): preserve multi-entity conflict recovery (#8990) 2026-07-14 14:10:52 +02:00
download-planning.spec.ts refactor(sync): extract snapshot hydration planning 2026-05-12 00:52:50 +02:00
encryption.spec.ts refactor(sync): post-extraction review cleanup of @sp/sync-core and @sp/sync-providers (#7595) 2026-05-14 13:06:08 +02:00
error.util.spec.ts refactor(sync): extract sync file prefix helpers 2026-05-11 21:21:25 +02:00
full-state-op-types.spec.ts refactor: remove dead SyncStateCorruptedError, compat exports, and 0 byte sync-providers barrel #8328 (#8396) 2026-06-15 14:16:14 +02:00
remote-apply.spec.ts fix(sync): harden op-log replay and recovery (#8978) 2026-07-13 20:03:42 +02:00
replay-coordinator.spec.ts fix(sync): harden op-log replay and recovery (#8978) 2026-07-13 20:03:42 +02:00
sync-file-prefix.spec.ts refactor(sync): post-extraction review cleanup of @sp/sync-core and @sp/sync-providers (#7595) 2026-05-14 13:06:08 +02:00
sync-import-filter.spec.ts refactor(sync): post-extraction review cleanup of @sp/sync-core and @sp/sync-providers (#7595) 2026-05-14 13:06:08 +02:00
upload-planning.spec.ts fix(sync): remediate sync-correctness review findings 2026-07-10 13:25:30 +02:00
vector-clock.spec.ts refactor(sync): post-extraction review cleanup of @sp/sync-core and @sp/sync-providers (#7595) 2026-05-14 13:06:08 +02:00