Android overhaul: stale comments and the module README
* Milestone and ownership notes that no longer hold ("owned by M5/M6/M8", "M8 replaces it", "(M8b)", "M7x add",
"proposed decision in the M5 report", which is D-027 and D-028) in build scripts, :core:design, :core:fakes, :data,
:app, :core:model and the settings string files.
* SyncEngine: the clock_skew KDoc sat orphaned above restampAfterClockSkew's; it now documents renewMutationId.
* libs.versions.toml header: no milestone, the drift date.
* README: the module table as built (no owners, no DebugFakesModule, which M8 removed), the test fixtures in the
architecture check and the shared screenshot harness.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
@@ -87,7 +87,7 @@ import javax.inject.Provider
|
||||
import javax.inject.Qualifier
|
||||
import javax.inject.Singleton
|
||||
|
||||
/** What `:app` (M8) provides: its version (§10.6) and build type (AC-2.8, AC-16.5). */
|
||||
/** What `:app` provides: its version (§10.6) and build type (AC-2.8, AC-16.5). */
|
||||
data class AppBuildInfo(val versionCode: Int, val versionName: String, val debug: Boolean)
|
||||
|
||||
@Qualifier
|
||||
|
||||
@@ -214,11 +214,6 @@ class SyncEngine(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `clock_skew` keeps the row pending (§14.4.5). The server stores rejected results by `mutation_id` and replays them
|
||||
* (§14.4.4 steps 1 and 12), so the row gets a new mutation id; otherwise it could never sync after the clock is
|
||||
* fixed (proposed decision in the M5 report). A row edited during the request already has a new one.
|
||||
*/
|
||||
/**
|
||||
* D-027 (§14.4.5 step 3): on the first attempt after a `clock_skew` rejection, every pending row stamped later than
|
||||
* the phone's clock now is re-stamped to now, so a corrected clock heals it. Rows stamped by a clock that is still
|
||||
@@ -233,6 +228,11 @@ class SyncEngine(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `clock_skew` keeps the row pending (§14.4.5). The server stores rejected results by `mutation_id` and replays them
|
||||
* (§14.4.4 steps 1 and 12), so the row gets a new mutation id; otherwise it could never sync after the clock is
|
||||
* fixed (D-027). A row edited during the request already has a new one.
|
||||
*/
|
||||
private suspend fun renewMutationId(pending: Pending) {
|
||||
val sent = pending.mutation.mutationId
|
||||
when (pending.entityType) {
|
||||
|
||||
@@ -36,7 +36,7 @@ fun interface LocalWriteListener {
|
||||
|
||||
/**
|
||||
* The sync triggers of AC-15.3 and §14.4.9: app start, every return to the foreground, 2 s after the last local write
|
||||
* (debounced), every 15 minutes in the background, and every FCM data message (expedited). `:app` (M8) calls
|
||||
* (debounced), every 15 minutes in the background, and every FCM data message (expedited). `:app` calls
|
||||
* [onAppStart], [onForeground] and [syncForPush].
|
||||
*/
|
||||
class SyncTriggers(
|
||||
@@ -85,7 +85,7 @@ class SyncTriggers(
|
||||
* WorkManager wiring (§14.4.1, §14.4.9): one-off work under the unique name `kvitt-sync` with `APPEND_OR_REPLACE`,
|
||||
* periodic work every 15 minutes with `KEEP`, both requiring a connected network, retries with exponential backoff
|
||||
* from 30 seconds. Periodic and one-off work cannot share a unique name in WorkManager, so the periodic one is
|
||||
* `kvitt-sync-periodic` (proposed decision in the M5 report).
|
||||
* `kvitt-sync-periodic` (D-028).
|
||||
*/
|
||||
class WorkManagerSyncWork(private val context: Context) : SyncWork {
|
||||
private val connected = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
|
||||
@@ -127,7 +127,7 @@ class SyncWorker(
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates [SyncWorker]s with the engine; `:app` (M8) installs it in its WorkManager `Configuration`. */
|
||||
/** Creates [SyncWorker]s with the engine; `:app` installs it in its WorkManager `Configuration`. */
|
||||
class KvittWorkerFactory(private val engine: () -> SyncEngine) : WorkerFactory() {
|
||||
override fun createWorker(appContext: Context, workerClassName: String, workerParameters: WorkerParameters): ListenableWorker? =
|
||||
if (workerClassName == SyncWorker::class.java.name) SyncWorker(appContext, workerParameters, engine()) else null
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.junit.runners.Parameterized
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* SPEC §14.3.5, M5 gate: every file under `contracts/examples/` decodes into its DTO and re-encodes to the same JSON
|
||||
* SPEC §14.3.5: every file under `contracts/examples/` decodes into its DTO and re-encodes to the same JSON
|
||||
* value (key order aside). One test case per file, so the case count equals the file count; [ExampleCoverageTest]
|
||||
* checks that no file is skipped. Sync bodies also round-trip their nested `entity` / `current` objects.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user