fix(config): cache read no mutation (#1256)

Matt Van Horn created

## What?

Closes #1251

`GetCachedEmailBody` is a read operation but it was stamping
`LastAccessedAt` on the matched entry and rewriting the body cache file
on every hit, violating the read/write boundary the issue calls out.
Drops the two flagged lines (`config/cache.go:505-506`) and adds a
one-line note above the function that `SaveEmailBody` is the access-time
owner.

## Why?

The issue's analysis is correct: every email view path in `main.go`
already chases `GetCachedEmailBody` with `SaveEmailBody`, which sets
`LastAccessedAt = time.Now()` on the entry it persists. That keeps the
LRU-style eviction in `evict` (sorted by `LastAccessedAt`) working
unchanged, with one fewer disk write per email view.

I traced both call sites to verify eviction recency is preserved on
cache hits:

- `main.go:707-744` (UpdatePreviewMsg): cache hit returns
`PreviewBodyFetchedMsg{Err: nil}`. The handler at `main.go:746-779` runs
`config.SaveEmailBody` whenever `msg.Err == nil`, which updates
`LastAccessedAt` (`config/cache.go:552`).
- `main.go:1247-1278` (ViewEmailMsg): cache hit returns
`EmailBodyFetchedMsg{Err: nil}`. The handler at `main.go:1282-1328` runs
`config.SaveEmailBody` whenever `msg.Err == nil`, same path.

So an email the user repeatedly opens still bumps to the front of the
eviction queue on every open; the work just happens in `SaveEmailBody`
(which already exists) instead of duplicating it inside
`GetCachedEmailBody`.

Change summary

config/cache.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

Detailed changes

config/cache.go 🔗

@@ -495,6 +495,8 @@ func saveEmailBodyCache(cache *EmailBodyCache) error {
 }
 
 // GetCachedEmailBody returns the cached body for a specific email, or nil if not cached.
+// LastAccessedAt is updated by SaveEmailBody, not here -- a read should not
+// mutate cache state.
 func GetCachedEmailBody(folderName string, uid uint32, accountID string) *CachedEmailBody {
 	cache, err := LoadEmailBodyCache(folderName)
 	if err != nil {
@@ -502,8 +504,6 @@ func GetCachedEmailBody(folderName string, uid uint32, accountID string) *Cached
 	}
 	for i, b := range cache.Bodies {
 		if b.UID == uid && b.AccountID == accountID {
-			cache.Bodies[i].LastAccessedAt = time.Now()
-			_ = saveEmailBodyCache(cache)
 			return &cache.Bodies[i]
 		}
 	}