# SafeTwitch Deployment Notes (darkness.services)

This document describes the practical changes made in this repo to stabilize and run SafeTwitch reliably on `safetwitch.darkness.services` and `api.safetwitch.darkness.services`.

## Goals

- Keep the stack self-hostable with Docker Compose.
- Improve live playback reliability (especially around ads and quality switches).
- Restore useful search behavior even when backend search responses are empty.
- Keep clearnet and onion routes available.

## Infrastructure and Build Changes

### 1. Frontend image is built locally

Files:
- `docker/Dockerfile`
- `docker/docker-compose.yml`

Changes:
- Node build stage moved to `node:22`.
- Frontend build command changed to `npm run build-only` for consistent container builds.
- Frontend services in compose now use local image build (`safetwitch-local:latest`).

Why:
- Ensures source-level fixes are actually deployed, instead of being masked by a prebuilt image.

### 2. Frontend reverse proxy behavior fixed

File:
- `docker/nginx.conf`

Changes:
- Added explicit forwarding for:
  - `/api/` -> backend API
  - `/proxy/` -> backend proxy

Why:
- Some playlists and media URLs are emitted as frontend-host paths (`/proxy/...`).
- Without these proxy routes, users see missing images/icons and stalled stream playback.

### 3. Compose routing and service layout

File:
- `docker/docker-compose.yml`

Changes:
- Clearnet and tor frontend/backend services retained.
- Traefik labels and host routing aligned for:
  - `safetwitch.darkness.services`
  - `api.safetwitch.darkness.services`
  - onion equivalents

## Playback and UX Reliability Changes

### 4. Player recovery logic for stuck live streams

File:
- `src/components/VideoPlayer.vue`

Changes:
- Added auto-recovery handlers for media stall scenarios:
  - `waiting`, `stalled`, `error`, and live `ended` transitions.
- Added watchdog loop for live streams:
  - if time does not advance for several seconds, attempt recovery.
- Recovery strategy:
  - soft resume with `play()`
  - hard resume by reloading source, then seeking appropriately and resuming.

Why:
- Prevents cases where ad transitions or stream discontinuities leave the player hanging until manual restart.

### 5. Quality selector stability and defaults

Files:
- `src/assets/qualitySelector.ts`
- `src/settingsManager.ts`
- `src/locales/en.json`

Changes:
- Added explicit `Auto` quality option.
- Default quality changed to `Auto` for new settings.
- Quality selection now behaves as an adaptive cap (selected quality and below), not a brittle single-rendition lock.
- Added safer startup fallback when chosen quality is unavailable.
- Ensure playback resumes after quality changes.

Why:
- Reduces buffering and prevents quality-switch dead-ends.

### 6. Live status fallback for stale backend `api/users`

Files:
- `src/views/UserView.vue`
- `src/components/StreamPreview.vue`

Changes:
- If `api/users` reports offline or missing stream, fallback to `api/users/isLive/bulk`.
- For confirmed live users without stream metadata, synthesize minimal stream data to avoid UI breakage.

Why:
- Handles backend variants where user detail endpoints can be stale while bulk live status is still accurate.

## Search Fixes

### 7. Frontend search page hardening

File:
- `src/views/SearchPageView.vue`

Changes:
- Search now re-runs when query changes (route watcher).
- Added fallback behavior when backend search returns empty:
  - user lookup
  - category matching from discover data

Why:
- Avoids blank pages from route update edge cases or empty backend responses.

### 8. Backend-level search fallback service

Files:
- `docker/search-fallback/server.mjs`
- `docker/docker-compose.yml`

Changes:
- Added `safetwitch-search-fallback` service.
- Traefik routes `/api/search` requests to this service (clearnet + tor API hosts).
- Fallback service behavior:
  - use backend search first
  - if empty, perform targeted fallback lookups
  - includes numeral normalization (`4` <-> `IV`) for queries like `diablo 4` and `Diablo IV`.

Why:
- Provides a backend-level mitigation without replacing the rest of the API stack.

## Operational Notes

- If the UI appears stale after deployment, do a hard refresh (`Ctrl+Shift+R`).
- For HLS diagnostics, use real `GET` checks. `HEAD` may be misleading for some playlist endpoints.
- Existing users may keep old local settings until changed in Settings.

## Validation Checklist

- `https://safetwitch.darkness.services` loads.
- `https://safetwitch.darkness.services/api/discover` returns JSON.
- Live playback resumes after quality change.
- Live playback recovers after ad transition/stall.
- `https://api.safetwitch.darkness.services/api/search/?query=diablo+4` returns category data.
- Onion routes remain available for frontend/backend tor services.
