Skip to content

fix(desktop): honor includeDeleted in observation queries #910

Description

@Mishael-2584

The small adventure

Offline-first systems do not always erase a deleted record immediately. They
often keep a tombstone long enough to tell another device, "this observation was
deleted too." ODE Desktop's structured query API accepts an includeDeleted
option, but the Rust query compiler currently ignores it.

Let's reconnect that switch. This is a contained bug fix with a useful glimpse
into how ODE preserves data history across sync.

Where to start

  • desktop/src-tauri/src/observation_query.rs
  • desktop/src-tauri/src/lib.rs (ObservationExtras and
    query_observations)
  • desktop/src/lib/formPreviewBridge.ts (getObservationsByQuery)
  • packages/observation-query/fixtures/
  • desktop/AGENTS.md

ObservationExtras.deleted is stored as JSON in the
observation_extras SQLite column. Check how other Desktop code reads that
field before choosing the SQL expression.

Expected behavior

  • includeDeleted: false excludes rows whose observation extras mark them as
    deleted.
  • includeDeleted: true includes both live rows and deletion tombstones.
  • Rows with missing or malformed deletion metadata remain treated as live,
    matching the existing default behavior elsewhere in Desktop.
  • Filtering must stay in parameterized SQL; do not fetch every row and filter it
    in TypeScript.

What to change

  • Use the existing include_deleted argument in
    compile_observation_query instead of discarding it.
  • Add focused Rust tests for both values and for rows without deletion
    metadata. A small in-memory SQLite test is encouraged because it proves the
    JSON expression, not just a string fragment.
  • Fix the suspicious fixture invocation around includeDeleted while you are
    there, and add or update a fixture if it makes the shared query contract
    clearer.
  • Keep unrelated query operators and indexes out of scope.

Done when

  • The compiled query produces the expected live/tombstone result set for
    both values of includeDeleted.
  • Existing structured query fixtures still pass.
  • Tests cover absent deletion metadata.
  • Desktop Rust tests pass; frontend checks remain green if TypeScript files
    are touched.

Verify it

From desktop/src-tauri/:

cargo test

If TypeScript is changed, also run from desktop/:

pnpm run lint
pnpm run format:check
pnpm test
pnpm run typecheck

What you will meet along the way

You will cross a real ODE boundary: a custom app calls the Formulus-style
bridge, Desktop forwards a structured request to Tauri, and Rust compiles it to
SQLite. You will also meet deletion tombstones, an unglamorous but essential
part of reliable offline synchronization.

AI tools are welcome, not required

AI can propose SQLite JSON syntax, but please verify it against the SQLite
version/features already used by Desktop and prove it with a real query test.
For data code, "the SQL looks plausible" is not verification.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions