- Shipped
- August 14, 2026 at 2:10 AM UTC
- Author
- kamo
- Commit
- a948e2c
Three things were slowing /messages down before a single message was fetched. Every email call made a round trip to /api/generate-otk first and sent the result as X-OTK. No route on this side has ever read that header: the proxy mints its own single-use OTK from the caller's session in buildForwardHeaders, which is what actually authenticates the hop to EmailService. So each request was really two, the first one serial in front of the second, plus two Redis ops — across 58 call sites in 18 files, each with its own copy of the helper. One call site had already worked this out and said so in a comment; the rest are now consistent with it. The cross-origin meet handoff in page.tsx is untouched, as that OTK travels to another origin and is validated there. The folder tree was the last thing on the page to be requested, for a reason that had nothing to do with folders. FolderSidebar is a child of MessageBrowser, which renders a boot skeleton instead of its children until the provider and the member's accessible mailboxes have both answered — two serial round trips. The message list never waited, because its fetch lives in an effect and effects run whatever the component returns. Folders alone sat behind the gate. An effect now starts that request at mount, and the sidebar joins it rather than opening a second. "Which mailboxes may this member open" was asked twice on one mount, by useEmailAvailability and by MessageBrowser, each making EmailService walk the member's mailbox, department, job-title and oversight grants. Answers are now shared for thirty seconds and dropped by every call that can change them. Alongside that, /messages remembers the folder tree and the first page it last showed, per tab, and paints them while the live versions load. Cached data is only ever a first frame — every read is still followed by a real request and replaced by it — so a stale entry costs a flicker, never a wrong answer.