feat: add server-sent events for logging and activity tracking

- Implemented a custom tracing layer (`AppLogLayer`) to capture log events and broadcast them to SSE clients.
- Created admin routes for streaming server logs and listing recent activity logs.
- Added an activity log repository interface and SQLite implementation for persisting activity events.
- Integrated activity logging into user authentication and channel CRUD operations.
- Developed frontend components for displaying server logs and activity logs in the admin panel.
- Enhanced the video player with a stats overlay for monitoring streaming metrics.
This commit is contained in:
2026-03-16 02:21:40 +01:00
parent 4df6522952
commit e805028d46
28 changed files with 893 additions and 8 deletions

View File

@@ -16,6 +16,7 @@ import type { SubtitleTrack } from "./components/video-player";
import type { LogoPosition } from "@/lib/types";
import {
Cast,
Info,
Maximize2,
Minimize2,
Volume1,
@@ -101,6 +102,7 @@ function TvPageContent() {
// Overlay / idle state
const [showOverlays, setShowOverlays] = useState(true);
const [showSchedule, setShowSchedule] = useState(false);
const [showStats, setShowStats] = useState(false);
const idleTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
// Video ref — used to resume playback if autoplay was blocked on load
@@ -411,6 +413,10 @@ function TvPageContent() {
e.preventDefault();
prevChannel();
break;
case "s":
case "S":
setShowStats((v) => !v);
break;
case "g":
case "G":
toggleSchedule();
@@ -623,6 +629,8 @@ function TvPageContent() {
}
subtitleTrack={activeSubtitleTrack}
muted={isMuted}
showStats={showStats}
broadcast={broadcast}
onSubtitleTracksChange={setSubtitleTracks}
onStreamError={handleStreamError}
onEnded={handleVideoEnded}
@@ -850,6 +858,14 @@ function TvPageContent() {
)}
</div>
<button
className={`pointer-events-auto rounded-md bg-black/50 p-1.5 backdrop-blur transition-colors hover:bg-black/70 hover:text-white ${showStats ? "text-violet-400" : "text-zinc-400"}`}
onClick={() => setShowStats((v) => !v)}
title="Stats for nerds [S]"
>
<Info className="h-4 w-4" />
</button>
<button
className="pointer-events-auto rounded-md bg-black/50 px-3 py-1.5 text-xs text-zinc-400 backdrop-blur transition-colors hover:bg-black/70 hover:text-white"
onClick={toggleSchedule}