# @aphrodite/broadcaster

Broadcaster service for Aphrodite platform - handles stream creation,
management, and broadcaster operations

TypeScript package. Built with tsc/tsup; consumed by other workspaces.

## Remote guest boundary

When `DATABASE_URL` and `REMOTE_GUEST_SIGNALING_BASE_URL` are configured, the
service exposes no-store host registration, invitation exchange, operation,
evidence, and release routes under `/api/v1/streams/:streamId/remote-guests`.
Host authority comes from the existing authenticated stream-owner boundary. The
guest receives a scoped `Guest` credential after a one-use invitation exchange;
it is not treated as a general broadcaster identity.

The HTTP server also owns the exact
`/live-media/:tenantId/:streamId/remote-guests/:operationId` WebSocket upgrade.
It rejects query strings, unknown origins, missing/malformed protocols, reused
tickets, path/operation mismatches, binary or schema-invalid messages, and a
third participant. The one-use signaling capability travels in
`Sec-WebSocket-Protocol`, while the selected protocol returned to the browser is
the public protocol name. SDP and ICE remain in the bounded in-process
two-participant hub and are never written to PostgreSQL.

Production signaling is intentionally a single-node one-host/one-guest browser
path. TURN, SFU/MCU, multi-party, screen-share, native clients, and distributed
signaling availability are not claimed.

## Scripts

| Command              | Definition             |
| -------------------- | ---------------------- |
| `pnpm build`         | tsup                   |
| `pnpm dev`           | tsx watch src/index.ts |
| `pnpm start`         | node dist/index.js     |
| `pnpm test`          | vitest run             |
| `pnpm test:watch`    | vitest                 |
| `pnpm test:coverage` | vitest run --coverage  |
| `pnpm typecheck`     | tsc --noEmit           |
| `pnpm lint`          | eslint src/            |
| `pnpm lint:fix`      | eslint src/ --fix      |
| `pnpm format`        | prettier --write src/  |
| `pnpm format:check`  | prettier --check src/  |
| `pnpm clean`         | rimraf dist coverage   |

## Layout

- `src/`

## Working on this package

The fastest local loop is via Nx:

```bash
pnpm nx test aphrodite-broadcaster
pnpm nx lint aphrodite-broadcaster
pnpm nx build aphrodite-broadcaster
```

When Nx is unhappy (usually because another worktree has duplicate project
names), bypass it with the underlying tools from this directory:

```bash
npx tsc --noEmit
npx vitest run
```

See the [root README](../../../README.md) for monorepo-wide conventions (catalog
deps, commit format, git workflow). See the
[Contributor Guide](../../../docs/CONTRIBUTING.md) for the full PR workflow.
