Skip to content

feat(data): implement core local-first data model, CRUD, and conflict… - #17

Merged
MaximilianRau04 merged 3 commits into
mainfrom
feature/local-first-data-model
Aug 24, 2026
Merged

MaximilianRau04 merged 3 commits into
mainfrom
feature/local-first-data-model

Conversation

@priyanshuvishwakarma273403

Copy link
Copy Markdown
Collaborator

Description
This PR designs and implements the core offline-first storage and reconciliation layer for DocsGraph. It provides the schema migrations, data store class (LocalStore), conflict-resolution mechanics, and automated unit tests required to support clean offline operations and synchronization with the remote backend.

Key Implementation Details

  1. Persistent Storage Schema (0002_data_model.sql)
    Created tables for all core entities: documents, parties, clauses, and relationships (representing the document graph).
    Created an append-only sync_ops table to track client mutations (create, update, delete) and their server synchronization/sequence state (seq).
    Added indexes on foreign keys (clauses.document_id), relationship lookups, and sequence tracking to ensure high-performance lookups.
  2. LocalStore (packages/data/src/store.ts)
    Implemented a unified LocalStore data access layer interacting through the SqliteAdapter interface.
    Offline CRUD: Complete transaction-safe CRUD operations for all entities. Any local mutation automatically records a corresponding SyncOp to the log with a seq set to NULL to denote unsynced status.
    Auto-Migrations: Implemented the schema verification loop (initialize()) to detect database state and apply pending migrations sequentially.
  3. Last-Write-Wins (LWW) Conflict Resolution (packages/data/src/sync/conflict-resolution.md)
    Documented and implemented a field-level Last-Write-Wins strategy.
    When applying incoming remote operations (applyRemoteOps):
    If the entity has no pending offline edits (seq IS NULL in sync_ops), remote changes are applied directly, and last_seq advances to the server's sequence number.
    If the entity has unsynced offline updates, the local modifications take precedence on a field-by-field level. Fields modified locally offline are preserved, while other non-overlapping fields are updated with remote values.
    Remote deletion is ignored if there are unsynced edits, preserving user input.
  4. Verification & Testing (packages/data/src/store.test.ts)
    Introduced a lightweight, memory-efficient in-memory SQLite database simulator.
    Added comprehensive unit tests covering:
    Idempotent schema migrations and meta version setting.
    Full CRUD lifecycle for documents, parties, clauses, and relationships.
    Transaction-safe local operational logging.
    Server acknowledgment mapping (applyAck updating sequences).
    Field-level conflict resolution (verifying overlapping offline edits are preserved while non-overlapping fields are updated).

@MaximilianRau04 MaximilianRau04 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid CRUD/migration layer with good test coverage. One thing worth fixing before this touches real remote data.

Comment thread packages/data/src/store.ts Resolved
…T and UPDATE dynamic queries to prevent SQL injection

@MaximilianRau04 MaximilianRau04 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified: allowlist is real and enforced in both the INSERT and UPDATE paths, table name isn't attacker-controlled. Approving.

@MaximilianRau04
MaximilianRau04 merged commit 5d1242f into main Aug 24, 2026
1 check passed
@MaximilianRau04
MaximilianRau04 deleted the feature/local-first-data-model branch August 24, 2026 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants