stack/apps/backend/src
mantrakp04 f4c2ee4575 feat(analytics): cross-tier span propagation (client fetch header + server withSpan({ request }))
Auto-links a customer's BACKEND span to the caller's CLIENT session with zero glue.
The browser attaches one `x-hexclave-span-context` header to same-origin outgoing
fetches; `serverApp.withSpan(type, { request }, fn)` resolves the caller's refresh
token (from the session) plus that header, so the span — and everything created
inside the callback — parents under $refresh-token → $session-replay →
$session-replay-segment, exactly like a browser event.

- span-propagation.ts: versioned base64url header codec, same-origin fetch
  auto-wrapper (idempotent, native header semantics preserved), origin predicate
- server-request-context.ts: AsyncLocalStorage ambient request context
- server-app-impl: withSpan/trackEvent({ request }) resolution; server telemetry
  buffer re-keyed from userId to the full (user, refresh, replay, segment) context;
  propagated custom parents flow as ambient frames
- backend events/batch: accept forwarded refresh_token_id/session_replay_id on
  SERVER auth (rejected on client auth); compose [rti-,sri-,srsi-,cs-] + stamp
  the scalar columns
- client-app-impl: install the fetch wrapper on init behind analytics.spanPropagation
  (same-origin default + exact-origin allowlist); reads the live per-tab id
- tests: 24 propagation unit tests + 2 e2e (server-auth ancestry + client-auth reject)

The framework adapters (tRPC, Convex, oRPC, ElysiaJS) build on this primitive in a
separate stacked branch; with an adapter you never pass { request } yourself.
2026-07-03 11:45:16 -07:00
..
app feat(analytics): cross-tier span propagation (client fetch header + server withSpan({ request })) 2026-07-03 11:45:16 -07:00
auto-migrations Rename STACK_* env vars to HEXCLAVE_* in env templates, with legacy dual-read (#1588) 2026-06-19 18:58:53 -07:00
lib feat(analytics): public trackEvent/startSpan SDK + custom events/spans ingestion 2026-07-02 11:34:34 -07:00
oauth refactor: migrate config parsing from Babel AST to jiti (#1661) 2026-06-29 10:25:11 -07:00
private Bump submodules (#1577) 2026-06-10 13:53:13 -07:00
route-handlers fix: return 409 instead of 500 when signing up with duplicate email (#1637) 2026-06-22 17:29:08 -07:00
scripts feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring (#1482) 2026-05-29 15:21:59 -07:00
utils feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring (#1482) 2026-05-29 15:21:59 -07:00
analytics.tsx feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring (#1482) 2026-05-29 15:21:59 -07:00
globals.d.ts Split backend and dashboard (#83) 2024-06-18 15:49:31 +02:00
hexclave.tsx feat(hexclave): PR 5 — internal symbol/path/package renames + brand strings (#1547) 2026-06-03 18:57:09 -07:00
instrumentation.ts feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring (#1482) 2026-05-29 15:21:59 -07:00
polyfills.tsx Rename STACK_* env vars to HEXCLAVE_* in env templates, with legacy dual-read (#1588) 2026-06-19 18:58:53 -07:00
prisma-client.tsx Improved PKCE support 2026-06-11 10:28:14 -07:00
proxy.tsx feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring (#1482) 2026-05-29 15:21:59 -07:00
s3.tsx feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring (#1482) 2026-05-29 15:21:59 -07:00
smart-router.tsx feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring (#1482) 2026-05-29 15:21:59 -07:00