### Object of this PR
This PR is NOT a monolithic series of fixes for the payments suite + a
complete rework. Its aims were
a) introducing and robustly testing the bulldozer db system
b) reworking the payments underlying architecture to use bulldozer for
correctness and scalability
c) Achieving parity with the old payments system excepting a few changes
like ensuring correctness of the ledger algo
There may still be some work to do with handling refunds, decoupling the
concepts of purchases from that of products, and some other things.
### Ledger Algorithm
This has been tuned and fixed. Item removals i.e negative item quantity
changes will apply to the soonest expiring item grant i.e positive item
quantity change. This is what is best for the user. Item grants can also
expire, and when they expire we obviate whatever is left of their
original capacity (meaning after all the removals that were applied to
it). Our ledger algo is applied via Bulldozer, so automatic
re-computation is handled when a new grant/ removal is inserted in the
middle of the existing ones.
### Things we got rid of
* No more automatic support for default products. You can use $0 plan
provisions to accomplish the same effect but it's manual
* Negative item quantity changes (i.e item removals) no longer can have
expiries
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Enhanced payment processing pipeline with improved data consistency
and state management.
* Advanced refund handling with comprehensive transaction tracking.
* Better tracking and management of customer item quantities and owned
products.
* Improved subscription lifecycle management including period-end
handling.
* **Bug Fixes**
* Fixed payment data integrity verification.
* Improved handling of edge cases in refund scenarios.
* **Chores**
* Updated cSpell configuration with additional words.
* Expanded developer documentation for linting workflows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>
Co-authored-by: Aadesh Kheria <kheriaaadesh@gmail.com>
Co-authored-by: Mantra <87142457+mantrakp04@users.noreply.github.com>
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
## Summary
Fixes five independent UI bugs in the dashboard. Each is a narrow,
localized fix — no changes to shared table / card primitives.
### 1. Auth methods preview didn't update until save
Toggling Email/password, Magic link, or Passkey updated the switch UI
but the right-hand sign-in preview kept rendering the pre-save config
until "Save changes" was clicked. The preview was reading
`project.config` instead of the local pending state.
**Fix:** pass the computed local state (`passwordEnabled`, `otpEnabled`,
`passkeyEnabled`) into `AuthPage`'s `mockProject.config` so the preview
reflects toggles immediately.
| Before | After |
|---|---|
|

|

|
---
### 2. Email-drafts "New Draft" dropdown items stacked on two rows
Icon rendered above text in the dropdown because the icon was a child of
a non-flex inner wrapper inside `DropdownMenuItem` and phosphor icons
default to `display: block`.
**Fix:** use `DropdownMenuItem`'s built-in `icon` prop (which
absolute-positions the icon) instead of passing it as a child.
| Before | After |
|---|---|
|

|

|
---
### 3. Project-keys status filter: clicking options did nothing visible
`DesignDataTable` renders the toolbar outside the card when
`glassmorphic && !insideDesignCard`. The table instance was captured
once via `onTableReady`; filter clicks updated the table's internal
state (rows actually filtered to "No results") but the toolbar's parent
never re-rendered, so checkboxes, chip count, and button label stayed
frozen.
**Fix:** wrap `InternalApiKeyTable` in `DesignCard` so
`useInsideDesignCard()` returns true, `needsOwnCard` becomes false, and
the toolbar renders inside the `DataTable` where it re-renders normally.
No changes to the shared `DesignDataTable` component.
| Before | After |
|---|---|
|

|

|
---
### 4. Analytics "Tables" page only listed Events
`AVAILABLE_TABLES` was hardcoded to a single entry.
**Fix:** registered all 12 ClickHouse views that exist in the `default`
schema (events, users, contact_channels, teams, team_member_profiles,
team_permissions, team_invitations, email_outboxes, project_permissions,
notification_preferences, refresh_tokens, connected_accounts) with
sensible default sort columns. Widened `TableId` to `string`.
| Before | After |
|---|---|
|

|

|
---
### 5. Price input `$` prefix overlapped the number on prod
The Input composed `h-9 px-3 ... pl-7`. In production's CSS bundle order
`.px-3` declared after `.pl-7`, so `padding-left` resolved to 12px —
same as the prefix's `left-3` position — making `$` overlap the first
digit. The emulator's bundle happened to order them the other way, which
is why it only reproduced in prod. Verified with a devtools injection
that mimics the prod CSS ordering.
**Fix:** change `pl-7` → `!pl-7` in `repeating-input.tsx` so the prefix
padding wins regardless of CSS order.
| Before (prod CSS ordering) | After (same ordering) |
|---|---|
|

|

|
---
## Test plan
- [x] `pnpm --filter @stackframe/dashboard typecheck`
- [x] `pnpm --filter @stackframe/dashboard lint`
- [x] Manual verification of each issue against the local dev dashboard
at localhost:8101
- [ ] Reviewer: confirm no visual regressions on other `DesignDataTable`
usages (api-key-table is the only one wrapped here)
- [ ] Reviewer: confirm analytics queries on added tables work with the
signed-in user's permissions
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Added 12 new analytics tables to the dashboard for enhanced data
visibility and tracking.
* **Bug Fixes**
* Fixed input styling issue with prefix alignment.
* **Style**
* Improved visual presentation of data tables with enhanced card
styling.
* Refined dropdown menu icon display for better UI consistency.
* Enhanced authentication preview settings to reflect current
configuration state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Added Stripe, OAuth, and Freestyle mock services to the local emulator
* Introduced `emulator run` CLI command to execute applications with
emulator credentials automatically injected
* Enhanced credential management for local development
* **Improvements**
* Improved ARM64 QEMU emulation with cross-architecture support
* Better error detection and logging during emulator provisioning
* Added example middleware configuration with authentication support
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Owned admin apps are constructed with `tokenStore: null`, which caused
EventTracker/SessionRecorder flushes to throw from
_ensurePersistentTokenStore() after #1331 removed the silencing.
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved analytics stability and privacy by restricting session
recording and event tracking to environments with required persistent
storage.
* **Tests**
* Adjusted a few end-to-end tests to skip when running against a local
emulator to reduce spurious failures.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
… V8 --jitless
2.6 GB to 1.3 GB final image
Flip arm64 matrix back to ubicloud-standard-8 so both arches share one
runner fleet. Cross-arch TCG on an amd64 host previously SIGTRAP'd in
migrations because V8's JIT emitted arm64 instructions that QEMU's
cross-arch translator mis-handled; pair the existing -cpu cortex-a72
fallback with NODE_OPTIONS=--jitless on the migration docker exec to
force V8 to stay on the interpreter. Does not affect amd64 migrations
(KVM, no TCG).
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Optimized emulator images with binary stripping, compression, and
preservation of standalone runtime dependencies.
* Improved multi-architecture build matrix, added optional KVM
detection/fallback, and gated certain emulator runtime steps for arm64.
* Enhanced build scripts to generate and include env files and persist
richer logs and artifacts.
* **New Features**
* Centralized provision entrypoint to streamline install → migrations →
slimming sequence.
* **Tests**
* Added a fast QEMU serial boot test for architecture validation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Extended `CliAuthAttempt` with `anonRefreshToken` and a migration.
- CLI `POST /auth/cli` accepts optional `anon_refresh_token` (must be an
anonymous user's refresh token for the current project).
- `POST /auth/cli/complete` supports `mode` `check` (anonymous vs none),
`claim-anon-session` (issue tokens for the linked anonymous session),
and `complete` (bind the browser session's refresh token to the
attempt). Completing clears `anonRefreshToken` on the row. We do **not**
merge anonymous account data into the signed-in user (that behavior was
removed as a security risk; the anonymous user remains unchanged).
- Template CLI confirmation page, stack-cli optional
`STACK_CLI_ANON_REFRESH_TOKEN`, SDK/spec updates, and e2e coverage.
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* CLI login supports attaching anonymous sessions and a multi-mode
confirm/claim/check flow; CLI tools now surface login codes and remove
anon token after use.
* Added interactive CLI auth demo page and a CLI simulator script.
* Client libraries: prompt flow accepts an optional anon token and a
promptLink(url, loginCode) callback.
* **Tests**
* Expanded end-to-end coverage for anonymous CLI sessions,
claim/complete/poll flows, upgrades, and error cases.
* **Documentation**
* Updated prompt CLI docs/spec to describe new options and callback
signature.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The gate delayed flushes until an access token resolved, but sendBatch
already resolves the session itself via _getSession() at send time, so
_lastKnownAccessToken was a redundant readiness check that caused
head-of-session events to be silently dropped on slow auth init and
suppressed uploads entirely when token fetch failed.
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Simplified analytics, session-replay, and event-tracking to stop
periodic background access-token refreshes; flushing now occurs based on
buffered data and lifecycle triggers.
* **Bug Fixes**
* Anonymous-user fallback tightened: anonymous identity is only applied
when explicitly requested as "anonymous-if-exists," preventing
unintended anonymous attribution.
* **Tests**
* Updated timing helper and removed token callback from test setups to
align with the new flush behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Updated package versions for '@supabase/*' libraries to 2.99.2 and
'@supabase/ssr' to 0.9.0.
- Added new devDependencies for 'rimraf' and 'framer-motion' in the
pnpm-lock file.
- Modified Next.js configuration to conditionally omit 'X-Frame-Options'
in development mode for better integration with Stack Auth dev tools.
- Refactored component exports in the template package to include
tracking for dev tools.
- Introduced new dev tool components and context for improved logging
and state management.
- Added styles for the dev tool indicator and panel, ensuring a
consistent dark theme.
- Implemented fetch interception to log API calls and user
authentication events in the dev tool.
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Added comprehensive Developer Tools interface with tabs for Overview,
Components, AI Chat, Console, Dashboard, and Support.
* Integrated AI Chat assistant within Developer Tools for enhanced
debugging.
* Added component version tracking and update notifications.
* Implemented API request logging and event monitoring.
* Enhanced feedback system with support for bug reports and feature
requests.
* **Bug Fixes**
* Fixed Content Security Policy headers for local development
environments.
* **Dependencies**
* Added AI SDK integration packages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>
This PR fixes the bug where analytics tool returns a lot of rows, which
results in huge token count. We do it by checking the number of
characters in the tool call, and if it is more than 50000 characters, we
send an error message rather than the rows and ask the ai to make more
focused queries.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* AI assistant shows friendlier, categorized error messages and captures
unexpected errors for diagnosis.
* UI now displays classifier-derived, user-friendly AI error text.
* **Bug Fixes & Improvements**
* Enforced a hard size budget for SQL query results and gracefully
handles oversized responses.
* Centralized safer database error messaging to avoid leaking internal
details.
* Strengthened AI guidance to prefer narrower queries, safer column
selection, and pairing GROUP BY with ORDER BY + LIMIT.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR puts the ask ai functionality into the ai stack companion, along
with persistent history.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* "Ask AI" chat sidebar with streaming assistant responses, progressive
word-by-word reveal, auto-scroll, Enter-to-send and Arrow-key
navigation, "Thinking…" and error indicators
* Chat UI primitives: inline/code blocks, smart links, copy-to-clipboard
for code/URLs, and expandable tool-result cards with copyable outputs
* **Bug Fixes**
* Prevented button/menu clicks inside list items from bubbling to parent
row handlers
* **Refactor**
* Chat rendering, streaming, parsing, and UI helpers consolidated into a
shared module and integrated into the sidebar widget
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
`window.screen` and `window.history` are accessor properties on
`Window.prototype`, so `Object.getOwnPropertyDescriptor(window,
X)?.value` returned undefined in real browsers, causing `start()` to
short-circuit and never capture or send any $page-view / $click events.
Read the globals directly instead; the jsdom-based regression test pins
the accessor-descriptor shape so this can't silently come back.
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Tests**
* Added a new test suite verifying event batching, timing, page-view and
click event capture, and client-side navigation behavior using simulated
timers and DOM environment.
* **Bug Fixes**
* Improved event tracker reliability by changing how browser screen and
history are read, yielding more consistent detection of screen
dimensions and navigation for analytics capture.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR is to fix the bug pointed out by Madison on gc.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved system reliability by correcting internal guidance for
user-data handling, preventing unsafe retrieval patterns and reducing
risk of incorrect or incomplete user responses.
* **Chores**
* Tightened AI system prompts with stricter runtime validation and
selection rules to ensure user queries return accurate, privacy-safe
results.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Added new internal API endpoint for documentation tools, allowing
actions such as listing available docs, searching, and fetching specific
documentation by ID.
- Updated environment configuration to support optional internal secret
for enhanced security.
- Refactored existing search functionality to utilize the new docs tools
API instead of the previous MCP server.
- Improved error handling and response parsing for documentation-related
requests.
- Expanded documentation to clarify the relationship between the new
tools and existing API functionalities.
This update streamlines the documentation access process and enhances
the overall developer experience.
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Non-stream AI responses now include a consolidated finalText for
clearer answers.
* Added an internal docs-tools HTTP API to power doc listing, search,
and fetch with optional header-based access control and configurable
service origin.
* **Refinement**
* Consolidated multiple doc tooling paths into a single question-focused
flow; backend now routes to the unified docs-tools endpoint.
* **Documentation**
* Updated guides and knowledge base to describe the new docs query flow
and optional env configuration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- **update submodule**
- **Enhance sign-up risk assessment by adding sameEmailCount and
sameEmailLimit to recent stats request. Update loadRecentSignUpStats
function to include email normalization checks. Adjust tests to reflect
new return structure.**
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Risk scoring now tracks and reports counts of recent signups that
share a normalized email (with configurable limit), exposing this as
part of signup-risk statistics.
* **Performance**
* Added a database index and migration to speed up recent-signup
queries, improving risk assessment responsiveness.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
The ClickHouse connected_accounts table is keyed by (project_id,
branch_id, user_id, provider, provider_account_id), so updating
providerAccountId in place on ProjectUserOAuthAccount orphaned the old
CH sort-key row: the sync re-emitted the row under the new key while the
old key sat untouched with no tombstone, and FINAL couldn't collapse
them. verify-data-integrity would then report a row count mismatch for
connected_accounts.
Record a delete tombstone for the old row state before the update runs,
so the sync pipeline marks the stale sort key as deleted.
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved OAuth account update handling to ensure external database
synchronization is properly recorded when reassigning provider accounts
to different account IDs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Added support for `@opentelemetry/sdk-node` in the backend.
- Updated various dependencies including AWS SDK and OpenTelemetry
packages.
- Implemented graceful shutdown handling for non-Vercel runtimes in
`prisma-client.tsx`.
- Enhanced AWS credentials retrieval to support GCP Workload Identity
Federation.
- Introduced a Dockerfile for Cloud Run deployment, optimizing the
backend build process.
- Updated `.gitignore` to include Terraform runtime files and secrets.
This commit improves the backend's observability and deployment
flexibility, particularly for Cloud Run environments.
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* OpenTelemetry observability with dynamic provider selection per
deployment.
* Cloud Run trusted-proxy support for accurate client IP handling.
* Graceful shutdown that waits for in-flight background work.
* New background-task handling to improve async webhook/email delivery
reliability.
* AWS credential providers added (Vercel OIDC & GCP Workload Identity
Federation).
* Dockerized backend image for Cloud Run / self-host deployments.
* **Chores**
* Updated dependencies for OpenTelemetry and AWS SDK support.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>