refactor(data): tighten data-core atomicity, chunking, and dead code (#313) #438

Merged
JMR-dev merged 1 commits from refactor-313-data-core-nits into main 2026-07-08 16:42:28 +00:00
JMR-dev commented 2026-07-08 13:09:42 +00:00 (Migrated from github.com)

Addresses every below-cut data-core review nit collected in #313.

Per-nit disposition

# Nit Disposition
1 SignatureRepository.delete non-atomic delete+promote-default Fixed — new SignatureDao.deletePromotingDefault @Transaction; repo delegates + logs the promotion (PII-free)
2 MessageDao.observeSummaries dead full-scan API Fixed — removed; migrated test/debug-probe callers to getById / the paged query
3 Unchunked IN(:ids) in MailRepositoryImpl expunge/move Fixed — getRoutingByIds/deleteByIds chunked at 500 like MailPruner
4 AccountDataMigrator stale KDoc (says v1/1.json) Fixed — KDoc now v2/2.json + notes the sortOrder addition
5 DatabaseEncryption.migrate doesn't sweep -journal Fixed — sweeps -journal too (the file is in journal_mode = DELETE)
6 AccountSettingsRepository.update / SignatureRepository.create non-atomic RMW / check-then-act Fixed — both moved into DAO @Transaction helpers (readModifyWrite, insertMakingFirstDefault)

All fixes follow the codebase's established pattern (AccountDao.insertAtEnd/SignatureDao.setDefault): read-modify-write / check-then-act wrapped in a DAO @Transaction default method. No Room entity/schema change — only DAO methods were added, so no migration is needed.

Notable decisions

  • Nit 2: observeSummaries was dead in main but still used by a debug-only cache probe and several instrumented tests. The #51 CursorWindow regression guard was re-pointed at the real production pagingUnifiedFolderSummaries query (strictly better coverage); the other callers moved to targeted getById reads.
  • Nit 6a: kept the domain-level transform in the repository and routed it through a lambda-taking DAO @Transaction, so the fast JVM setter tests (clamping, field preservation) stay intact and JVM coverage is preserved.

Tests

  • JVM unit tests updated for the repository delegations (SignatureRepositoryTest, AccountSettingsRepositoryTest) + a new chunk-split case in MailRepositoryImplTest.
  • Instrumented DAO tests cover the new @Transaction behaviour (SignatureDaoTest, AccountSettingsDaoTest) and the -journal sweep (DatabaseEncryptionTest).

Local fast gate (all green)

assembleDebug + testDebugUnitTest + jacocoTestCoverageVerification (floor 0.84) + compileDebugAndroidTestKotlin + lintDebug + ktlintCheck + detekt. Full multi-API E2E runs in CI.

Closes #313

Addresses every below-cut data-core review nit collected in #313. ## Per-nit disposition | # | Nit | Disposition | |---|-----|-------------| | 1 | `SignatureRepository.delete` non-atomic delete+promote-default | **Fixed** — new `SignatureDao.deletePromotingDefault` @Transaction; repo delegates + logs the promotion (PII-free) | | 2 | `MessageDao.observeSummaries` dead full-scan API | **Fixed** — removed; migrated test/debug-probe callers to `getById` / the paged query | | 3 | Unchunked `IN(:ids)` in `MailRepositoryImpl` expunge/move | **Fixed** — `getRoutingByIds`/`deleteByIds` chunked at 500 like `MailPruner` | | 4 | `AccountDataMigrator` stale KDoc (says v1/1.json) | **Fixed** — KDoc now v2/2.json + notes the `sortOrder` addition | | 5 | `DatabaseEncryption.migrate` doesn't sweep `-journal` | **Fixed** — sweeps `-journal` too (the file is in `journal_mode = DELETE`) | | 6 | `AccountSettingsRepository.update` / `SignatureRepository.create` non-atomic RMW / check-then-act | **Fixed** — both moved into DAO @Transaction helpers (`readModifyWrite`, `insertMakingFirstDefault`) | All fixes follow the codebase's established pattern (`AccountDao.insertAtEnd`/`SignatureDao.setDefault`): read-modify-write / check-then-act wrapped in a DAO `@Transaction` default method. **No Room entity/schema change** — only DAO methods were added, so no migration is needed. ### Notable decisions - **Nit 2**: `observeSummaries` was dead in `main` but still used by a debug-only cache probe and several instrumented tests. The `#51` CursorWindow regression guard was re-pointed at the real production `pagingUnifiedFolderSummaries` query (strictly better coverage); the other callers moved to targeted `getById` reads. - **Nit 6a**: kept the domain-level transform in the repository and routed it through a lambda-taking DAO `@Transaction`, so the fast JVM setter tests (clamping, field preservation) stay intact and JVM coverage is preserved. ## Tests - JVM unit tests updated for the repository delegations (`SignatureRepositoryTest`, `AccountSettingsRepositoryTest`) + a new chunk-split case in `MailRepositoryImplTest`. - Instrumented DAO tests cover the new `@Transaction` behaviour (`SignatureDaoTest`, `AccountSettingsDaoTest`) and the `-journal` sweep (`DatabaseEncryptionTest`). ## Local fast gate (all green) `assembleDebug` + `testDebugUnitTest` + `jacocoTestCoverageVerification` (floor 0.84) + `compileDebugAndroidTestKotlin` + `lintDebug` + `ktlintCheck` + `detekt`. Full multi-API E2E runs in CI. Closes #313
mergify[bot] commented 2026-07-08 13:32:20 +00:00 (Migrated from github.com)

Merge Queue Status

This pull request spent 3 hours 10 minutes 13 seconds in the queue, including 1 hour 22 minutes 14 seconds running CI.

Required conditions to merge
<!--- DO NOT EDIT -*- Mergify Payload -*- {"version": 1, "state": "merged", "queue_rule_name": "default", "queued_at": "2026-07-08T13:32:17.881042+00:00", "estimated_time_of_merge": null, "speculative_check_pr": null, "required_conditions": []} -*- Mergify Payload End -*- --> # Merge Queue Status - ✅ **Entered queue** — `2026-07-08 13:32 UTC` · Rule: `default` · triggered by merge protections - ❌ **Checks failed** — `2026-07-08 13:58 UTC` · on draft #441 - ✂️ Bisecting to identify the failing PR (round 1/1) - ✅ **Checks passed** · on draft #447 - ✅ **Merged** — `2026-07-08 16:42 UTC` · at `d0ed168fcb7b967ec74cd22c206aa23213c393c3` · merge This pull request spent **3 hours 10 minutes 13 seconds** in the queue, including **1 hour 22 minutes 14 seconds** running CI. <details> <summary>Required conditions to merge</summary> - `-conflict` - [X] #438 - `-draft` - [X] #438 - [X] `base = main` - [X] `check-success = CI passed` - `github-review-approved` [🛡 GitHub repository ruleset rule `main`] - [X] #438 - `label != broken` - [X] #438 - [X] any of [🛡 GitHub branch protection]: - [X] `check-success = Debug build` - [ ] `check-neutral = Debug build` - [ ] `check-skipped = Debug build` - [X] any of [🛡 GitHub branch protection]: - [X] `check-success = Unit tests` - [ ] `check-neutral = Unit tests` - [ ] `check-skipped = Unit tests` - [X] any of [🛡 GitHub branch protection]: - [X] `check-success = CI passed` - [ ] `check-neutral = CI passed` - [ ] `check-skipped = CI passed` - [X] any of [🛡 GitHub repository ruleset rule `main`]: - [X] `check-success = @github-actions/CI passed` - [ ] `check-neutral = @github-actions/CI passed` - [ ] `check-skipped = @github-actions/CI passed` </details>
Sign in to join this conversation.