V2 Release Smoke Testing
Run the exact anonymous-route and API contract gate against a V2 deployment.
V2 Release Smoke Testing
Clean Estimate V2 includes a zero-dependency smoke gate for checking the deployed web boundary before deeper workflow QA begins. Run it against the same preview or production deployment that will receive manual testing:
node qa/ui-smoke.mjs <target-deployment-url>Replace <target-deployment-url> with the exact preview or production URL being approved. A pass against a different deployment is not a release gate for the target build.
If the exact preview uses Vercel Deployment Protection, provide the project's automation bypass secret without placing it in the command history or shared QA output:
# SMOKE_VERCEL_BYPASS must already be injected by the secret manager.
node qa/ui-smoke.mjs <target-deployment-url>The harness sends the value only in Vercel's protection-bypass request header and never prints it. A Vercel SSO redirect means the smoke gate did not reach the app and is not a pass.
Pull-request release evidence comes from the repository's required build and test checks, the isolated PostgreSQL race suites when a change adds them, the Vercel preview, exact-target smoke verification, and an exact-head Codex review requested on the PR. The earlier Claude review workflows were only a proposed integration and had no configured review service, so they are not a release gate and no longer run or create false failed checks.
Production schema promotion gate
Vercel's Git integration and the repository's GitHub Actions workflow start independently after a merge to main. A successful Vercel build is therefore not evidence that the production database migration has finished.
The Vercel project must require the GitHub Actions migrate-production job as a Deployment Check before it promotes or aliases a new build to the production domain. That job waits for the complete CI and production-build gates, validates that production migration configuration is enabled and present, and applies the committed migration chain. Missing configuration or a migration failure must leave the check failed and the previously promoted application live.
This ordering protection is not active from repository code alone. The V2 Vercel project now has the GitHub migrate-production check configured as a required production check that blocks production alias assignment, with a 3,600-second timeout for the complete CI, build, and migration chain. Keep the job name stable and confirm the check remains present before each release. Do not replace it with a hand-run migration or a local CLI production deployment; Force Promote is an emergency bypass and is not a normal release path.
Each page or API probe has a 15-second deadline. A deployment that accepts a connection but stalls therefore records a failed assertion and lets the gate finish instead of waiting indefinitely. Receiving redirect headers does not count as a pass when that response body then stalls.
The gate fails unless all of these contracts are exact:
- Every named office page redirects an anonymous request directly to the
same-origin /sign-in page and preserves the full requested URL for return after authentication. This contract also applies to direct HTTP probes and link scanners that do not send browser-navigation headers; a Clerk 404 protection rewrite is not a pass.
- The public home renders the CleanEstimate application shell and its dedicated
root-page bundle. The sign-in page must include both the mounted Clerk browser loader and its dedicated sign-in route bundle. Generic HTML, another app route, or a page containing the words "sign in" does not pass these public-surface checks.
- A random invalid proposal token reaches the mounted public API and returns
its structured not-found response. A generic HTML 404 or ordinary 200 page does not pass.
- Tasks, Price Book, Plans, and Canvassing reach their real mounted tRPC procedures and
return that procedure's structured UNAUTHORIZED response. A missing procedure or anonymously readable response does not pass.
The current protected route inventory includes Clients, Pipeline, Leads, Estimates, Approvals, Inbox, Tasks, Price Book, Calendar, Plans, Canvassing, Ops, Invoices, Reports, and Settings. The shared sales-and-operations Calendar uses the protected /calendar route and keeps All jobs on the same page. /jobs remains a protected compatibility and job-detail route, and the office invoice list, builder, detail, and authenticated preview remain protected under /invoices. Public proposal (/q/...) links, one-invoice bearer links (/i/...), customer account entry and account-authenticated invoice pages, authentication pages, and the home page are explicitly outside the office-route guard. Their own token or customer-session contracts must still reject unrelated records.
For customer-link rendering checks with approved QA records, provide the optional token variables:
SMOKE_QUOTE_TOKEN=<qa-proposal-token> \
node qa/ui-smoke.mjs <target-deployment-url>Do not use a real customer's link in automated or shared QA output. The smoke gate is read-only, but opening a valid customer link may record an engagement view. When SMOKE_QUOTE_TOKEN is present, the gate calls the proposal JSON API directly and requires its successful customer-safe contract, including the organization, customer block, status, immutable revision, sent time, and selectable options. The customer block must contain only the supported name, service-address, and location-name fields with their documented nullable text types; unexpected internal fields fail the gate. A 200 customer-page shell is not enough to pass.
Release order
- Confirm the production build was promoted only after its exact-commit
migrate-production Deployment Check succeeded.
- Run the automated smoke gate against the target deployment.
- Walk the money path, Calendar, plans, tasks, Price Book, and customer portal
on that same deployment using approved QA records.
- Spot-check the role and location permission matrix with separate accounts.
- Confirm the deployment's error monitoring is clean before release.
For the standalone-job release, use only an approved synthetic QA customer and saved property. With a Manage calendar account, create one unscheduled job and verify its single immutable job number, exact property, All jobs search, job detail, and client Work row. Then use a separate request to attempt a scheduled overlap on an approved QA crew: confirm the first attempt creates no job or number, provide the explicit override reason, and confirm the retry creates exactly one scheduled job. Re-submit the successful command only in an isolated test environment where its request identity can be retained, and confirm it resolves to the same job and number. A user without Manage calendar, a company portfolio parent, an inactive or cross-office customer, and an archived or cross-office property must fail closed. Verify one pre-release row still shows Legacy job rather than inventing a number. Remove the synthetic jobs and related QA artifacts through the approved cleanup procedure; do not use a production customer or crew schedule.
This smoke gate checks reachability and anonymous access boundaries. It does not replace authenticated workflow testing, database authorization tests, or the stress-testing readiness drill.
Related articles
Was this article helpful?
Still need help? Contact support