Sync engine (critical):
- SyncWorker now pulls server ops for EVERY tracked list, not just
lists with pending local outbox ops. Previously remote edits on
'quiet' lists (incl. shared/joined lists) never arrived.
- SyncWorker advances the local HLC with each incoming server op
(tick(op.hlcTs)) so LWW is correct across devices with skewed
clocks; previously a fast-clock device permanently won conflicts
and a slow-clock device's own edits were silently rejected.
- Added missing 'list_create' branch in applyServerOpProjection.
- Use server hlc_ts for createdAt/updatedAt in projections so lists
and items keep a stable order instead of jumping by sync time.
- Prune old synced op_log rows (deleteOldSynced) to bound growth.
- Added ListDao.getAllListIds() one-shot query for the pull loop.
Build / runtime (critical):
- Added proguard-rules.pro with keep rules for kotlinx.serialization
serializers and Retrofit interfaces; release builds with R8 would
otherwise crash with SerializationException on the first API call.
- Added network_security_config.xml allowing cleartext only to
10.0.2.2/localhost so the debug build can reach the local backend
(blocked by default on Android 9+).
- Manifest: disable default WorkManager initializer so Hilt's
HiltWorkerFactory is used (otherwise SyncWorker can fail to
instantiate); added ACCESS_NETWORK_STATE permission.
Data safety (critical/major):
- Removed fallbackToDestructiveMigration from DatabaseModule: in a
local-first app a destructive migration on schema bump would wipe
the source of truth. Provide explicit Migrations instead.
- ShoppingRepository: wrap every local projection write + op_log
insert in db.withTransaction{} so a crash between them can no
longer silently lose a pending sync op.
- ShoppingRepository: replace manual JSON string concatenation with
kotlinx.serialization buildJsonObject; the old escapeJson did not
handle tab/CR/control chars, producing malformed op payloads.
- Persist device clientId and clientSeq counter in SessionManager so
they survive process restarts (idempotency stays stable per device).
- Trigger immediate + periodic sync after login/register/OIDC so
users see their lists without waiting up to 15 minutes.
.gitignore: ignore desktop.ini and backend/.testbin.
60 lines
841 B
Text
60 lines
841 B
Text
# === Secrets / local env ===
|
|
.env
|
|
.env.*
|
|
!.env.example
|
|
deploy/.env
|
|
*.pem
|
|
*.key
|
|
|
|
# === Go ===
|
|
backend/bin/
|
|
/backend/server
|
|
/backend/migrate
|
|
*.exe
|
|
*.exe~
|
|
*.dll
|
|
*.so
|
|
*.dylib
|
|
*.test
|
|
*.out
|
|
/backend/coverage/
|
|
|
|
# === sqlc generated (keep if committed; uncomment to ignore) ===
|
|
# backend/internal/store/sqlc/
|
|
|
|
# === IDE / OS ===
|
|
.idea/
|
|
.vscode/
|
|
*.iml
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
# === Agent / tooling local data ===
|
|
.zcode/
|
|
backend/.testbin/
|
|
|
|
# === Windows system files ===
|
|
desktop.ini
|
|
Thumbs.db
|
|
|
|
# === Docker ===
|
|
deploy/data/
|
|
|
|
# === Android / Gradle ===
|
|
android/.gradle/
|
|
android/build/
|
|
android/app/build/
|
|
android/local.properties
|
|
android/captures/
|
|
android/.cxx/
|
|
*.apk
|
|
*.aab
|
|
*.ap_
|
|
*.dex
|
|
*.keystore
|
|
*.jks
|
|
keystore.properties
|
|
|
|
# === Gradle wrapper (KEEP gradlew + wrapper jar; ignore caches) ===
|
|
android/**/build/
|
|
!android/gradle/wrapper/gradle-wrapper.jar
|