Backend: temporary per-user BASE_URL override for dev/preview testing#8787
Backend: temporary per-user BASE_URL override for dev/preview testing#8787aapeliv wants to merge 3 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @aapeliv's task in 1m 8s —— View job Migration ReviewOne of our most common issues is migrations that don't work with existing data in production. This is very hard to catch with CI, so we have this bot to check for potential problems. Overall Risk: SAFE Files Reviewed
FindingsNo issues found.
SummaryPure additive migration creating a new, empty table — no risk to existing production data. |
|
Claude finished @aapeliv's task in 55s —— View job Migration ReviewOne of our most common issues is migrations that don't work with existing data in production. This is very hard to catch with CI, so we have this bot to check for potential problems. Overall Risk: SAFE Files Reviewed
FindingsNo issues found.
SummaryPure additive migration creating a new, empty table — no risk to existing production data. |
Replace the implicit reliance on config["BASE_URL"] in couchers.urls with an explicit context: every base_url-derived helper now takes a CouchersContext as its first positional arg and builds from a new context.base_url property (currently just config["BASE_URL"]). This threads context through the servicer, notification render, email, tasks and postal layers so that a later per-request / per-recipient BASE_URL override becomes a small change to one property. The media/console helpers are unchanged as they are not base_url-derived. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ting Lets a dev/preview frontend tell the (shared stage) backend to point every link it generates (notifications, emails, redirect URLs, ...) back at the frontend they're testing on, instead of the configured BASE_URL. Backed by an append-only user->base_url history table; the active override is the most recent row within a 15 min TTL. Resolved through a contextvar that urls.py reads, set per-request (authenticated user) and per-notification (recipient). Gated by ENABLE_DEV_APIS so it is inert in real prod. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Address review feedback on the per-user BASE_URL override: - Resolution moves onto CouchersContext.use_base_url_override (a contextmanager that sets the urls contextvar), replacing the free-floating use_base_url_override_for_user(session, user_id) helper. The interceptor and notification job now go through context, matching how the rest of the codebase carries per-operation user state. - An override is always non-empty: SetBaseUrlOverride rejects an empty base_url and the empty-string-clears-the-override semantics is gone (it expires via TTL). - Add a composite index (user_id, created) serving the active-override lookup, replacing the redundant single-column user_id index. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
df3ae38 to
1d4f64f
Compare
Adds a dev/testing mechanism to override
BASE_URLper user for ~15 minutes, so a frontend running on a Vercel preview or a mobile dev build (pointed at the shared stage backend) gets the links the backend generates — notifications, emails, redirect URLs, invite/verification links, etc. — back at whatever frontend they're testing on, rather than the configuredBASE_URL.How it works:
base_url_overridestable (user_id -> base_urlhistory). The active override for a user is the most recent row withinBASE_URL_OVERRIDE_TTL(15 min); an emptybase_urlis an explicit clear.urls.pyresolvesBASE_URLthrough aContextVarthat falls back toconfig["BASE_URL"]. The override is set for the duration of a request (from the authenticated user, in the gRPC interceptor) and for a notification job (from the recipient, inhandle_notification).ENABLE_DEV_APIS-gated debug RPCs on the Notifications service:SetBaseUrlOverride(records a row) andGetBaseUrlOverrides(returns the history, newest first, with the active one flagged).ENABLE_DEV_APIS, so it's completely inert in real prod (no rows can be created or applied, andurls.pyalways usesBASE_URL). Intended to be enabled on stage, which otherwise runs prod config.BaseUrlOverrideSyncsendswindow.location.origin; mobileuseSetBaseUrlOverridesendsEXPO_PUBLIC_WEB_BASE_URL.Note: the two debug RPCs live on the Notifications service alongside the other
ENABLE_DEV_APISRPCs, even though the override is broader than notifications — happy to move to a dedicated dev service if preferred.Testing
make formatclean;make mypyclean for changed files (the 2 reported errors are pre-existing in untouched files:tests/fixtures/misc.py,test_calendar_events.py).test_db.py) passes, confirming0158matches the model and ordinals stay linear.ENABLE_DEV_APISgating, and end-to-end notification link rewriting (with and without an override).tsc --noEmitandeslintclean on changed files.node_modules/generated proto stubs).To try on stage: set
ENABLE_DEV_APIS=1, open a preview frontend authenticated as a user, and notifications/emails for that user will link back to the preview origin for 15 min.Backend checklist
developif necessary for linear migration historyWeb frontend checklist
For maintainers
This PR was created with the Couchers PR skill.