Add optional sync backend for multi-device synchronization#54
Add optional sync backend for multi-device synchronization#54bl4ckh4nd wants to merge 2 commits intoBEKO2210:mainfrom
Conversation
… support - Add package.json with dependencies and scripts for starting the server and running tests. - Implement server.js with endpoints for device pairing, sync push/pull, and health check. - Create SQLite database schema for households, devices, entities, and changes. - Implement logic for handling changes with last-write-wins strategy and tombstone deletes. - Add server tests for pairing devices, authentication, sync operations, and error handling.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fe39d661aa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
src/lib/db.ts
Outdated
| barcode: typeof payload.barcode === 'string' ? payload.barcode : existing?.barcode, | ||
| category: |
There was a problem hiding this comment.
Preserve explicit field clears during product sync
In applyProductUpsertFromSync, optional fields default to existing whenever a key is missing, but outbound sync payloads are JSON-serialized (see pushChanges) so undefined fields are dropped. This means clearing optional product fields (e.g. barcode, notes, photo, minStock) on one device is transmitted as an omitted key and other devices keep the old value, so state does not converge after sync.
Useful? React with 👍 / 👎.
src/components/Settings.tsx
Outdated
| {!syncIsPaired ? ( | ||
| <button |
There was a problem hiding this comment.
Allow re-pairing after changing sync backend
The pair flow is hidden once syncIsPaired is true, but that flag only checks whether stored credentials exist. If the user edits Server URL (or the backend data is reset), the app keeps old household/token credentials, sync calls fail with authorization errors, and there is no UI path to enter a sync code and pair again, leaving users stuck unless they manually clear storage.
Useful? React with 👍 / 👎.
P1: toSyncProductPayload now serializes optional fields (barcode, photo, minStock, notes) as explicit null instead of omitting them via JSON.stringify. applyProductUpsertFromSync uses 'key in payload' to distinguish an intentional clear (null) from an absent key (fallback to existing), so clearing a field on one device correctly propagates to peers. P2: Add a 'Neu koppeln' path in Settings that clears stored pairing credentials (householdId/deviceToken) and shows the sync-code input again, allowing users to re-pair after switching servers or resetting backend data.
Summary
updatedAttimestamps (last-write-wins)Architecture
sync-backend/— Node.js server (Fastify, SQLite viabetter-sqlite3) exposing REST endpoints for products, storage locations, and consumption logssrc/lib/sync.ts— Client sync engine: pushes local changes, pulls remote changes, resolves conflicts byupdatedAtsrc/lib/syncConfig.ts— Persists sync server URL and enabled state inlocalStoragesrc/lib/db.ts— Extended withsyncIdfields and sync queue trackingTest plan
updatedAtwinsdocker compose -f docker-compose.sync.yml upstarts the backendnpm run test)