import * as Sentry from '@sentry/vue' import type { App } from 'vue' import type { Router } from 'vue-router' import { scrubEvent } from './scrubber' export interface SentryInitOptions { app: App router: Router dsn: string release: string environment: string } /** * Initialises @sentry/vue for the SPA per RFC-WS-7 §3.2-§3.9. * * - Empty DSN → no-op (RFC §3.3, mirrors backend). * - Errors-only — tracesSampleRate / profilesSampleRate hard-pinned to 0 * (RFC §2 amendment B). * - sendDefaultPii=false (RFC §3.7 / §3.8); user identity is bound * explicitly by {@link installContextBinding} as a ULID-only object. * - app=app initial scope tag (RFC §3.6) so GlitchTip can filter * frontend vs backend events. * - PII scrubbing via {@link scrubEvent} as the beforeSend hook (RFC §3.7 * frontend block). */ export function initSentry(options: SentryInitOptions): void { if (options.dsn === '') return Sentry.init({ app: options.app, dsn: options.dsn, release: options.release === '' ? undefined : options.release, environment: options.environment, // RFC §2 amendment B — errors-only. tracesSampleRate: 0, profilesSampleRate: 0, // RFC §3.7 / §3.8: never let Sentry's auto-context capture IP, locals // from stack frames, or the User session-cookie payload. sendDefaultPii: false, // RFC §3.7 frontend point 5: console-logging integration off in prod // (info / debug breadcrumbs may include user data through formatted // arguments). Keep the BrowserApiErrors/Vue/global integrations. integrations: defaults => defaults.filter(i => i.name !== 'Console'), // RFC §3.7 frontend block — scrubber applied on every event. beforeSend: scrubEvent, // RFC §3.6 — route-scope baseline tag. AuthScopeContextListener-style // binding of actor_scope / user_id / actor_type happens per route // navigation in {@link installContextBinding}. initialScope: { tags: { app: 'app', }, }, }) }