# Connecting a New App to the Tester Analytics Platform

One dashboard serves **every app**. Create each app in the Developer portal first so
you can copy its `appId` and API key. Testers and events then register automatically
on the first telemetry event.

The SDK reports **directly to this dashboard** over HTTPS. No Firebase, no Google
Analytics / PostHog / Mixpanel / Amplitude — no third-party analytics of any kind
except your own server.

---

## Setup — Expo Go / dev-client (about 10 minutes)

You get:

- Persistent anonymous tester ID (UUID v4)
- Offline event queue (survives no network)
- Automatic tester/event registration after you create the app
- Screen, foreground/background, and crash tracking
- **Active-usage tracking** — the server measures how many minutes each tester
  was actually using the app, per day
- No native builds, no Expo Go restrictions

### 1. Install the SDK

```bash
cd your-new-app
npm install tester-analytics-sdk
npx expo install expo-secure-store expo-constants
```

The SDK is public on npm, so a normal install needs no local SDK folder or Metro
monorepo configuration. `expo-secure-store` keeps the anonymous Tester ID and
offline event queue; `expo-constants` reads the app configuration.

### 2. Set the config in `app.json`

Add to `expo.extra`:

```jsonc
{
  "extra": {
    "testerAnalytics": {
      "appId": "my-cool-app",                // exact appId from the Developer portal
      "apiKey": "hk_your_app_key_here",      // app-specific key from the Developer portal
      "apiUrl": "https://saraayab.shop"      // hosted dashboard (use HTTPS)
    }
  }
}
```

The SDK reads these values automatically — you can omit `appId`/`apiUrl`/`apiKey`
from the init call below. Create the app in the Developer portal first and copy
its app-specific key. The key is required in production, and `apiUrl` must use
your hosted dashboard's HTTPS URL. Keep the configured `appId` consistent with
the app that issued the key; the server scopes requests to the app bound to that key.

### 3. Initialize the SDK (one call)

Create `src/tester.ts`:

```ts
import { initializeExpoTesterAnalytics } from 'tester-analytics-sdk/expo';

// appId + apiUrl + apiKey are pulled from app.json automatically.
export const tester = initializeExpoTesterAnalytics();
```

### 4. Wire it into your app

**Entry point** (early import):

```ts
// App.tsx or index.ts (classic Expo)
import './src/tester';   // boots ID + session automatically
```

For Expo Router, import it at the top of `app/_layout.tsx` instead:

```ts
import '../src/tester';
```

**Screen tracking** (inside your navigator):

```ts
import { tester } from '../src/tester';

// NavigationContainer props:
onReady={() => tester.setScreen(route.name)}
onStateChange={() => {
  const route = navigationRef.current?.getCurrentRoute();
  if (route?.name) tester.setScreen(route.name);
}}
```

**Crash reporting** (optional):

```ts
import { tester } from '../src/tester';

// in an error boundary / global handler:
tester.reportCrash(error.message, error.stack);
```

**Show tester ID in Settings** (optional, helps testers share their ID with you):

```ts
import { tester } from '../src/tester';

const id = await tester.getTesterId();
// display `id`, offer setContactName / eraseMyData
```

### 5. Run it

```bash
npx expo start          # Expo Go works immediately on Android
npx expo start --dev-client   # or use a dev-client
```

Open the dashboard → the new app appears in the **app selector** on first
telemetry event.

## What gets tracked

To view it, open the dashboard **Usage** tab (or `GET /api/usage?appId=`).

| Signal | Sent when | Used for |
| --- | --- | --- |
| `app_opened` | App opens (increments `opens`) | Stats |
| `session_start` | First open / after a fresh install since the last close | Active-usage |
| `session_resume` | App returns to foreground after background/close | Active-usage |
| `session_heartbeat` | ~every 60s while foreground | Active-usage |
| `session_pause` | App goes to background or is closing | Active-usage |
| `screen_view` | Screen changes | Activity history |
| `crash` | JS error / error boundary | Crash row |

The server (not the device) measures elapsed active time and splits it into
per-day buckets (UTC). Background time is excluded. A force-close, crash, or
network drop is recovered automatically — the server closes any session with no
signal for `USAGE_SESSION_TIMEOUT_SECONDS` (default 10 min).

## Opt-out

The tester can opt out at any time (`tester.setOptedOut(true)` — the app shows
this in **Settings → Testing & Privacy**). Opting out stops the SDK from sending
future events; it does not delete data already received by the dashboard.
`tester.eraseMyData()` deletes the tester's dashboard data (including usage) via
`POST /api/tester/erase`.

---

## Privacy-policy disclosure for a testing app

Add a clear disclosure to your app's privacy policy and provide that policy to
testers and in your store listing. Adapt the sample below to your actual app,
hosting provider, data handling, and retention period:

> **Temporary testing data:** While this app is in its [closed/open testing
> period], [developer or organization] uses TesterFlow to evaluate test builds,
> diagnose crashes and bug reports, and understand test-session activity. The
> app sends a random tester ID, app version, device information, screen and
> activity events, and foreground session signals to [hosting provider/region].
> Crash details and bug-report information are sent when generated or submitted.
> Testers may optionally provide contact details. This data is used only to
> operate this testing program, not for advertising or production-user
> analytics. Collection will stop when [specific test end condition/date], and
> data will be retained for [actual retention period]. To stop future collection,
> use [in-app opt-out instructions]; to request deletion, use [erase instructions
> or contact details].

Only describe collection as temporary or say it is not used in production if
that is true for your app and you will stop or change collection when the test
ends. Specify a retention period you can actually meet; TesterFlow does not
automatically delete data just because a test ends. Keep the privacy policy,
store listing/Data safety disclosures, and app behavior consistent. This sample
does not guarantee approval by Google Play; review and follow the current
Google Play policies for your app and testing track.

---

## API key and app security

Create the app in the Developer portal and use its app-specific API key. The SDK
sends this value as the `x-api-key` header. In production the header is required;
the server scopes requests to the app bound to the key.
`APP_API_KEY` is an optional legacy shared-key fallback, not needed for new apps.

An API key included in a mobile app can be extracted from its installed package.
Treat it as public, use only the key for that app, and never include the dashboard
admin password or another sensitive credential in the app.

---

## Notes

- **Reinstall → new ID** — the tester ID lives in secure storage.
  Reinstalling or clearing app data generates a fresh ID.
- **Native app adapter** — use Expo Go with an Android device or emulator.
- **GDPR** — `tester.eraseMyData()` deletes dashboard + local data via
  `POST /api/tester/erase`.
