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

Addresses the below-cut data-core review nits from #313:

- SignatureRepository.delete: wrap delete + default-promotion in one SignatureDao
  @Transaction (deletePromotingDefault) so a crash between them can't leave an
  account with signatures but no default; log the promotion (PII-free).
- SignatureRepository.create: move the count-then-default check-then-act into a
  SignatureDao @Transaction (insertMakingFirstDefault) so two concurrent
  first-creates can't both become default.
- AccountSettingsRepository.update: route the read-modify-write through an
  AccountSettingsDao @Transaction (readModifyWrite) so concurrent per-field
  setters can't clobber each other.
- MailRepositoryImpl expunge/move/move-by-role: chunk the unbounded
  getRoutingByIds/deleteByIds IN(:ids) queries (500/chunk) like MailPruner,
  removing the latent SQLITE_MAX_VARIABLE_NUMBER crash.
- MessageDao.observeSummaries: remove the dead whole-table projection (superseded
  by Paging #124/#214); migrate test/debug-probe callers to getById or the paged
  query (which now guards the #51 CursorWindow regression).
- AccountDataMigrator: fix stale KDoc (schema is v2 with sortOrder, not v1).
- DatabaseEncryption.migrate: also sweep the stale -journal sidecar (journal_mode
  = DELETE), matching AccountDataMigrator's sweep.

Unit tests updated for the repository delegations; instrumented DAO tests cover
the new @Transaction behaviour; MailRepositoryImplTest covers the chunk split;
DatabaseEncryptionTest covers the -journal sweep.

Closes #313
This commit is contained in:
2026-07-08 08:09:12 -05:00
parent 4d724a52a8
commit d0ed168fcb
21 changed files with 348 additions and 114 deletions
+2 -1
View File
@@ -110,7 +110,8 @@ UNIFIED folder-only : SCAN TABLE messages USING INDEX index_messages_timestampMi
search (`matchesSearch`) over the small folder-scoped set — never the whole cache. `StateFlow`'s
built-in equality de-dup means an unrelated write now costs one cheap scoped re-query and no
recomposition.
- `observeSummaries()` is retained as the #51 CursorWindow regression-guard target in the DB tests.
- The #51 CursorWindow regression guard now targets the paged `pagingUnifiedFolderSummaries()`
projection in the DB tests; the superseded whole-table `observeSummaries()` was removed (issue #313).
## Deferred follow-ups