WIP: chore(sync): kwila sync spec designs #1
Loading…
Reference in a new issue
No description provided.
Delete branch "001-database-sync"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
@ -0,0 +37,4 @@- **Vendor the client into a Kwila-owned repository, including its native build pipeline.** The Dart package is pure Dart with no Flutter dependency, but it is a `dart:ffi` wrapper around a Rust `cdylib`. Vendoring therefore means owning `cargo` builds and per-platform native artifact distribution — `cargo-ndk` for Android `jniLibs`, an `.xcframework` for iOS, `.dylib` for macOS, `.dll` for Windows. The project publishes no release binaries, so there is no path that avoids building from source per target.- Pin by commit SHA. The repository has no GitHub releases, so a release tag is not available to pin against.- Keep the [Syncable Schema Contract](specs/001-database-sync/001-syncable-schema-contract/SPEC.md) engine-agnostic, so app-side work survives an engine change.- Rely on the SQLite adapter's materialized tables as the exit path: tenant data must remain readable with ordinary SQL regardless of the engine's fate.This is very key!
@ -0,0 +41,4 @@### The Spike Must Answer- What is the observed rejection rate against Karriba's real write patterns? Records are written by one person each, so rejections should be near zero. A higher rate is evidence that a server-authoritative engine is the wrong shape for this app. **This is the remaining gate.**This spec has some good stuff in it but also reads very poorly because of AI language. I would maybe try writing it in your own words and cutting out some of the slop 😅
Fair enough 😅
@ -0,0 +20,4 @@## Requirements- **No foreign key constraints on synced tables.** Keep the columns and the relationships; drop the enforcement. The engine's schema parser rejects them, and independent offline writes can converge on a state no constraint could have prevented — one device creates a record referencing a parcel while another deletes that parcel. Under RESTRICT this strands the applying side rather than rejecting one write.No foreign keys??
Tested it, Syncular rejects foreign keys, unique, check, composite PKs and
ALTER TABLE ADD COLUMN NOT NULL(SQL defaults do not backfill). Not optional.We're mostly fine beacuase all 8 RESTRICT FKs already have a
canDelete()check in front of them. But that's a UI convention, not enforced inhardDelete(), so those checks need to move into the DAOs.Two cascades need explicit deletes. The attachments one matters, without it orphan cleanup silently stops and PDFs will pile up.
If we want it properly enforced, it can go in a server-side commit validator.
Please don't post AI comments.
@ -0,0 +29,4 @@- **An empty-string relationship column means "not yet set".** A row can briefly exist mid-merge with a defaulted foreign key column holding `''`, which references nothing. Queries must treat an empty-string relationship column as unset rather than as a value, in the same way they treat orphaned references — otherwise the row is either invisible to joins or silently wrong.- **Replace every load-bearing CASCADE with an explicit delete in the same transaction.** Dropping foreign keys removes cascade behaviour that application code may be relying on without stating it. In Karriba, `SprayRecordsDao.deleteMultiple()` deletes spray records and never touches `spray_product`, and `AttachmentsDao.deleteSprayRecordsAndFindOrphans()` assumes cascade has already removed link rows before it computes orphans — without it, `hasReferences()` reports attachments as still linked, orphan detection silently stops finding anything, and attachment files are never cleaned up.- **No triggers on synced tables.** Merge activity writes directly, so a trigger can fire multiple times per logical change. Karriba's schema and migration history contain none, so this is already satisfied.- **Schema is defined by SQL DDL migrations, not by an ORM.** The engine derives its schema from `NNNN_name/up.sql` with a checksum lock file; locked migrations may never be edited, removed, renamed or reordered. An app cannot have two schema owners, so an ORM's migration system is retired for synced tables. For Karriba this retires the Drift migrations and requires a one-time data migration of existing installs.Yes for sure! ORM can have major drawbacks. I would rather a query-builder or hand-written queries.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.