Commit Graph

1402 Commits

Author SHA1 Message Date
mantrakp04
6cf0e899a0 Merge remote-tracking branch 'origin/dev' into devin/1782257319-migrate-config-to-jiti 2026-06-29 10:23:43 -07:00
mantrakp04
2fd1e09865 fix: update GitHub owner in seedDummyProject function
- Changed the GitHub owner from "mantrakp04" to "hexcalve" in the seedDummyProject function to reflect the correct repository ownership.

This update ensures that the dummy data seeding process points to the appropriate GitHub account.
2026-06-29 10:00:19 -07:00
devin-ai-integration[bot]
4a0f2b1778
Default user export to filtered scope; note Anonymous in all-users label (#1679)
## Summary
Two changes to the user data export dialog on the project Users page:

1. The export scope now defaults to **"Export only filtered/searched
users"** instead of "all users".
2. The all-users option label is now **"Export all users in the project
(includes Anonymous)"**.

To keep this scoped to the Users table (the shared export dialog is
reused by other tables), the dialog's default scope is made configurable
rather than changed globally:

- `DataGridExportOptions` gains `defaultScope?: DataGridExportScope`
(defaults to `"all"`).
- The dialog initializes `useState(exportOptions?.defaultScope ??
"all")`.
- `user-table.tsx` passes `defaultScope: "filtered"` and the updated
`allScopeLabel`.

Other tables (teams, transactions, emails) are unaffected — they keep
the `"all"` default.

Link to Devin session:
https://app.devin.ai/sessions/4996678b2b944090b6eef2f64f0a62a1

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Default the Users export dialog to filtered scope and clarify that the
"all users" option includes Anonymous; scope resets to the per-table
default only when the dialog reopens, and other tables keep "all".

- **New Features**
- Added `defaultScope` to export options and initialized scope from it;
Users table sets `defaultScope: "filtered"` and updates the all-users
label.
- Reset scope to `defaultScope` only on a closed→open transition to
avoid changing it while the dialog is open.

- **Bug Fixes**
- Stubbed `NODE_ENV` via `vi.stubEnv` in
`apps/backend/src/oauth/ssrf-protection.test.ts` to fix lint and prevent
env mutation.

<sup>Written for commit 3aa670b6d2.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1679?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: vedanta.gawande <vedanta.gawande@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-06-29 09:31:06 -07:00
github-actions[bot]
092c27dd0e chore: update package versions 2026-06-27 22:00:12 +00:00
Konstantin Wohlwend
c6d162e5c8 Fix negative email queue step deltas 2026-06-27 14:54:24 -07:00
mantrakp04
b7394e1bd3 Merge remote-tracking branch 'origin/devin/1782257319-migrate-config-to-jiti' into worktree-agent-afc9a08055d13e0a9 2026-06-26 18:36:05 -07:00
mantrakp04
06d3402f34 Merge remote-tracking branch 'origin/dev' into worktree-agent-afc9a08055d13e0a9
# Conflicts:
#	docs-mintlify/guides/getting-started/setup.mdx
#	docs-mintlify/snippets/home-prompt-island.jsx
#	packages/shared-backend/src/index.ts
2026-06-26 18:27:35 -07:00
Devin AI
8c24f791c1 fix(config): add UUID validation to run_id in cancel/commit/run route schemas
Adds .uuid() to the yupString() validator for run_id in all three config
agent routes (cancel, commit, run). Without this, a non-UUID string
reaches lockConfigAgentRun's ::uuid SQL cast and causes a PostgreSQL
'invalid input syntax for type uuid' exception — surfacing as a 500
instead of a clean 400.

Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-27 01:22:49 +00:00
mantrakp04
8837389870 fix: address follow-up review comments (eval error-class test, elapsed sentinel, cancel diff)
- config-eval test: assert a malformed file throws a loader error, NOT a
  ConfigFileEvalError, so the documented "Failed to load config file" routing
  is actually protected (cubic)
- progress-content: guard useElapsedSeconds against the startedAt=0 "not started"
  sentinel so the counter shows 0 instead of ~epoch-since-1970 on first paint (vercel)
- config index: clear a cancelled run's captured diff so it can't linger in the
  API shape or be replayed by the commit route (greptile observation)
2026-06-26 18:13:17 -07:00
mantrakp04
8b09fa3479 fix: address PR review comments (commit-hash re-link, cancel stranding, elapsed timer, uuid, test gap)
- index/commit route: gate commit_hash advance on committedRef identity so a
  mid-run repo re-link can't stamp a foreign commit SHA (cross-repo TOCTOU)
- github-push-dialog: cancel handler now settles the dialog itself instead of
  relying on a poll loop that has already exited at awaiting_review
- progress-content: useElapsedSeconds reacts to startedAt changes (fresh anchor)
  so a post-mount start time no longer freezes a stale offset
- schema-fields: configAgentRunSchema.id uses .uuid() to match the @db.Uuid column
- tests: cover the SyntaxError config-eval path and the re-link commit-hash case
2026-06-26 17:54:44 -07:00
mantrakp04
9b088a89d5 refactor: clarify comments in repo-agent.ts for Git diff handling
- Updated comments in the `applyConfigUpdate` function to enhance clarity regarding the handling of Git diffs and token management.
- Removed redundant token redaction logic, ensuring the diff captures the authoritative commit source without alteration.

These changes aim to improve code readability and maintainability in the configuration update process.
2026-06-26 17:31:53 -07:00
github-actions[bot]
e70e95a3af chore: update package versions 2026-06-27 00:28:49 +00:00
mantrakp04
64b885fb70 feat: enhance config agent run tracking and GitHub integration
- Added a new `ConfigAgentRun` model to track the state of configuration agent runs in the database.
- Updated the Prisma schema to include new fields for the `ConfigAgentRun` model, allowing for detailed tracking of run status, timestamps, and associated metadata.
- Introduced new API routes for starting, cancelling, and committing configuration agent runs, improving user interaction and feedback during updates.
- Updated existing routes to utilize the new `run_id` for better tracking and management of agent runs.
- Added a new dependency `diff` to facilitate change tracking in configuration files.

These changes aim to improve the overall functionality and user experience of the configuration agent integration with GitHub.
2026-06-26 17:22:24 -07:00
BilalG1
74471d8d30
feat(emails): allow custom emails on shared server with dev wrapper (#1673)
## What

Custom emails / templates / drafts sent through Hexclave's **shared
(development) email server** are no longer blocked with
`RequiresCustomEmailServer`. They are now allowed, but their **subject
and body are wrapped** at send time with a notice that this is a
development email from Hexclave, so unexpected recipients know they can
safely ignore it.

The wrapper only applies to **project-defined content addressed to the
project's own users**. Hexclave's own default-template emails
(verification, password reset, magic link, etc.) and system
notifications (credential-scanning alerts, internal feedback) are sent
**verbatim**.

## How

-
**[send-email/route.tsx](apps/backend/src/app/api/latest/emails/send-email/route.tsx)**
— removed the `RequiresCustomEmailServer` throw that blocked the shared
server.
- **[emails.tsx](apps/backend/src/lib/emails.tsx)** — added
`wrapSharedDevEmail()` (prefixes the subject with `[Hexclave dev email]`
and prepends a notice banner to HTML/text) and
`isCustomEmailForSharedServer(recipient, createdWith, templateId)`.
- **[email-queue-step.tsx](apps/backend/src/lib/email-queue-step.tsx)**
— applies the wrapper at send time, gated on `emailConfig.type ===
"shared"` **and** the email being project-defined custom content.
Applying it at send time reliably wraps both the subject (from
`overrideSubject` or the template's `<Subject>`) and the rendered HTML.

### What counts as "wrap-eligible"
`isCustomEmailForSharedServer` returns true only when **all** hold:
1. the email is addressed to one of the project's own users (recipient
type is not `custom-emails`), **and**
2. it is a draft, a custom template, or raw HTML — i.e. **not** one of
the built-in `DEFAULT_TEMPLATE_IDS`.

Condition (1) exempts Hexclave's own system senders (credential-scanning
revoke, internal feedback) which send raw HTML to bare addresses via
`custom-emails` and would otherwise be mis-classified as project
content. This was a bug caught in review — a leaked-API-key security
alert to a shared-server customer would have been prefixed `[Hexclave
dev email]` with a "you can safely ignore it" banner. The recipient type
is already persisted on the outbox row, so no schema change was needed.

## Tests

- **send-email.test.ts** — replaced the old "400 on shared config" test
with two new tests: (a) a custom email on the shared server is delivered
with the `[Hexclave dev email]` subject prefix + notice banner, and (b)
a **default template** (`sign_in_invitation`) on the shared server is
delivered **verbatim** (no prefix, no banner) — pinning the core safety
contract.
- **js/email.test.ts** — flipped the "throws RequiresCustomEmailServer"
test to assert the send now resolves.

Verified locally against a full stack:
-  `send-email.test.ts` — 18/18
-  `js/email.test.ts` — 12/12
-  `password/send-reset-code.test.ts` — passes (default templates on
shared server stay unwrapped)

## Known limitations (intentional scope)

- **Template CRUD still blocked on the shared server.**
`internal/email-templates` routes still throw
`RequiresCustomEmailServer`, so a shared-server project can send raw
HTML / a default template via the API but cannot create or edit a
*saved* custom template. Sending arbitrary HTML is unaffected; only the
saved-template editor remains gated.
- **A project can send a (project-edited) default template unwrapped**
by calling `send-email` with a `template_id` equal to a built-in
`DEFAULT_TEMPLATE_IDS` value. Low impact (requires a server key, limited
upside), noted for awareness.

## Note: freestyle-mock fix included


[freestyle-mock/Dockerfile](docker/dependencies/freestyle-mock/Dockerfile)
now also accepts `/execute/v3/script`. The `freestyle` SDK bump in #1654
moved to `/v3`, but the mock only served `/v1`+`/v2`, so **all** local
email rendering 404'd (pre-existing `dev` breakage, not from this
feature). The v3 request/response is identical to v2. Happy to split
this into its own PR if preferred.

Out of scope: `emails/email-queue.test.ts` has 2 pre-existing snapshot
failures (`margin:0` vs recorded `margin:0rem`, a
`@react-email/components` version drift in the mock) — those tests use a
custom email server, so this PR's shared-only code path never runs for
them.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Email sending can now proceed when using a shared email server.
* Development-style wrapping is applied to eligible shared-server custom
email content, including HTML notice injection.

* **Bug Fixes**
* Removed the previous blocking “requires custom email server” behavior
for shared-server configurations.
* Default-template emails over the shared server are no longer wrapped.

* **Tests**
* Updated end-to-end and JS email tests to validate both wrapped
custom-email behavior and unwrapped default-template behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-26 15:44:44 -07:00
github-actions[bot]
c868ec31bc chore: update package versions 2026-06-26 21:28:46 +00:00
github-actions[bot]
788e7cc87c chore: update package versions 2026-06-26 21:18:23 +00:00
mantrakp04
47319f221d Refactor environment and configuration files
- Removed outdated comments from `.env.development`, `.eslintrc.cjs`, and `schema.prisma` for clarity.
- Cleaned up import statements in `local-emulator.ts` and `repo-agent.ts` to improve code organization.
- Adjusted import order in `ssrf-protection.ts` and `cli.test.ts` for consistency.
- Updated `init.ts` to streamline imports and enhance readability.
- Minor adjustments in `admin-interface.ts` and `schema-fields.ts` to maintain code quality.

These changes aim to enhance maintainability and readability across the codebase.
2026-06-26 14:11:53 -07:00
mantrakp04
913f98484f Merge remote-tracking branch 'origin/dev' into devin/1782257319-migrate-config-to-jiti 2026-06-26 14:00:26 -07:00
mantrakp04
b4ed4dfb2c feat: enhance GitHub config agent integration
- Added support for a new shared backend package in the pnpm workspace.
- Updated the Prisma schema to include a new field for tracking the latest config agent run state.
- Refactored config agent scripts for improved clarity and functionality, including renaming the build image script.
- Removed obsolete scripts related to linking projects to GitHub and seeding config tests.
- Introduced a new API route to retrieve the state of the most recent config agent run, enhancing user feedback during updates.

Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-26 13:50:01 -07:00
github-actions[bot]
ee48755ef3 chore: update package versions 2026-06-26 20:38:10 +00:00
Vedanta-Gawande
164374f6c8
User page email filtering (#1668) 2026-06-26 12:27:24 -07:00
github-actions[bot]
53b0cae480 chore: update package versions 2026-06-26 19:10:16 +00:00
github-actions[bot]
fc6d111e6b chore: update package versions 2026-06-26 18:50:39 +00:00
Konstantin Wohlwend
014437f478 Better error handling 2026-06-26 11:42:22 -07:00
mantrakp04
989f318a1a chore: simplify config update agents 2026-06-26 11:35:20 -07:00
mantrakp04
57188ed78b chore: align config agent proxy defaults 2026-06-25 18:19:32 -07:00
mantrakp04
212502a00b fix: stop config agent sandbox on apply failure 2026-06-25 17:53:44 -07:00
mantrakp04
49a0c1083f chore: address config agent review cleanup 2026-06-25 17:51:08 -07:00
mantrakp04
2558a63a81 feat: implement two-phase review flow for config updates
- Introduced a new API route for committing changes after user review, allowing the agent to keep the sandbox alive for inspection before finalizing updates.
- Enhanced the existing applyConfigUpdate function to transition to an awaiting review state, storing the diff for user visibility.
- Added progress tracking and stage reporting for the config agent run, improving user feedback during the update process.
- Updated the dashboard to reflect the new review stages and provide a more interactive experience for managing configuration changes.

Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-25 17:12:42 -07:00
Devin AI
f6e121f816 fix: validate config_update_string with getInvalidConfigReason and add polling correlation check
Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-25 22:13:58 +00:00
Devin AI
16a5fb763e fix: update spike-orchestrator docs and exclude type-only exports from structural regex
Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-25 22:03:04 +00:00
Devin AI
0f743f93ff fix: address P0-P2 review feedback from Cubic review
P0: Strip OAuth token from git origin after clone so LLM agent
    never sees credentials (repo-agent.tsx)

P1: Replace raw error.message with safe hardcoded text in API
    response and dashboard UI (apply/route.tsx, config-update.tsx)
P1: E2E spike script now requires explicit env vars instead of
    falling back to pushing to main (spike-orchestrator-e2e.mts)

P2: Use urlSchema for commit_url (schema-fields.ts)
P2: Return commitSha directly instead of parsing from URL
    (repo-agent.tsx, apply/route.tsx)
P2: Support LINK_BRANCH_ID env var (link-project-to-github.ts)
P2: Widen structural fallback regex (config-updater.ts)
P2: Log warning when cancel has no sandboxId (cancel/route.tsx)
P2: Reject arbitrary string config values (config-eval.ts)
Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-25 21:54:46 +00:00
BilalG1
d2a84f5a28
fix: reduce recurring production Sentry errors (Stripe webhooks, email, session replay) (#1667)
## Summary

A cleanup pass over recurring production errors triaged from Sentry
(`stackframe-pw` org). The common thread: expected/edge-case conditions
thrown as `HexclaveAssertionError` / `captureError`, so Sentry filed
them as errors (and, for the Stripe ones, Stripe redelivered
indefinitely). Each is handled at the source or logged at the correct
severity.

| Sentry issue | Fix | Risk |
|---|---|---|
|
[STACK-BACKEND-1F5](https://stackframe-pw.sentry.io/issues/STACK-BACKEND-1F5)
— `Unknown stripe webhook type` (`invoice_payment.paid`, `payout.paid`)
| Add both to `ignoredEvents`. They fell through to the throwing `else`
and Stripe redelivered them. (`payout.failed`/`canceled`/`updated`
intentionally left unhandled for now.) | Trivial |
|
[STACK-SERVER-1ZV](https://stackframe-pw.sentry.io/issues/STACK-SERVER-1ZV)
— session-replay `413 Request body too large` | Measure event size in
UTF-8 bytes (was UTF-16 `.length`, which undercounts multibyte content);
drop a single oversized event with a warning instead of shipping a
doomed request | Low |
|
[STACK-BACKEND-140](https://stackframe-pw.sentry.io/issues/STACK-BACKEND-140)
+
[STACK-BACKEND-1F1](https://stackframe-pw.sentry.io/issues/STACK-BACKEND-1F1)
— `Unknown error while sending (test) email` | Classify refused SMTP
connections (`ECONNREFUSED`, surfaced by nodemailer as `code:
'ESOCKET'`) as a typed `CONNECTION_REFUSED` error with a real
user-facing message, instead of falling through to the `UNKNOWN`
catch-all in both the low-level sender and the send-test-email route.
Marked `canRetry` so the queued-email path reschedules with backoff. |
Low |

## Notes

- **Session replay (1ZV):** edited the `packages/template`
source-of-truth; the generated SDK copies are gitignored and regenerated
by CI (`pnpm -w run generate-sdks`). The `TextEncoder` is hoisted out of
the rrweb emit hot path to avoid per-event allocation.
- **Email classification (140/1F1):** the new `CONNECTION_REFUSED`
errorType is additive — other consumers only read `errorType` for
logging, and the send-test-email route only special-cases `UNKNOWN`, so
the new type cleanly bypasses both assertion captures. `canRetry: true`
is safe because the connection is refused before any SMTP exchange (no
message handed off → no duplicate-delivery risk); transient refusals
recover, and a persistent misconfig still fails after
`MAX_SEND_ATTEMPTS`. The one-shot send-test-email path ignores
`canRetry`, so its immediate feedback is unchanged.

## Investigated but intentionally NOT changed here

These were initially included, then reverted so we keep getting Sentry
signal while the root causes are still under investigation:

-
**[STACK-BACKEND-1GM](https://stackframe-pw.sentry.io/issues/STACK-BACKEND-1GM)**
— `Stripe webhook bad customer id`. A subscription-changed event with no
customer (the observed case was a Stripe-CLI test
`payment_intent.succeeded` against a dev-connected account). Skipping is
likely the right long-term fix, but kept the throw for now to keep
observing. Note: in live mode the same path could fire on legitimate
customerless one-time payments / guest checkouts.
-
**[STACK-BACKEND-1CN](https://stackframe-pw.sentry.io/issues/STACK-BACKEND-1CN)**
— `Recovered N stale outgoing request(s)`. This is a self-healing
recovery notice (0 user impact); the underlying cause is the poller
process dying between the claim `UPDATE` and the delete. Kept at
`captureError` to keep collecting data on how often / why it happens.

## Verification
- `typecheck` clean: `@hexclave/backend`, `@hexclave/template`,
`@hexclave/js`, `@hexclave/react`, `@hexclave/next`,
`@hexclave/tanstack-start`
- `eslint` clean on all touched files
2026-06-25 14:48:49 -07:00
Devin AI
1b6a98ebdd fix: resolve merge conflict with dev (queueMicrotask)
Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-25 21:41:23 +00:00
Devin AI
abf95240f9 Merge remote-tracking branch 'origin/dev' into devin/1782257319-migrate-config-to-jiti 2026-06-25 21:40:39 +00:00
Konstantin Wohlwend
3e53da8fce OAuth improvements 2026-06-25 14:40:15 -07:00
mantrakp04
0a23409a87 feat: enhance GitHub configuration management with new scripts and API routes
- Added a script for building a shared config-agent base snapshot, optimizing the warm-boot process for configuration updates.
- Introduced a new script to link existing projects to GitHub repositories without re-seeding, improving workflow efficiency.
- Updated the workflow paths and configuration file names to align with the new Hexclave structure.
- Refactored existing scripts to ensure consistency in configuration paths and enhance overall integration with GitHub.

Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-25 14:37:27 -07:00
github-actions[bot]
c749cf2b62 chore: update package versions 2026-06-25 19:11:40 +00:00
mantrakp04
2f477aba1e feat: enhance GitHub integration with new config seeding and agent routes
- Added a new script for seeding a local dashboard project linked to a GitHub repository, facilitating end-to-end testing of the config-agent flow.
- Introduced new API routes for preparing and applying configuration updates via the GitHub repo agent, improving the workflow for managing config changes.
- Updated the command hook in settings to provide clearer instructions on handling typecheck and lint failures.
- Refactored the config update logic to ensure seamless integration with the new agent routes.

Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-24 19:07:43 -07:00
mantrakp04
f2b5cbd0b3 feat: implement Config Update Repo Agent for GitHub integration
- Introduced a new Config Update Repo Agent to manage GitHub configuration updates within a Vercel Sandbox.
- The agent allows for efficient cloning, dependency installation, and configuration updates while preserving the original file structure.
- Updated model selection to include "anthropic/claude-haiku-4.5" for enhanced AI capabilities.
- Refactored config update logic to ensure all writes are routed through the agent, maintaining authoring integrity.

Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-24 16:23:39 -07:00
Armaan Jain
81723c3d55
Usage page performance improvements (#1650)
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/hexclave/hexclave/blob/dev/CONTRIBUTING.md

-->

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Speed up the Usage page by aggregating metered usage across owned
projects/tenancies with fewer queries and new indexes. Adds E2E tests to
verify team-owned rollups and calendar‑month windows.

- **Performance**
- Added concurrent indexes for `EmailOutbox(tenancyId,
startedSendingAt)` and `SessionReplay(tenancyId, startedAt)`; updated
Prisma schema.
- Group tenancies by (DB client, schema) and run one SQL per group that
counts both emails and session replays; uses `mapWithConcurrency` from
`@hexclave/shared` (concurrency 4, aborts on first error).
- Added helpers `getOwnedProjectAndTenancyIdsForBillingTeam` and
`getNonAnonymousUserCountForTenancies`; made `mapWithConcurrency`
null‑safe with bounds checks.

- **Tests**
- Added E2E tests for the internal plan-usage endpoint covering
team-owned rollups, calendar‑month boundaries, and zero‑usage cases.
- Added unit tests for ownership scope resolution and non‑anonymous user
counting.

<sup>Written for commit 5d6098006c.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1650?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Performance Improvements**
* Improved plan usage rollups by aggregating metered emails and session
replays together across an owned scope.
* Added database indexes to speed up time-window metering lookups for
email outbox and session replays.
* **Tests**
* Extended unit tests for billing-team entitlement aggregation and
non-anonymous user counting.
* Added end-to-end coverage for the internal plan-usage endpoint,
including seeded scenarios and period validation.
* **Refactor**
* Reworked entitlement and usage calculations to reuse shared logic for
more consistent results.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: armaan <armaan@stack-auth.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-06-24 12:25:20 -07:00
Aman Ganapathy
0c8f5e33ed
feat(payments): quick-ack + idempotent webhooks (#1664)
### Context
Stripe recommends acking webhook events ASAP with a 200. Stripe also
recommends employing event idempotency on your end. By responding
quickly, you prevent stripe from thinking the webhook failed and
retrying the event. Retrying the event in the past used to be
responsible for people getting multiple payment receipt emails. Note
that even in the case where an event processing genuinely fails, we have
a new table to let us recover from it.

Currently, recovery will be manual, but since it will be logged to
sentry we will be notified.


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Quick-ack Stripe webhooks with 200 and add atomic idempotency to stop
duplicate processing and emails. Events are persisted and processed in
the background with clear status and error tracking.

- **New Features**
- Persist each webhook in `StripeWebhookEvent` keyed by `event.id` with
full `payload` and `stripeAccountId` for recovery.
- Return 200 immediately; process in the background and track status as
`PENDING`, `PROCESSED`, or `FAILED`.
- Single-flight claim deduplicates redeliveries while `PENDING` and
after `PROCESSED`; only `FAILED` events reprocess on redelivery.
- Store `lastError` on failures; unknown webhook types ack with 200 and
are handled asynchronously.
- Webhook response includes `deduplicated: true` when a redelivery is
skipped.

- **Migration**
- Run Prisma migrations to create the `StripeWebhookEvent` table, enum,
and unique index on `stripeEventId`.

<sup>Written for commit 59456a36e8.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1664?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added persistent, idempotent Stripe webhook handling with event-level
deduplication keyed by the webhook event id.
* Webhooks are acknowledged immediately and processed asynchronously,
with automatic retry capability for failed events.
* **Bug Fixes**
* Reduced duplicate side effects from redeliveries (including preventing
repeated receipt emails) by ensuring only one successful processing per
event.
* **Tests**
* Updated and expanded integration and end-to-end coverage for
asynchronous processing, deduplication, and failure recovery behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-24 09:30:38 -07:00
github-actions[bot]
09c9df410a chore: update package versions
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
DB migration compat / Check if migrations changed (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests (Local Emulator) / E2E Tests (Local Emulator, Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Runs E2E Fallback Tests / E2E Fallback Tests (Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Lint & build / lint_and_build (24) (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
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
DB migration compat / No migration changes (skipped) (push) Has been cancelled
2026-06-24 01:55:58 +00:00
Devin AI
97b1a2f960 fix: narrow ParsedConfigValue to LocalEmulatorConfigValue with type guard
Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-24 00:06:17 +00:00
Devin AI
f71cde84b8 fix: split config-eval from config-rendering for browser safety
Move Node.js-only functions (evalConfigFileContent, tryEvalConfigFileContent,
detectImportPackageFromDir) to new config-eval.ts. This prevents the dashboard
browser build from failing on fs/path/jiti imports.

Dashboard now uses parseStaticConfigLiteral (regex+JSON.parse) instead of
jiti eval for untrusted GitHub-fetched config content, avoiding RCE risk.

Remove type casts in favor of isRecord type guard.

Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-23 23:58:42 +00:00
Devin AI
df52acb94f refactor: migrate config parsing from Babel AST to jiti
Replace parseHexclaveConfigFileContent and evaluateStaticConfigExpression
with jiti-based evalConfigFileContent. Move renderConfigFileContent from
hexclave-config-file.ts to config-rendering.ts alongside the new eval
function.

Removed functions:
- parseHexclaveConfigFileContent (Babel AST walker)
- tryParseHexclaveConfigFileContent
- evaluateStaticConfigExpression
- unwrapStaticConfigExpression

Added jiti dep to @hexclave/shared since config-rendering.ts now uses
jiti.evalModule for runtime evaluation of config file content strings.

Co-Authored-By: mantra <mantra@stack-auth.com>
2026-06-23 23:38:10 +00:00
Konsti Wohlwend
59f6e53f7e
chore: upgrade deprecated dependencies (#1654) 2026-06-23 15:44:37 -07:00
Konstantin Wohlwend
812716dae2 Better migration 2026-06-23 13:07:27 -07:00
github-actions[bot]
781dde9a78 chore: update package versions 2026-06-23 20:06:39 +00:00
Konsti Wohlwend
a559531080
feat: implement preview project pool for instant project creation (#1649) 2026-06-23 12:55:26 -07:00