| name | alisay-call |
| description | Operate, debug, test, deploy, and safely modify the Alisay Call two-person WebRTC video/audio chat app. Use when working on `/Users/swader/repos/alisay`, WebRTC signaling, TURN/coturn credentials, relay-only call failures, browser camera/microphone issues, Nginx WebSocket proxying, or production service checks for this app. |
Alisay Call
Core Workflow
Start every task by reading:
/Users/swader/repos/alisay/docs/IMPLEMENTATION_AND_SPEC.md
- Relevant source files in
/Users/swader/repos/alisay/src/, public/, tests/, and deploy/
Keep the app minimal: two people, one secret hash URL, no accounts, no database, no chat history, no recordings, no persistent room logs.
Use Bun commands from the repo root:
bun install
bun run test
bun run typecheck
bun run dev
Task Selection
- For code changes or tests, read
references/local-debugging.md.
- For browser/WebRTC failures, read
references/webrtc-turn-triage.md.
- For production deployment or server work, read
references/production-deployment.md.
Safety Rules
- Treat room hash fragments, TURN secrets, cookies, certs, and env files as sensitive. Never print secret values.
- Keep server-side signaling schema strict; reject unknown message types instead of relaying arbitrary JSON.
- Keep
/turn-credentials ephemeral and server-generated; never hardcode TURN passwords in frontend code.
- In production, require
PUBLIC_ORIGIN, ALLOWED_ROOM_IDS, and ALLOW_OPEN_ROOMS=false; never publish live allowlist hashes because the signaling protocol admits that hash directly.
- Scope production changes to Alisay-owned paths only. Do not touch unrelated apps on a shared host.
- Do not deploy or mutate production unless the user explicitly asks. When deploying, verify both HTTP and WebSocket paths.
Expected Architecture
The Bun service serves static files, /healthz, /rooms, /ws, and a disabled-by-default /turn-credentials test endpoint.
The browser:
- Keeps the secret room token in
location.hash.
- On bare visits, waits for Generate room before creating a hash token; existing hash invite links enable Start directly.
- Registers only
sha256(hash) through same-origin POST /rooms.
- Opens
/ws without a query string and sends sha256(hash) in the first join message.
- Receives ICE servers only after WebSocket admission and refreshes near-expiry TURN credentials with
refresh-ice.
- Requests camera/microphone after signaling and Relay-only preflight succeeds.
- Uses Relay-only mode by default and Auto mode as an option.
- Exchanges offer/answer/ICE over the WebSocket.
- Treats same-tab hash changes as a room switch: stop startup/call, recompute room state from the visible hash, and disable Copy invite until that room is registered and admitted over WebSocket.
The signaling server:
- Allows at most two clients per room.
- Admits static allowlisted rooms or same-origin generated rooms registered through
/rooms, with active-room plus pending-reservation capacity checks and a per-IP generated-room cap that counts active generated rooms plus unjoined reservations.
- Rejects room IDs in WebSocket URLs so proxy logs do not persist join-bearing room identifiers.
- Relays only validated
offer, answer, ice, and hangup.
- Relays negotiation messages only after both peers are ready and negotiation has started.
- Rate-limits post-upgrade signaling messages and configures WebSocket transport/backpressure caps.
- Closes upgraded sockets that do not send
join promptly.
- Deletes empty rooms and expires inactive/generated rooms, with browser heartbeat keeping live sessions active.
- Generates coturn REST credentials from
TURN_SECRET only after room admission.
Verification Bar
For code changes, run at least:
bun run test
bun run typecheck
For call-path changes, also run:
bun run test:e2e
For manual browser confirmation, use two tabs:
- Open the same hash URL in both tabs.
- Start both sides.
- Confirm local previews appear.
- Confirm the signaling server emits peer-ready behavior.
- Confirm mode-specific behavior: Relay-only requires TURN, Auto can run with STUN/TURN config.
For production checks, verify:
<PUBLIC_ORIGIN>/healthz
- WebSocket upgrade on
/ws without a room query
- a real browser relay-only call receives
relayAvailable: true without exposing TURN_SECRET
- coturn is not an open relay
- the father’s actual network can reach the configured TURN routes
Handoff Discipline
Update /Users/swader/repos/alisay/docs/IMPLEMENTATION_AND_SPEC.md after meaningful behavior, config, deployment, or verification changes. Include what changed, what was verified, and which environment-only checks remain unverified.