console: fix comments this branch left describing the old email.json shape (final review, item 6)
Four comments this branch falsified: - mailevents_test.go's TestTheMailLogGoesToTheAppSESSaysSentIt doc comment still said counts are "attributed by the domain, as they always were" — false since senders; it now says counts follow the caller-named sender and fall back to the domain only when SES names nobody CARLOS minted. - apimail.go's handleAPIEmailPause comment still said SetPaused and ApplyGrant "write only email.json". - appsettings.go's MailCard doc comment still named apps/<acct>/<app>/email.json as the record it views. - ownership.go's purge-ordering comment still said release.PurgeApp "deletes email.json out from under it". All four now name the sender record (email/senders/app.json) and, where relevant, the email.json read fallback.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4 files changed,
+17
−13
internal/console/apimail.go+2 −1internal/console/appsettings.go+3 −2internal/console/mailevents_test.go+5 −4internal/console/ownership.go+7 −6
CI passed — run details
diff --git a/internal/console/apimail.go b/internal/console/apimail.go| index cfee73b3f..5a22ae60a 100644 |
| --- a/internal/console/apimail.go |
| +++ b/internal/console/apimail.go |
| @@ -1481,7 +1481,8 @@ func (s *Server) handleAPIEmailPause(w http.ResponseWriter, r *http.Request) { |
| detail = append(detail, fmt.Sprintf("daily cap raised to %d", req.DailyCap)) |
| } |
| s.audit(acct, app, addr, "email-pause", strings.Join(detail, "; ")+" (cli)") |
| - // No bumpSerial: SetPaused and ApplyGrant both write only email.json, |
| + // No bumpSerial: SetPaused and ApplyGrant both write only the sender |
| + // record (email/senders/app.json, with an email.json read fallback), |
| // never the app's own delivered config. |
| s.mailWalkReply(ctx, w, acct, app, rec) |
| } |
diff --git a/internal/console/appsettings.go b/internal/console/appsettings.go| index 907f244da..702388fb1 100644 |
| --- a/internal/console/appsettings.go |
| +++ b/internal/console/appsettings.go |
| @@ -189,8 +189,9 @@ type StoreCard struct { |
| CanDestroy bool |
| } |
| -// MailCard is the Settings tab's view of apps/<acct>/<app>/email.json (issue |
| -// #240, mail.Record): tenant email's Settings card, mirroring StoreCard verb |
| +// MailCard is the Settings tab's view of the app sender, apps/<acct>/<app>/ |
| +// email/senders/app.json with an email.json read fallback (issue #240, |
| +// mail.Record): tenant email's Settings card, mirroring StoreCard verb |
| // for verb — same declare -> provision -> deliver -> rotate shape, same |
| // read-only presentation, same error discipline (mailCard's doc comment). |
| // |
diff --git a/internal/console/mailevents_test.go b/internal/console/mailevents_test.go| index 7c64489b7..f82a8285c 100644 |
| --- a/internal/console/mailevents_test.go |
| +++ b/internal/console/mailevents_test.go |
| @@ -118,10 +118,11 @@ func TestTheMailLogForgetsAfterThirtyDays(t *testing.T) { |
| } |
| } |
| -// Two apps can send from one domain. Their counts are attributed by the |
| -// domain, as they always were; the log is narrower wherever SES names the |
| -// sender, because a recipient's address is one app's business, not every |
| -// app's that happens to share a From domain. |
| +// Two apps can send from one domain. The log is narrower wherever SES names |
| +// the sender, because a recipient's address is one app's business, not |
| +// every app's that happens to share a From domain; the counts follow the |
| +// same caller-named sender now (design §8) and fall back to charging every |
| +// app on the domain only when SES names nobody CARLOS minted. |
| func TestTheMailLogGoesToTheAppSESSaysSentIt(t *testing.T) { |
| fx := newConsoleFixture(t) |
| ctx := context.Background() |
diff --git a/internal/console/ownership.go b/internal/console/ownership.go| index b479bab17..d183623bb 100644 |
| --- a/internal/console/ownership.go |
| +++ b/internal/console/ownership.go |
| @@ -445,12 +445,13 @@ func (s *Server) handlePurgeApp(w http.ResponseWriter, r *http.Request) { |
| // mail.Teardown is the ONLY place that releases this app's domain |
| // claims — the create-only global gate at |
| // email/domain-claims/<domain>.json (spec §4a) — and release.PurgeApp |
| - // below deletes email.json out from under it. Without this, a purged |
| - // app leaves a live IAM user with an active key, its SES identity, its |
| - // published DNS, and — worst — a domain claim that DomainRecord.Apps |
| - // can never again name this (now-deleted) app to release: the domain |
| - // is denied to every CARLOS account, including its rightful owner, |
| - // permanently. |
| + // below deletes the sender record (email/senders/app.json, plus a |
| + // legacy email.json if one is still there) out from under it. Without |
| + // this, a purged app leaves a live IAM user with an active key, its |
| + // SES identity, its published DNS, and — worst — a domain claim that |
| + // DomainRecord.Apps can never again name this (now-deleted) app to |
| + // release: the domain is denied to every CARLOS account, including |
| + // its rightful owner, permanently. |
| // |
| // mail.Teardown is nil-record-safe (it sweeps this account's domain |
| // records and this app's ORPHANED claims even when the app never |