- Shipped
- August 9, 2026 at 5:24 AM UTC
- Author
- Kamo
- Commit
- f497600
Walks every mailbox Kamo hosts and records, per arrival day, the RFC822 bytes it holds — headers, body and encoded attachments, across every folder including Trash and Junk, since a message in Trash is still on disk. One round trip per folder: the Jakarta Mail IMAP provider expands FetchProfile.Item.ENVELOPE to ENVELOPE INTERNALDATE RFC822.SIZE, so size and arrival date arrive together. What counts is decided by whether Dovecot has credentials for the address, not by reading the provider setting. Presence in virtual_users IS the definition of "Kamo stores this mailbox", whereas a provider column can be stale, inherited from a parent, or mid-migration. A mailbox hosted by Microsoft or Google yields no credentials and is skipped, so its organization is charged nothing. Who it counts for comes from each mailbox's own org_id. KamoMail is not a single tenant — production has 18 mailboxes under one organization and 41 under another, intermixed across four domains — so summing a domain or the maildir would bill one organization for another's mail. Addresses are matched lowercased. Dovecot's user table and maildir paths are lowercase while the mailbox table keeps whatever casing the mailbox was created with, and a case mismatch here has already once split delivery and retrieval across two different maildirs. Also protects /api/internal as a whole rather than endpoint by endpoint. The filter named /api/internal/calendar and /api/internal/lead-comms individually, so the next controller mounted under that prefix — this one — would have been reachable with no secret, silently and in the direction of exposure. 6 new tests covering attribution, case handling and the not-hosted case; 152 total, all passing.