# @mintel/observability

Standardized observability package for the Mintel ecosystem, providing Umami analytics and Sentry/GlitchTip error tracking with a focus on privacy and ad-blocker resilience.

## Features

- **Umami Smart Proxy**: Track analytics without external scripts and hide your Website ID.
- **Sentry Relay**: Bypass ad-blockers for error tracking by relaying envelopes through your own server.
- **Unified API**: consistent interface for tracking across multiple projects.

## Installation

```bash
pnpm add @mintel/observability @sentry/nextjs
```

## Usage

### 1. Unified Environment (via @mintel/next-utils)

Define the following environment variables:

```bash
# Analytics
UMAMI_WEBSITE_ID=your-website-id
UMAMI_API_ENDPOINT=https://analytics.infra.mintel.me

# Error Tracking
SENTRY_DSN=your-sentry-dsn
```

Note: No `NEXT_PUBLIC_` prefix is required for these anymore, as they are handled by server-side proxies.

### 2. Analytics Setup

In your root layout:

```tsx
import {
  AnalyticsContextProvider,
  AnalyticsAutoTracker,
  UmamiAnalyticsService,
} from "@mintel/observability";

const analytics = new UmamiAnalyticsService({
  enabled: true,
  websiteId: process.env.UMAMI_WEBSITE_ID, // Server-side
  apiEndpoint:
    typeof window === "undefined" ? process.env.UMAMI_API_ENDPOINT : "/stats",
});

export default function Layout({ children }) {
  return (
    <AnalyticsContextProvider service={analytics}>
      <AnalyticsAutoTracker />
      {children}
    </AnalyticsContextProvider>
  );
}
```

### 3. Route Handlers

Create a proxy for Umami:
`app/stats/api/send/route.ts`

```ts
import { createUmamiProxyHandler } from "@mintel/observability";
export const POST = await createUmamiProxyHandler({
  websiteId: process.env.UMAMI_WEBSITE_ID,
  apiEndpoint: process.env.UMAMI_API_ENDPOINT,
});
```

Create a relay for Sentry:
`app/errors/api/relay/route.ts`

```ts
import { createSentryRelayHandler } from "@mintel/observability";
export const POST = await createSentryRelayHandler({
  dsn: process.env.SENTRY_DSN,
});
```

### 4. Notification Setup (Server-side)

```ts
import { GotifyNotificationService } from "@mintel/observability";

const notifications = new GotifyNotificationService({
  enabled: true,
  url: process.env.GOTIFY_URL,
  token: process.env.GOTIFY_TOKEN,
});

await notifications.notify({
  title: "Lead Capture",
  message: "New contact form submission",
  priority: 5,
});
```

### 5. Sentry Configuration

Use `initSentry` in your `sentry.server.config.ts` and `sentry.client.config.ts`.

On the client, use the tunnel:

```ts
initSentry({
  dsn: "https://public@errors.infra.mintel.me/1", // Placeholder
  tunnel: "/errors/api/relay",
});
```

## Architecture

This package implements the **Smart Proxy** pattern:

- The client NEVER knows the real `UMAMI_WEBSITE_ID`.
- Tracking events are sent to your own domain (`/stats/api/send`).
- Your server injects the secret ID and forwards to Umami.
- This bypasses ad-blockers and keeps your configuration secure.
