feat(logging): connectivity/send → AppLog + breadcrumbs, scrub email PII (#328) #338

Merged
JMR-dev merged 5 commits from feat-328-logging-connsend into main 2026-07-05 03:29:04 +00:00
JMR-dev commented 2026-07-05 02:23:00 +00:00 (Migrated from github.com)

Summary

  • Migrate ImapClient/SendWorker/IdleService off raw android.util.Log to AppLog, per the debug-logging strangler epic (#324), so breadcrumbs reach the RingLogBuffer and a submitted DebugReport.
  • New/kept breadcrumbs: IMAP connect (ImapClient), IDLE push message count (ImapClient), IDLE watch start (IdleService), outbox-drain queued count (SendWorker), per-message send result (SendWorker), and the existing IDLE-dropped / Graph→SMTP-fallback warnings (both migrated).
  • Closes #297: SendWorker and IdleService logged the raw account.email via Log.w on the Graph→SMTP-fallback and IDLE-drop paths. Both now log accountLogRef(account.id) instead — a short, stable, non-reversible per-account reference — so the email never reaches Logcat or a report.
  • SendWorker.doWork() grew past detekt's LongMethod threshold once the breadcrumbs were added, so the per-entity send logic is extracted into a new private sendQueued helper (behavior-preserving).

Test plan

  • Rewrote ImapClientTest/SendWorkerTest to install a real RingLogBuffer via AppLog.install(...) and assert on its contents (migrated calls + new breadcrumbs) instead of verifying a mocked Log.
  • Every relevant test also asserts no buffer line carries the test account's email — the #297 regression cover — including a dedicated `regression #297 - no send breadcrumb ever contains the account email` test.
  • Added a SendWorkerTest case that drives a real SmtpSender against an in-process GreenMail SMTP server end to end (the "connectivity/send" E2E surface for this ticket — still a JVM unit test, no emulator).
  • android.util.Log is stubbed only by fully-qualified name (never imported) in these test files, since AppLog's Logcat passthrough would otherwise crash the unmocked Android stub in a JVM test; the import stays reserved for AppLog.kt itself, matching the epic's eventual guard-rule ticket.
  • :app:testDebugUnitTest — all 14 SendWorkerTest + 24 ImapClientTest cases pass.
  • :app:compileDebugAndroidTestKotlin — androidTest source set compiles.
  • :app:ktlintCheck / :app:detekt — clean.

Closes #328
Closes #297
Part of #324

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

## Summary - Migrate `ImapClient`/`SendWorker`/`IdleService` off raw `android.util.Log` to `AppLog`, per the debug-logging strangler epic (#324), so breadcrumbs reach the `RingLogBuffer` and a submitted `DebugReport`. - New/kept breadcrumbs: IMAP connect (`ImapClient`), IDLE push message count (`ImapClient`), IDLE watch start (`IdleService`), outbox-drain queued count (`SendWorker`), per-message send result (`SendWorker`), and the existing IDLE-dropped / Graph→SMTP-fallback warnings (both migrated). - **Closes #297**: `SendWorker` and `IdleService` logged the raw `account.email` via `Log.w` on the Graph→SMTP-fallback and IDLE-drop paths. Both now log `accountLogRef(account.id)` instead — a short, stable, non-reversible per-account reference — so the email never reaches Logcat or a report. - `SendWorker.doWork()` grew past detekt's `LongMethod` threshold once the breadcrumbs were added, so the per-entity send logic is extracted into a new private `sendQueued` helper (behavior-preserving). ## Test plan - [x] Rewrote `ImapClientTest`/`SendWorkerTest` to install a real `RingLogBuffer` via `AppLog.install(...)` and assert on its contents (migrated calls + new breadcrumbs) instead of verifying a mocked `Log`. - [x] Every relevant test also asserts no buffer line carries the test account's email — the #297 regression cover — including a dedicated `` `regression #297 - no send breadcrumb ever contains the account email` `` test. - [x] Added a `SendWorkerTest` case that drives a real `SmtpSender` against an in-process GreenMail SMTP server end to end (the "connectivity/send" E2E surface for this ticket — still a JVM unit test, no emulator). - [x] `android.util.Log` is stubbed only by fully-qualified name (never imported) in these test files, since `AppLog`'s Logcat passthrough would otherwise crash the unmocked Android stub in a JVM test; the import stays reserved for `AppLog.kt` itself, matching the epic's eventual guard-rule ticket. - [x] `:app:testDebugUnitTest` — all 14 `SendWorkerTest` + 24 `ImapClientTest` cases pass. - [x] `:app:compileDebugAndroidTestKotlin` — androidTest source set compiles. - [x] `:app:ktlintCheck` / `:app:detekt` — clean. Closes #328 Closes #297 Part of #324 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign in to join this conversation.