Gabriel Kaszewski a6558e15b2 kill LibraryItem, unify to MediaItem; decouple schedule engine from providers
ADR-0001: MediaItem absorbs LibraryItem fields (provider_id, external_id,
collection_name, collection_type, synced_at, role/MediaRole).
LibraryItem + LibraryItemRow deleted. All ports/adapters/tests updated.

ADR-0002: schedule engine takes LibraryQuery instead of IProviderRegistry.
Algorithmic blocks query library via search(), manual blocks via get_by_id().
get_stream_url removed from engine; provider_registry moved to ScheduleDeps
for playback-time stream URL resolution in application layer.

BlockContent provider_id field removed (meaningless when querying library).
2026-07-12 07:02:08 +02:00
2026-07-12 03:41:51 +02:00

k-tv

Self-hosted linear TV channel orchestration. Turns a personal media library into broadcast-style channels.

Stack

  • Backend — Rust (Axum), SQLite/PostgreSQL, Jellyfin
  • Frontend — Next.js 16, React 19, TanStack Query, Tailwind v4, shadcn/ui

Docker

Registry: registry.gabrielkaszewski.dev

Build

NEXT_PUBLIC_API_URL is baked into the frontend bundle at build time — always pass it explicitly.

# Backend
docker build -t registry.gabrielkaszewski.dev/k-tv-backend:latest ./k-tv-backend

# Frontend — NEXT_PUBLIC_API_URL required
docker build \
  --build-arg NEXT_PUBLIC_API_URL=https://tv-api.gabrielkaszewski.dev/api/v1 \
  -t registry.gabrielkaszewski.dev/k-tv-frontend:latest \
  ./k-tv-frontend

Push

docker push registry.gabrielkaszewski.dev/k-tv-backend:latest
docker push registry.gabrielkaszewski.dev/k-tv-frontend:latest

Build + push (one-liner)

docker build -t registry.gabrielkaszewski.dev/k-tv-backend:latest ./k-tv-backend && \
docker push registry.gabrielkaszewski.dev/k-tv-backend:latest && \
docker build \
  --build-arg NEXT_PUBLIC_API_URL=https://tv-api.gabrielkaszewski.dev/api/v1 \
  -t registry.gabrielkaszewski.dev/k-tv-frontend:latest \
  ./k-tv-frontend && \
docker push registry.gabrielkaszewski.dev/k-tv-frontend:latest

Deploy (on server)

docker compose -f compose.yml -f compose.traefik.yml pull
docker compose -f compose.yml -f compose.traefik.yml up -d

Ports

Service Port
Backend 3000
Frontend 3001

Env vars

Var Where Note
NEXT_PUBLIC_API_URL frontend build arg Baked in at build time — must point to the public backend URL
API_URL frontend runtime env Server-side only (Next.js API routes). Set in compose.
DATABASE_URL backend sqlite:///app/data/k-tv.db or postgres DSN
JWT_SECRET backend JWT signing key — change in production (min 32 chars)
COOKIE_SECRET backend OIDC state cookie encryption key — change in production (min 64 chars)
Description
Self hosted TV broadcast that uses existing media libary
Readme 3 MiB
Languages
Rust 65%
TypeScript 34.5%
CSS 0.3%
Dockerfile 0.1%