Commit graph

7 commits

Author SHA1 Message Date
Johannes Millan
da8e509972 refactor(sync): unify JWT expiry to 365 days for all auth methods
Replace separate JWT_EXPIRY_MAGIC_LINK (365d) and JWT_EXPIRY_PASSKEY (7d)
constants with a single JWT_EXPIRY (365d). The auth method only matters
during login — once a JWT is issued, it represents a verified session
regardless of how the user authenticated.
2026-02-16 18:44:27 +01:00
Johannes Millan
ed061f90fb fix(sync): clamp future timestamps instead of rejecting
Operations with timestamps beyond maxClockDriftMs (60s) were being
permanently rejected, causing silent data loss when a client's clock
was slightly ahead.

Now these timestamps are clamped to now + maxClockDriftMs and accepted.
A TIMESTAMP_CLAMPED audit log is recorded for debugging.

- Add clamping logic in SyncService.processOperation()
- Remove future timestamp rejection from ValidationService
- Add comprehensive tests verifying clamped values and boundaries
- Update integration test to expect acceptance
2025-12-28 12:23:36 +01:00
Johannes Millan
a52b7716aa refactor(sync): remove tombstone system
Tombstones were used for tracking deleted entities but are no longer
needed with the operation log architecture. This removes:

- Tombstone table from Prisma schema
- Tombstone-related methods from SyncService
- Tombstone mocks and tests from all test files
- Database migration to drop tombstones table

The operation log now handles deletions through DEL operations,
making the separate tombstone tracking redundant.
2025-12-28 12:08:28 +01:00
Johannes Millan
fe8cc5e7ac fix(sync): code review fixes and parentOpId support
Code review fixes:
- Fix download memory limit to correctly return success: false
- Add logging when vector clock entries are stripped during sanitization
- Add integration test for partial batch upload recovery (network failure)

parentOpId support for conflict resolution:
- Add parentOpId field to Operation type for conflict chain tracking
- Add parent_op_id column to operations table with migration
- Update sync routes schema to accept parentOpId
- Store and retrieve parentOpId in sync service

Also adds PLUGIN_USER_DATA and PLUGIN_METADATA to allowed entity types.
2025-12-12 20:47:47 +01:00
Johannes Millan
b2c4cf1548 refactor(sync): remove ACK mechanism, simplify to time-based cleanup
Remove the acknowledgeOps mechanism and simplify server-side garbage
collection to pure time-based cleanup (delete ops older than 50 days).

Client-side changes:
- Remove acknowledgeOps from OperationSyncCapable interface
- Remove acknowledgeOps implementation from super-sync.ts
- Remove ACK call from download service (with explanatory comment)
- Remove ACK-related tests and mock server methods

Server-side changes:
- Remove ACK endpoint (POST /api/sync/devices/:clientId/ack)
- Remove updateDeviceAck and getMinAckedSeq from sync service
- Simplify deleteOldSyncedOpsForAllUsers to time-based only
- Update status endpoint (pendingOps now always 0)

Documentation updates:
- Update architecture diagrams to remove ACK references
- Update cleanup process to show 50-day time-based cleanup

This simplification was needed because fresh clients couldn't ACK
(device registration only happens on upload), causing 403 errors.
Time-based cleanup at 50 days is simpler and equally effective.

Also fixes DIAGNOSTIC test to expect server-side conflict detection
(test was written before server conflict detection was added).
2025-12-12 20:47:47 +01:00
Johannes Millan
54ad38890a test(sync-server): add gzip compression integration tests
Add two integration tests for gzip-compressed snapshot uploads:
- Verify compressed snapshots work through full route handler and sync
- Verify backwards compatibility with uncompressed snapshots

Tests simulate real multi-client scenarios where one client uploads
a compressed snapshot and another client retrieves it.
2025-12-12 20:47:47 +01:00
Johannes Millan
8e73d25200 test(sync-server): add multi-client sync integration tests
Add comprehensive programmatic integration tests that simulate multiple
clients syncing through the server without requiring Playwright/browser:

- Basic sync round-trip between clients
- Sequence continuity and pagination
- Piggybacked operations in upload responses
- Fresh client bootstrap scenarios (new device joining sync group)
- Vector clock preservation and merging
- Idempotency (duplicate op rejection)
- Multi-user isolation
- Device acknowledgment and pending ops tracking
- Concurrent uploads from multiple clients
- Delete operations and tombstone tracking
- Error cases (future timestamps, invalid entity types)
- Diagnostic tests for real-world sync scenarios

Includes SimulatedClient helper class that encapsulates client-side
sync behavior (vector clocks, sequence tracking, upload/download).
2025-12-12 20:47:41 +01:00