Replace self-service checkout with a needs form and booking step - #1011
Merged
Conversation
spashii
force-pushed
the
feat/pricing-configurator
branch
3 times, most recently
from
August 25, 2026 07:15
0cc836a to
eb66a77
Compare
A person who reaches a plan limit answers a few questions and books a call; existing subscribers keep managing their subscription. Blocked controls stay visible and open a popover that names the feature; one modal serves every mount point, with the step in the url, nothing required, a real skip, and answers restored after a reload. Free text takes voice through the existing composer where a transcription context exists. The booking step embeds cal.com with a reference and a plain summary prefilled, and falls back to a plain link when the embed does not load. The confirmation reports a booking only after cal.com confirms it. Underneath: one additive Directus collection with an idempotent migration and its snapshot; an upsert endpoint keyed on the session id with identity derived server side and answers saved before optional audio; the content security policy admits the cal.com embed; analytics hooks are wired and not yet captured; the billing surface shows no checkout to accounts without a subscription and is unchanged for subscribers and managed accounts; the tier price components and the personal booking link are removed; documentation describes plan capabilities and points pricing questions to the contact flow; catalogues are extracted and compiled.
spashii
force-pushed
the
feat/pricing-configurator
branch
from
August 25, 2026 07:16
eb66a77 to
8afa9f3
Compare
The stateless transcription endpoint accepts purpose=pricing_intake from any signed-in session with no project: nothing is metered, the size cap stays, a tighter per-user rate limit applies, and every existing caller path is unchanged. The intake's free text boxes use it where no project exists, so the record button renders on organisation and workspace mounts as well. The create-workspace access step opens the same popover as the other gated controls instead of showing disabled options. The Dutch catalogue carries every new intake string.
When cal.com confirms a booking inside the intake, the client reports the uid, status and start time to the same endpoint under the same session id, fire and forget with one retry; the confirmation never waits. The server writes the uid and status onto the row and keeps the start time in the row's json; a booking write never lowers the row's status, the same uid merges, a different uid wins and re-arms the notification. A scheduled forwarder, shaped like the support one, posts one message per unnotified booking to the support webhook with kind pricing_booking, the reference, the booking, the contact fields and a short summary of the answers, stamps the row only on a 2xx, and is a no-op without the webhook settings. One new field, booking_notified_at, in the migration and the snapshot.
spashii
marked this pull request as ready for review
August 25, 2026 10:37
spashii
enabled auto-merge
August 25, 2026 10:37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Self-service checkout is replaced by a needs form and a booking step. A person who reaches a plan limit answers a few questions and books a call; existing subscribers keep managing their subscription.
Draft. Translations, analytics capture and a final walkthrough are still open. See the list at the end.
What changes for a person
What changes underneath
pricing_configuration, one idempotent migration inecho/directus/migrations/, the snapshot carries it. No existing field or collection is changed.POST /api/v2/pricing-configurations, upsert onconfig_session_id. Identity fields are derived server side; answers are saved before optional audio, and storage failures are reported separately. 16 tests.frontend/vercel.json):app.cal.comandcal.comin frame-src, script-src, connect-src and font-src, for the embed.Deployment
Apply the additive schema change before deploying. The frontend calls the new endpoint on its final step; if the frontend lands before the API, that step retries until the API is up, and nothing is lost.
Checks
tsc,biome lint,vite build, vitest for the pricing, workspace and billing components. Two failures inuseChunkAnchorScroll.test.tsxpredate this branch (missing jsdom directive).tests/test_pricing_configurations.py. The migration is idempotent (second run is a no-op); upsert and access guards verified against a local stack.Still open before this leaves draft