fix: sidebar re-expand, silent token refresh, working Gmail/Outlook connect + gap audit #4061
ccantynzcommented Jun 13, 2026
Originally written by @vercel[bot] on GitHub.
Deployment failed with the following error:
There is no GitHub account connected to this Vercel account.ccantynzcommented Jun 13, 2026
Originally written by @vercel[bot] on GitHub.
The latest updates on your projects. Learn more about Vercel for GitHub.
| Project | Deployment | Actions | Updated (UTC) |
|---|---|---|---|
| alec-rae-com-admin | Preview, Comment | Jun 13, 2026 2:50am |
Cross-repo impact
See what breaks downstream if this PR merges.
⮌ Merged
This pull request was merged into main.
c comment · e edit title · m merge · a approve · r request changes · ? shortcuts
Originally written by @ccantynz-alt on GitHub.
Imported from https://github.com/ccantynz-alt/AlecRae.com/pull/70
Addresses three issues Craig reported and the request to scan for gaps (docs were out of date).
Bugs fixed
1. Sidebar collapse was a dead end — pressing the
‹toggle ("left arrow") collapsed the nav to 64px, but theoverflow-hiddensidebar still rendered the full "AlecRae" wordmark, pushing the›expand button off the visible edge. No way back. Now the wordmark is hidden when collapsed (toggle stays visible/centered) and⌘\/Ctrl\toggles the sidebar as a guaranteed keyboard path.2. "Invalid or expired bearer token" mid-session — access tokens last 15 min; the API issues a 7-day refresh token alongside them, but the web client discarded the refresh token and never refreshed, so after 15 min idle every request 401'd and the user was silently logged out. New
apps/web/lib/auth-token.tsstores the refresh token and, on any 401, silently calls/v1/auth/refresh(single-flight) and retries once before giving up. Wired into both fetch wrappers, all login flows, and the Google callback (which now forwards the refresh token in its fragment).3. Gmail/Outlook connect was completely broken (the path to importing inboxes) — three stacked bugs: relative
/v1/connect/gmailhit the web host not the API; a top-level browser redirect carried no Bearer header (401); and the route required the unsatisfiableaccounts:writescope (403 regardless). NowGET /v1/connect/gmail|outlookreturn the OAuth consent URL as JSON via an authenticated fetch (the signedstatestill carries identity to the public callback, so no token lands in any URL) and use the satisfiableaccount:managescope. Onboarding fetches the URL, then navigates.Gap audit
Adds
PRODUCT_GAP_AUDIT.md(code-verified): the backend is genuinely deep (~96 mounted route groups, 300+ endpoints, DB-backed), but the web app exposes only a fraction. There is no working admin console (the one/adminpage is unlinked, ungated, wired to nothing), and mailbox provisioning, Google-Workspace bulk import, org/team/invite/SSO, and import jobs are all backend-only with no UI (import workers are also stubs). Craig is an owner and the sidebar shows the role badge, but cannot administer or run the business/workspace flows from the product. The gap is frontend wiring + a few stub workers, not missing backend.Verification
docs:checkgreenhttps://claude.ai/code/session_01VNLKrNfL6Z87AjCnht8DrF
Generated by Claude Code