Repository navigation
v1.1.1
Fixed
- The logger writes an
Errorpassed in its data as its type, message,
stack,codeandcausechain. It wrote{}, so a logged failure such
as the scaffold's seeding error carried no detail. settlePendingLocalInvoicespicks its invoices at random rather than
oldest first, so an invoice that fails to settle on every run (an
amount the provider disputes, a grant that throws) no longer holds back
every invoice behind it, and starts no settle afterdeadlineMs
(default 45 s), reporting the rest asdeferred.- The
payment-pollitem's callback route answers{ ok }only. It
returned the settle summary, with each failure's message, to an
unauthenticated caller. - The scaffold's assistant route answered every request with 429: its
stand-in modelexample/echo-1had no registered price, so admission
refused it asunknown_model. The scaffold registers the stand-in at
no cost, and the route answers a refusal only the deployment can fix
with 503 and one the workspace can fix by paying with 402, and lets a
failure other than a refused guard through instead of answering 401. - The stub chat model refuses to reply in a production build, so a
deployment that never bound a real model inlib/chat-model.tsfails
loudly instead of billing its users for an echo.
INTELLIGO_ALLOW_STUB_MODEL=1, orallowInProductionin code, lets a
deployment meant to run on it do so. - Stripe amounts for ISK, UGX and MNT. Stripe takes these in hundredths
although none are in use, and they were sent as whole units — a charge
at a hundredth of its price, or refused under Stripe's minimum. Credit
checkout now converts through the newtoStripeMinor, and amounts read
back from Stripe (the payment-failed email, the admin revenue totals)
throughfromStripeMinor, both in@intelligo-dev/core/money.toMinor
keeps the whole units local payment rails take. - A Stripe subscription that ended stays ended. A payment failure that
arrives aftercustomer.subscription.deletedno longer marks it
past_due(which kept the paid plan), and the deletion drops the row's
Stripe id. A plan granted to a workspace whose Stripe subscription
ended — a local payment,grantPlan— now gets its period and lapses,
instead of being taken for one Stripe still bills. - Quota admission no longer needs a second database connection inside its
transaction. A billing settings cache miss read the settings through the
shared pool while the transaction held its connection, so a pool full of
admissions waited on each other forever. The settings are read first. - The database pool waits at most 15 seconds for a connection, so an
exhausted pool fails requests instead of hanging the process, and logs
an idle connection the server dropped instead of letting the unhandled
error end the process.DATABASE_POOL_MAXsizes it (default 10). - A chat turn stopped mid-reply is charged for the step that was running.
The finished steps were the only usage settled, so a reply stopped
before its first step finished — every one-step turn — settled at
zero while the provider billed it. The step in flight is now estimated
from its prompt and what it had streamed.
Security
- Better-Auth's organization endpoints that the team and workspace
services wrap (create, update, delete, invite, accept, reject, cancel,
remove, update role, leave) answer 404 over HTTP. Called directly they
skipped the plan's member and workspace limits and the
beforeDeleteWorkspacehook that cancels the subscription. The
services, andset-activefrom the workspace switcher, are unaffected.
A product that called these throughauthClient.organizationcalls the
services instead. - A password reset ends every session that was open before it
(revokeSessionsOnPasswordReset). AUTH_IP_HEADERSandAUTH_TRUSTED_PROXIEStell the auth rate limiter
where the client address is: without them, an app behind more than one
proxy resolved no address and put every client in one bucket.- The scaffold's
next.config.mjssendsframe-ancestors 'none',
X-Frame-Options,X-Content-Type-Options,Referrer-Policyand
Strict-Transport-Securityon every response. An existing app adds the
headers()block to its own config (intelligo upgrade --checkshows
the template changed).
Changed
- A workspace that is its owner's only one cannot be deleted, and no one
can leave their only workspace (last_workspacefrom the workspace and
team services, with messages inworkspace-settingsand
team-settings). With none left, the next page created a new personal
workspace, and with it a new start for whatever the product grants one.
Upgrading
Run intelligo sync team-settings workspace-settings app-shell payment-poll chat for the new error messages, the callback route and the seam notes. Copy
the headers() block from the scaffold's next.config.mjs into your own.
A production deployment that runs on the stub chat model sets
INTELLIGO_ALLOW_STUB_MODEL=1; one behind more than one proxy sets
AUTH_IP_HEADERS / AUTH_TRUSTED_PROXIES. Code that called Better-Auth's
organization endpoints from the browser (authClient.organization.*,
other than setActive) calls the team and workspace services instead.