# Datadog RUM Sourcemaps Via CI Design

**Goal:** Deobfuscate frontend RUM and Error Tracking stack traces in Datadog for the Xtablo frontends by generating sourcemaps during build, uploading them in CI, and keeping `.map` files off the public CDN.

## Current State

- `apps/main` initializes Datadog RUM in [apps/main/src/lib/rum.ts](/Users/arthur.belleville/Documents/perso/projects/xtablo-source/apps/main/src/lib/rum.ts) with `service: "xtablo-ui"` and `env: import.meta.env.MODE`, but no explicit release version.
- `apps/main`, `apps/clients`, and `apps/external` are Vite frontends with production Cloudflare deployments.
- None of the three Vite configs currently emit production sourcemaps.
- On this branch there is no tracked GitHub Actions workflow yet, so CI wiring must be introduced as part of the implementation.

## Decision

Use Datadog’s recommended CI upload flow:

1. Build each frontend with Vite `build.sourcemap: "hidden"`.
2. Upload generated sourcemaps from CI with `datadog-ci sourcemaps upload`.
3. Use a release version derived from the CI commit SHA.
4. Remove all `.map` files from `dist/` before deploy packaging so they are never publicly served.

This keeps sourcemaps private while still enabling unminified stack traces in Datadog.

Sources:
- Datadog CI sourcemap upload guide: https://docs.datadoghq.com/real_user_monitoring/guide/upload-javascript-source-maps/?tab=vite
- Vite `build.sourcemap` docs: https://vite.dev/config/build-options.html

## Runtime Contract

Datadog matches sourcemaps against browser events by `service` and `version`.

- `apps/main` must emit `version: import.meta.env.VITE_APP_VERSION` in its RUM initialization.
- CI must upload sourcemaps for `apps/main` using:
  - `service=xtablo-ui`
  - `release-version=$GITHUB_SHA`
- `apps/clients` and `apps/external` should use the same CI release version convention now, even though they do not currently emit RUM events. This keeps the deployment contract consistent and avoids another pipeline change when browser monitoring is enabled there.

## Public Asset Prefixes

The Datadog upload command must use the real production asset prefixes:

- `apps/main`: `https://app.xtablo.com/assets`
- `apps/clients`: `https://clients.xtablo.com/assets`
- `apps/external`: `https://embed.xtablo.com/assets`

These prefixes must match the actual URLs used by the deployed JS bundles.

## Implementation Shape

### Frontend code

- `apps/main/src/lib/rum.ts`
  - add `version: import.meta.env.VITE_APP_VERSION`
- `apps/main/src/vite-env.d.ts`
  - declare `VITE_APP_VERSION`
- `apps/clients/src/vite-env.d.ts`
  - create and declare `VITE_APP_VERSION`
- `apps/external/src/vite-env.d.ts`
  - declare `VITE_APP_VERSION`

### Build config

- `apps/main/vite.config.ts`
- `apps/clients/vite.config.ts`
- `apps/external/vite.config.ts`

Each should emit hidden sourcemaps for non-test builds.

### CI

- Add GitHub Actions workflow for frontend builds on self-hosted runners.
- Add `@datadog/datadog-ci` as a root dev dependency so the workflow can run a pinned CLI version from the repo.
- After each frontend build:
  - upload sourcemaps to Datadog
  - delete `dist/**/*.map`

## Secrets And CI Inputs

The workflow needs:

- `DATADOG_API_KEY`
- `DATADOG_SITE`
- release version from `github.sha`

The workflow should fail fast if Datadog secrets are missing on the deployment path where sourcemap upload is required.

## Verification

- Unit test for `apps/main` RUM init to assert `version` is wired from env.
- Vite config tests or config assertions for all three apps to verify production builds use `sourcemap: "hidden"`.
- CI workflow smoke verification:
  - build the apps
  - run sourcemap upload
  - confirm `.map` files are removed from `dist`

## Non-Goals

- Enabling Datadog RUM in `apps/clients` or `apps/external` right now.
- Serving sourcemaps publicly.
- Changing app deployment hosts or CDN paths.
