Fix: Critical sync, build and data-safety bugs in Android app
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.
This commit is contained in:
parent
97583340a4
commit
b44bc8c3af
10 changed files with 326 additions and 141 deletions
48
android/app/proguard-rules.pro
vendored
Normal file
48
android/app/proguard-rules.pro
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# ============================================================================
|
||||
# Mitbringsl ProGuard / R8 rules
|
||||
# ============================================================================
|
||||
|
||||
# --- Kotlinx Serialization ---
|
||||
# R8 strips the serializer companions resolved via reflection unless kept.
|
||||
-keepattributes *Annotation*, InnerClasses
|
||||
-dontnote kotlinx.serialization.**
|
||||
|
||||
# Keep the @Serializable companions and their serializers.
|
||||
-if @kotlinx.serialization.Serializable class **
|
||||
-keepclassmembers class <1> {
|
||||
static <1>$Companion Companion;
|
||||
}
|
||||
-if @kotlinx.serialization.Serializable class ** {
|
||||
static **$* *;
|
||||
}
|
||||
-keepclassmembers class <2>$<3> {
|
||||
kotlinx.serialization.KSerializer serializer(...);
|
||||
}
|
||||
-keep,includedescriptorclasses class com.example.mitbringsl.**$$serializer { *; }
|
||||
-keepclassmembers class com.example.mitbringsl.** {
|
||||
*** Companion;
|
||||
}
|
||||
|
||||
# --- Retrofit ---
|
||||
# Retrofit uses reflection to parse annotations and build service interfaces.
|
||||
-keepattributes Signature, Exceptions
|
||||
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
|
||||
-keep,allowobfuscation,allowshrinking class retrofit2.Response
|
||||
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
|
||||
# Do not strip method/parameter annotations on service interfaces.
|
||||
-keepclassmembers,allowshrinking,allowobfuscation interface * {
|
||||
@retrofit2.http.* <methods>;
|
||||
}
|
||||
-if interface * { @retrofit2.http.* <methods>; }
|
||||
-keep,allowobfuscation interface <1>
|
||||
|
||||
# --- OkHttp ---
|
||||
-dontwarn okhttp3.**
|
||||
-dontwarn okio.**
|
||||
-dontwarn org.conscrypt.**
|
||||
|
||||
# --- Keep all DTO/model classes used by serialization (paranoia / safety) ---
|
||||
-keep class com.example.mitbringsl.data.remote.dto.** { *; }
|
||||
|
||||
# --- Room (KSP-generated code should be safe, but keep entities) ---
|
||||
-keep class com.example.mitbringsl.data.local.entity.** { *; }
|
||||
Loading…
Add table
Add a link
Reference in a new issue