Invite-only sign-up, a console that loads once, and one subscription per workspace
Close public sign-up and still let invited people in, get a console that no longer bootstraps twice on every load, and never pay for a second subscription from a double-clicked checkout. The SDK went from 0.0.74 to 0.0.78 across the week.
Added
3- AuthenticationInvite-only sign-up. An "Allow public sign-up" switch on a new Sign-up tab under Authentication closes every door that creates a user - the hosted form, social sign-in and the monday.com webhook - while someone holding the emailed link of a live invitation addressed to them still gets in. The hosted register page says the organization is invite-only instead of showing a form that would be refused, and the account an invitee creates through the link is marked verified, since the link only ever went to that mailbox. The SDK's own invite screen passes the invitation along from @buildbase/sdk 0.0.75; an earlier SDK still shows the invitee the invite-only notice.
- NotificationsSlack posts when an API token is deactivated, reactivated, archived or restored. The event was offered on the Slack settings page and never posted: 55 events to tick, 54 that arrived. A rename or a description edit still sends nothing, and a test now fails if the settings page offers an event with no handler behind it.
- WebsiteThe homepage links each supported framework to its setup guide, with React and Node.js pointing at the Vite and Express guides for the searches that use those names. A framework without a published guide drops its tile rather than linking a 404.
Improved
10- ConsoleThe console loads once. A provider shifted position when the config answered, so React recreated everything below it on every page load: auth initialised twice, the organization list loaded twice, every shell request fired twice, and a toast raised before the config landed was dropped. A fresh sign-in also rendered the dashboard as logged out for one frame, bounced through the login page and ran the whole bootstrap again. Sign-in now lands on the dashboard in one document load, measured at zero duplicate requests across all 72 dashboard routes. Sidebar icons are bundled rather than fetched from a third-party icon service at runtime, which a self-hosted network may not reach.
- ConsoleEvery action says what it is doing. Confirmation dialogs hold their button pending until the handler finishes; archive a workflow, purge the dead-letter queue, cancel a run, make an asset public, unpublish a testimonial and rotate or revoke the export token all ask first; exports show a pending state and a completion toast; a list whose request failed shows the error instead of "Nothing yet". The last 30 raw error toasts are rewritten, and the burn-down list behind that rule is empty.
- ConsoleSwitching organization keeps your place on the keyboard. The switch remounts the shell, which destroyed the control that opened the switcher before focus could return to it, so a keyboard user finished every switch at the top of the document with the whole rail to tab through again. Focus is restored to the new switcher, and the control has an accessible name before the organization resolves. The switch itself was measured at zero frames without a shell and no document load.
- SDKuseSubscription, useAllQuotaUsage and useCreditBalance share one in-flight request instead of each sending its own copy, and an inline auth prop no longer re-dispatches the whole configuration on every render. From @buildbase/sdk 0.0.76.
- SDKA refused request keeps its HTTP status and the server's error code, so a documented 409 stops reading as an outage; the plan picker offers only the billing intervals your plans actually price; and content webhooks pass a cache-life profile so Next.js 16 stops warning on every tag. From @buildbase/sdk 0.0.78.
- SDKAn app whose own session cookie had expired kept authenticating as the previous user: the SDK still sent the stale session id and left it in storage, so the app showed signed out while requests carried the old identity. From @buildbase/sdk 0.0.74 the id is cleared with the cookie. Three public, org-scoped reads that fire before hydration can still carry it, which moves no one's data anywhere; it is reported as its own failing check in the starter's end-to-end suite until it is closed.
- WebhooksOne organization's slow receiver no longer holds every delivery slot. The queue was a single line with no notion of whose job was whose, so a receiver that answered slowly could occupy all ten slots while another organization's payment.succeeded waited behind it. At most three deliveries are in flight per organization now; one over the cap is deferred for a few seconds, not dropped. A delivery close to its five-minute signature window is sent rather than deferred, so fairness never manufactures a rejected signature.
- PlatformA momentary database stall no longer refuses every organization. In shared-client mode a five-second heartbeat timeout marked the server unknown and every request answered "Tenant database connection not available" until the next heartbeat: a 20 s stall failed 21,371 of 44,226 requests. The same stall after the change fails none, with the slowest request taking the 20 s of the stall.
- DocumentationNine docs described a product we no longer ship. Assets said any file type and named a delete route that does not exist; uploads are five image formats decided by the file's bytes. Collections still warned about two bugs that were fixed. The folder tree route, draft preview, a reporting chart that does not exist, the Slack webhook URL, the service worker push notifications need, archived short links and theming's dark class were each corrected against the shipped build, and the "Auth > Clients" path that outlived its screen is gone from docs and console alike.
- DocumentationSeven ways to sign in, not eight. The OAuth 2.0 authorization server was counted as a sign-in method on every page that prints the list and in 25 posts; it is how agents and third-party apps get access, not a way for a person to sign in, and it now has its own line. The RBAC FAQ said new teammates join as editor; they join as viewer.
Fixed
11- BillingTwo checkout sessions opened before either completed, a second tab or a second click, were both payable, and the second completion left the first subscription billing in Stripe with nothing pointing at it: two trialing subscriptions on one customer. Opening a checkout now expires the customer's other open sessions, and a completion cancels every other live subscription on that customer, refunding one that had already been charged. Four more billing edge cases are proved end to end: publishing a newer version of a plan moves nobody, a double checkout leaves exactly one subscription and refuses a third, an upgrade on a card that asks for authentication waits on the open invoice, and a promotion code typed at checkout lands on the first invoice.
- WorkspacesAn invited admin who already had an account landed on an empty console. A customer's team are usually end users of the customer's product too, so the invitee already had a row with the default user role, and the first org switch kept it: one menu item and the no-access page everywhere else, with nothing short of remove-and-re-invite to reach the role again. An invitation now lands on the role it names, custom role or tier, over any existing row, for every tier and custom role; once the membership is recorded the role chosen in the org is authoritative again. The invitation email also named no role when no custom role was chosen; it names the tier.
- WorkspacesAn invitation naming owner as the role was stored, printed "as owner" in the email, and landed the person on user; it is refused, since ownership moves by transfer. A tier named at the other tier was dropped silently; it is refused with the field to set.
- EmailAn organization over its send budget could lose mail for good. Deferring an over-budget job cost it a retry attempt, which the comment above the code said it did not, and when the attempts ran out the sender recorded the message as failed and returned, which the queue counts as success: one relay blip while throttled lost a sign-in code with nothing in the failed set. Measured against a real Redis, four deferrals left one real attempt out of five. Both the mail and webhook workers refund the attempt now, and a test fails if a third queue defers without doing the same.
- EmailThree workers counted their last attempt one early. Mail got four of its five attempts and the fifth never ran; a campaign was marked failed on attempt two of three; and the webhook delivery log printed every attempt one higher than it was, so a first try read as "attempt 2". Rows written before this keep the old numbering.
- AudienceExporting a filtered audience exported everyone. The button sat above a filtered list and sent no filter, so a list narrowed to 200 people produced a file with all of them. It sends the filter the table is showing and reads "Export filtered" when there is one.
- ConsoleSaving one field in the blog or doc editor discarded the others. Each Save button sends one field, and the response reset the whole form: saving the title threw away an unsaved description, slug and body. Only the field that was sent is folded back in.
- AuthenticationRotating a client secret hung the tenant for any client that had tracking settings. The hook that decrypts protected fields walked the document without cycle detection, a nested subdocument points back at its parent, and the walk never ended; the console showed a bare "Network Error". New clients, with no tracking settings, rotated fine.
- Access controlTwo controls were offered to roles that could not use them: Add users on a user list, to a role with read but no update, and Edit on the auth settings sheet, to a reader. The server refused both writes; what leaked was the offer. Both follow the permission now.
- ConsoleAn oversized upload answered 200 with success: false, where every other refusal on the route answers 400. The upload dialog branches on the status, so the spinner never stopped and the message was never seen. It answers 400.
- WebsiteThe contact form reported "Message sent" when the enquiry was dropped. Delivery was an unchecked fetch, which does not reject on an HTTP error, so a revoked or rate-limited webhook returned an error and the sender was told it arrived. A failed delivery now answers with the support address, and the failure is logged. The two new error pages also rendered in the browser's default serif; they use the site font.