Files
xTeVe/tasks/todo.md
T
nathan 504ea3f9f4
continuous-integration/drone/push Build encountered an error
Phase 3: Go hygiene pass, runtime PUID/PGID, fork README
Go:
- staticcheck 399 -> 0 with staticcheck.conf (style checks ST1000/1003/
  1005/1016/1020/1021/1022 excluded; error strings are shown in the UI).
- io/ioutil and rand.Seed removed; CloseNotifier kept with a lint-ignore
  until the Phase 2 context rewrite.
- Dead code deleted: Auto handler, getStreamByChannelID, updateXEPG,
  indexOfInt, jsonToMapInt64, removeOldSystemData, randomTime, and the
  commented-out blocks in struct-buffer.go and internal/authentication.
- Duplicates folded: cacheImagesInBackground(), one addErrorToStream().
- Bugs found by SA4006/SA5001: os.Create handle leaked per ffmpeg segment
  (buffer.go), http.NewRequest error unchecked (buffer.go), xepg.json
  migration wrote null on read error (migrate.go), WriteUserData errors
  silently dropped (authentication.go), defer Close before error check
  (buffer.go, toolchain.go). checkFilePermission results were discarded;
  an unwritable config or temp dir is now fatal at start-up.
- gofmt applied repo-wide; Drone runs gofmt check and staticcheck.

Docker:
- Entrypoint starts as root, applies PUID/PGID (falls back to XTEVE_UID/
  XTEVE_GID, then image defaults), fixes config ownership only when it
  differs, then drops to xteve via su-exec. --user starts skip all of it.
- /xteve removed from LEGACY_CONFIG_DIRS (it is the parent of the default).
- mwader/static-ffmpeg pinned to 7.1.1; VOLUME /xteve/config.
- Compose files pull registry.coadcorp.com/nathan/xteve:latest, use
  PUID/PGID/TZ, and explain that SSDP needs host networking.
- .dockerignore excludes the npm toolchain (bundle stays in html/js).

Docs: README rewritten for the fork (about, registry, compose, env vars,
security notes); README-DEV gains a container section.
2026-09-26 12:57:43 +10:00

5.7 KiB

xTeVe improvement checklist

Detailed rationale, file references and effort estimates: tasks/improvement-plan.md. Status: Phase 0 committed on branch improvements 2026-09-26.

Phase 0: Hygiene

  • .gitignore (.gocache/), deleted .gocache/, extended .dockerignore
  • agent.md / skill.md git-ignored and docker-ignored (left in place)
  • Version drift fixed (xteve.go now 0201) and Drone drift check added
  • Auto-updater deleted (BinaryUpdate, internal/up2date, GitHub/Update structs, xteveAutoUpdate + update.url settings, UI rows, en.json); migrations kept in migrate.go; kardianos/osext gone
  • go 1.27.1; Dockerfile and Drone golang images pinned to 1.27.1
  • Four go vet unreachable-code warnings fixed (vet clean)
  • staticcheck baseline via go run honnef.co/go/tools/cmd/staticcheck@latest ./...: 408 findings (S1002 113, SA5008 79, S1039 67, S1038 40, S1023 35, ST1005 20, SA1019 14, SA4006 9, misc 11). Mostly style; SA5008/SA4006/SA1019 worth a pass in Phase 3 cleanup

Phase 1: Security

  • Replace innerHTML with textContent for provider-controlled strings
  • Enforce websocket Origin check; move token from query string to cookie; stop console-logging tokens
  • Cookie HttpOnly + SameSite
  • Wizard GET must not set AuthenticationWEB = false
  • Sanitise uploadLogo filename
  • Zip-slip guard in backup restore
  • Restrict ffmpeg.path / vlc.path and reject non-http(s) stream URLs
  • Put /download/ behind auth
  • Configured base URL instead of Host-header-derived domain
  • bcrypt with migrate-on-login; constant-time compare
  • Token expiry and eviction
  • Only admins may edit other users
  • Settings file mode 0600; redact Plex token in UI payload
  • Decide default for web auth on fresh installs (keep off; LAN only, decided 2026-09-25)

Phase 2: Streaming stability

  • Race tests: two concurrent tuners against a fake TS server, run with -race
  • *Playlist with own mutex; remove stale store-backs
  • Atomic tuner reservation; clean BufferClients on force kill
  • RWMutex around StreamingURLS
  • Remove defer inside read loops (buffer, compression, imgcache)
  • Single external-process buffer (exec.CommandContext + request context) with ffmpeg and VLC argument builders; drop CloseNotifier
  • Real mutex for screen log
  • http.Server with timeouts; timeouts on all outbound clients
  • imgcache: download outside the lock
  • Atomic write helper (temp + fsync + rename)
  • Fix listed concrete bugs (xepg append, range mutation, log overflow, headers after WriteHeader, random notification eviction, unchecked assertions, API double write, WS struct reuse)
  • Error hygiene: no-op closures, os.Exit/panic outside main, ignored results

Phase 3: Build, embed, CI, Docker

  • //go:embed via html/embed.go; deleted webUI.go, html-build.go, cmd/webui-gen; ETag + Cache-Control on static assets
  • i18n dropped: 254 placeholders inlined, en.json deleted, only HTML pages templated (authenticationErr)
  • package.json + ts/tsconfig.json (tsc 5.9.3, ES2020, single outFile html/js/app.js, committed, CI-verified); 10 dead JS files deleted; 6 tsc errors fixed incl. a real ASI bug in the search shortcut
  • CI: vet, gofmt check, staticcheck v0.8.1 (config in staticcheck.conf), bundle freshness check. go test -race still to add once tests exist
  • Version-tagged images (amd64 only)
  • PUID/PGID via su-exec at runtime; static-ffmpeg pinned to 7.1.1; VOLUME /xteve/config; /xteve removed from LEGACY_CONFIG_DIRS; compose files pull from the registry and document SSDP/host networking
  • /healthz endpoint; Dockerfile healthcheck uses it
  • README-DEV.md and fork-specific README.md (about, container usage, env vars, security notes)
  • staticcheck 399 -> 0; dead code and duplicates removed; ioutil/rand.Seed gone. Real bugs fixed on the way: leaked file handle per ffmpeg segment, unchecked http.NewRequest, migration writing null xepg.json, silent user-write failures, unwritable config/temp dir now fatal at start
  • Resolve missing docs/design-system/ referenced by agent.md (user decision: agent.md is a personal, git-ignored file)

Phase 4: Data model and performance

Not planned (lineup is ~170 channels, decided 2026-09-25). See plan for the reference list.

Phase 5: Frontend architecture

  • Persistent websocket with request IDs, queue, backoff reconnect
  • Section-level re-render instead of full createLayout()
  • Virtualised mapping table
  • Split menu_ts.ts; addEventListener; data-driven settings rows
  • Accessibility follow-ups; light theme via prefers-color-scheme
  • Consolidate CSS layers

Phase 6: Optional features

  • Regex filters
  • Per-playlist tuner limit and buffer choice
  • Bulk channel edit
  • Versioned backup/restore
  • Dummy EPG durations

Review

Phase 0 (2026-09-26, branch improvements)

  • go build, go vet, go test ./... all clean. src/webUI.go regenerated.
  • Smoke run against an empty config dir on port 34499: /web/, /lineup_status.json, /discover.json all 200, no errors logged.
  • Not verified locally: Docker image build (no daemon on this machine); Drone will cover it.
  • Compiled JS in html/js/ was hand-edited to mirror the TS change because a current tsc does not reproduce the committed output (different shim, 5 type errors in menu_ts.ts). Phase 3 replaces this with a pinned toolchain.
  • html/js/menu.js still mentions xteveAutoUpdate; it is one of the ten dead legacy files scheduled for deletion in Phase 3.
  • Settings.Branch (git.branch) was kept: it still drives whether the build number is shown in the UI and XMLTV header.