Commit Graph

8 Commits

Author SHA1 Message Date
Konstantin Wohlwend
b11257fd5b Re-add Elysia backend transport
Keep the transport migration isolated on a dedicated branch so development can continue without blocking dev.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-13 12:41:55 -07:00
Konstantin Wohlwend
a66a8d972d Revert "Migrate backend transport from Next.js to ElysiaJS (WIP) (#1630)"
This reverts commit 5209ec83ae.
2026-07-13 12:38:53 -07:00
Mantra
5209ec83ae
Migrate backend transport from Next.js to ElysiaJS (WIP) (#1630)
> **Draft / WIP — do not merge.** Backend Next.js → ElysiaJS transport
migration, in progress.

## Summary

Migrates the backend (`apps/backend`) HTTP transport from **Next.js (App
Router)** to **ElysiaJS** (Node adapter, `@elysiajs/node`), with the
explicit goal of keeping every API route **byte-for-byte backwards
compatible** — same URLs, methods, status codes, headers, and bodies.
Elysia becomes purely the transport layer; the existing
`createSmartRouteHandler` abstraction and all ~221 file-based route
handlers are reused unchanged.

## Approach

- **One wildcard dispatcher** reuses the existing `smart-router`
matchers + generated `routes.json`/`api-versions.json` rather than
re-registering 221 routes on Elysia's router.
- **`proxy.tsx` (Next 16 middleware) ported** to an Elysia request
pipeline: CORS, dev rate-limit, `x-hexclave-*`→`x-stack-*` header
aliasing, OPTIONS preflight, and the **API version rewrite** (`/api/v1`,
`/api/v2betaN` → `/api/latest` / `/api/migrations/*`).
- **Two-URL dispatch**: the version-rewritten path locates the handler;
the original client URL is preserved on `req.url`/`nextUrl`
(load-bearing for OIDC/neon routes that assert `/api/v1/...`).
- **`next/*` compatibility shims** (`next/headers`, `next/navigation`,
`next/server`) under `src/lib/next-compat/`, wired via aliases in
tsconfig / vitest / tsdown so route files stay untouched.
- **Observability** moved off `@sentry/nextjs` → `@sentry/node` + manual
OpenTelemetry NodeSDK preload (`src/instrument.ts`); explicit
`/monitoring` Sentry tunnel.
- **Build/deploy**: `next build/start` → tsdown bundle
(`tsdown.config.ts`) for container; Vercel default-export entry;
Dockerfile CMD → `dist/server.mjs`; `next.config.mjs` removed (security
headers etc. reimplemented).

## Status — WIP

**Green so far:** backend `typecheck`, backend `lint`, tsdown bundle,
`GET /health`, `GET /api/v1`, e2e `migration-tests` (13/13),
`analytics-query` (69/69), unit suite (~1006 tests).

**Remaining before ready for review:**
- [ ] Full backend e2e snapshot suite green (snapshots = byte-for-byte
oracle; never `-u`'d to mask drift)
- [ ] `config.test.ts` (`custom_oidc`) snapshot root-cause
- [ ] M4: source-map upload + remove remaining `@sentry/nextjs` browser
leftovers
- [ ] M5: Docker + Vercel artifact verification
- [ ] M6: confirm React-UI → slim-handler cleanup

## Notes
- Backwards-compat gate: the existing e2e snapshot files (recorded
against the Next.js backend) must pass unchanged.
- Built primarily by Codex (`gpt-5.5`); branch intentionally separate
from `dev`.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Migrates the backend transport from Next.js to ElysiaJS with
byte‑for‑byte compatible APIs, bundled with `tsdown` for Node, Vercel,
and Docker. Reverts out‑of‑scope payments/metrics/custom OIDC changes to
keep this PR focused.

- **Refactors**
- Transport: Next.js → ElysiaJS (`elysia`, `@elysiajs/node`) via
wildcard dispatcher + generated route registry; preserve original URL;
decode params; 400 on malformed params.
- Next shims: `next/headers`, `next/navigation`, `next/server` with
request context and cookie serialization; don’t percent‑decode;
`cookies().delete()` clears pending Set‑Cookie; add `fetch` `next`
options typing.
- Observability: move to `@sentry/node`/`@sentry/browser`; preload
`@opentelemetry/sdk-node`; guard duplicate OTel registration; add
`/monitoring` tunnel; sanitize Sentry release names; replace Next.js
instrumentation with `src/instrument.ts`.
- Build/deploy: bundle `dist/server.mjs` and `dist/vercel.mjs` with
`tsdown`; Vercel function at `api/index.ts` re‑exports the handler
(`runtime: nodejs`, `maxDuration: 60`, `framework: null` rewrite);
Docker runs the Node bundle.
- Runtime: reimplement security headers; dev rate limiter uses high‑res
timers; graceful SIGTERM.
- Env/dev: expand nested env refs; load `.env.development` in dev;
TS/Vitest alias `next/*` to shims.
- Deps/tooling: re‑add `@sinclair/typebox`; regenerate `pnpm-lock.yaml`
with pnpm 11.5.0 and pin `exact-mirror@1.1.1`.

- **Bug Fixes**
  - Dispatcher: catch `NextNotFoundError` and return 404.
- Emails: deterministic localhost/loopback SMTP fallback (prefer IPv6)
and consistent HTML for snapshot parity.
- E2E parity: restore email‑conflict error; poll all‑users outbox before
asserting; extend refund/transactions timeouts; fix team invitation
revoke setup.
- Build/Docker: prevent `dist` wipes by setting `clean:false` in
db‑migrations `tsdown` config; reorder COPY so `dist/server.mjs` is
present; backend entrypoint uses `dist/server.mjs`.
- CI/tests: Vitest `minWorkers: 1`; fallback e2e starts the Elysia
bundle via `pnpm run start` with `PORT`.
- Shared: normalize `esbuild-wasm` default export under Node to avoid
runtime mismatches.

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

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1630?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

## Release Notes

* **Bug Fixes**
* Improved email delivery by adding localhost/loopback-aware SMTP retry
behavior and more consistent delivered email HTML.
  * Enhanced error reporting during external database synchronization.
* Refined OAuth provider type validation to better handle missing or
custom provider configurations.

* **Improvements**
* Updated backend runtime and routing/request handling for more
consistent behavior, including updated Vercel/Docker startup.
* Improved payment “dual write” reliability by scheduling Bulldozer
projection updates with per-tenant ordering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: mantra <mantra@stack-auth.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Bilal Godil <bg2002@gmail.com>
2026-07-09 21:39:28 -07:00
aadesh18
2055d98dea
External db sync (#1036)
<img width="1920" height="969" alt="Screenshot 2026-02-04 at 9 47 16 AM"
src="https://github.com/user-attachments/assets/d7d0cd04-0051-4fc4-b857-e6f87ee97a59"
/>

**This PR revolves around the following components**
1. Sequencer - sequences the updates in the internal db
2. Poller - polls for the latest updates to sync with the external db
3. Outgoing Request Handler - essentially a trigger that can make http
requests based on a change in the internal db
4. Sync Engine - syncs with the latest changes from the internal db to
the external db

**What has been done**
- Added a global sequence id for ProjectUser, ContactChannel and
DeletedRow.
- Added the deletedRow table to keep track of the rows that were deleted
across ProjectUser and ContactChannel.
- Added the OutgoingRequest table to keep track of the outgoing requests
- Added function for the sequencer to call to sequence updates
- Added a sequencer that sequences all the changes in the internal db
every 50 ms
- Added a poller that polls for the latest changes in the internal db
every 50 ms, and adds to a queue
- Added a Vercel cron that calls sequencer and poller every minute
- Added a queue that fulfills the outgoing requests by making http calls
(for external db sync, it calls the sync engine endpoint)
- Added a sync engine that uses the defined sql mapping query in the
user's schema to pull in the changes for the user, and sync them with
the external db
- Added tests to test out each functionality


**How to review this PR:**
1. Review the migrations (sequence id, deletedRow, triggers, backlog
sync) (all files created under the migrations folder)
2. Review sequencer
3. Review poller
4. Review the changes in schema
5. Review sync-engine (the function, and it's helper file)
6. Review the schema changes, and query mappings
7. Review the tests (basic, advanced and race, along with the helper
file)
8. Review the changes made in Dockerfile to support local testing using
the postgres docker

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduces a cron-driven external DB sync pipeline with global
sequencing, internal poller and webhook sync engine, new DB
tables/functions, config schema/mappings, and comprehensive e2e tests.
> 
> - **Database (Prisma/Migrations)**:
> - Add global sequence (`global_seq_id`) and
`sequenceId`/`shouldUpdateSequenceId` to `ProjectUser`,
`ContactChannel`, `DeletedRow` with partial indexes.
> - Create `DeletedRow` (capture deletes) and `OutgoingRequest` (queue)
tables; add unique/indexes.
> - Add triggers/functions: `log_deleted_row`,
`reset_sequence_id_on_update`, `backfill_null_sequence_ids`,
`enqueue_tenant_sync`.
> - **Backend/API**:
> - New internal routes: `GET
/api/latest/internal/external-db-sync/sequencer`, `GET /poller`, `POST
/sync-engine` (Upstash-verified) for sync orchestration.
> - Add cron wiring: `vercel.json` schedules and local
`scripts/run-cron-jobs.ts`; start in dev via `dev` script.
> - Tweak route handler (remove noisy logging) without behavior change.
> - **Sync Engine**:
> - Implement `src/lib/external-db-sync.ts` to read tenant mappings and
upsert to external Postgres (schema bootstrap, param checks,
sequencing).
> - Add default mappings `DEFAULT_DB_SYNC_MAPPINGS` and config schema
`dbSync.externalDatabases` in shared config.
> - **Testing/Infra**:
> - Add extensive e2e tests (basics, advanced, race conditions) for
sequencing, idempotency, deletes, pagination, multi-mapping, and
permissions.
> - Docker compose: add `external-db-test` Postgres for tests; e2e deps
for `pg` types.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3f2a8efcfb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

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

* **New Features**
* External PostgreSQL sync: automatic, batched replication with
mappings, resume/idempotency, and on-demand enqueueing.

* **Admin UI**
* Real-time External DB Sync dashboard and status API showing
per-mapping backlog, sequencer/poller/sync-engine telemetry, and fusebox
controls.

* **Tests**
* Large e2e suite: basic, advanced, race, high-volume tests and test
utilities for external DB sync.

* **Chores**
* DB migrations, CI/workflow updates, background cron runner and
local/dev test support.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
Co-authored-by: Bilal Godil <bg2002@gmail.com>
2026-02-05 12:04:31 -08:00
Konstantin Wohlwend
4757458685 Update vercel.json 2025-12-16 12:02:11 -08:00
Konstantin Wohlwend
29f748b0a0 Move vercel.json to backend 2025-12-16 11:52:21 -08:00
Konstantin Wohlwend
1868cb44a1 Disable failed email digest temporarily 2025-06-19 15:20:08 -07:00
BilalG1
71c35fd672
added cron job to for daily failed email digest (#714)
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
Docker Emulator Test / docker (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Test / docker (push) Has been cancelled
Runs E2E API Tests / build (22.x) (push) Has been cancelled
Lint & build / lint_and_build (latest) (push) Has been cancelled
Preview Docs / run (push) Has been cancelled
Dev Environment Test / restart-dev-and-test (push) Has been cancelled
Run setup tests / setup-tests (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
2025-06-17 15:38:09 -07:00