'use client' import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' import AdminShell from '../../ui/AdminShell' import { authFetch, clearToken, getApiBase, getToken } from '../../lib/auth' type FlowStage = { title: string input: string action: string output: string } const REQUEST_FLOW: FlowStage[] = [ { title: 'Identity + access', input: 'Jellyfin/local login', action: 'Magent validates credentials and role', output: 'JWT token + user scope', }, { title: 'Request intake', input: 'Jellyseerr request ID', action: 'Magent snapshots request + media metadata', output: 'Unified request state', }, { title: 'Queue orchestration', input: 'Approved request', action: 'Sonarr/Radarr add/search operations', output: 'Grab decision', }, { title: 'Download execution', input: 'Selected release', action: 'qBittorrent downloads + reports progress', output: 'Import-ready payload', }, { title: 'Library import', input: 'Completed download', action: 'Sonarr/Radarr import and finalize', output: 'Available media object', }, { title: 'Playback availability', input: 'Imported media', action: 'Jellyfin refresh + link resolution', output: 'Ready-to-watch state', }, ] export default function AdminSystemGuidePage() { const router = useRouter() const [loading, setLoading] = useState(true) const [authorized, setAuthorized] = useState(false) useEffect(() => { let active = true const load = async () => { if (!getToken()) { router.push('/login') return } try { const baseUrl = getApiBase() const response = await authFetch(`${baseUrl}/auth/me`) if (!response.ok) { if (response.status === 401) { clearToken() router.push('/login') return } router.push('/') return } const me = await response.json() if (!active) return if (me?.role !== 'admin') { router.push('/') return } setAuthorized(true) } catch (error) { console.error(error) router.push('/') } finally { if (active) setLoading(false) } } void load() return () => { active = false } }, [router]) if (loading) { return
Loading system guide...
} if (!authorized) { return null } const rail = (
Guide map

Quick path

Identity → Intake → Queue → Download → Import → Playback.

Admin only
) return ( router.push('/admin')}> Back to settings } >

End-to-end system flow

This is the exact runtime path for request processing and availability in the current build.

{REQUEST_FLOW.map((stage, index) => (
{index + 1}. {stage.title}
Input {stage.input}
Action {stage.action}
Output {stage.output}
{index < REQUEST_FLOW.length - 1 && }
))}

Operational controls by area

General

Application URL, API URL, ports, bind host, proxy base URL, and manual SSL settings.

Notifications

Email, Discord, Telegram, push/mobile, and generic webhook delivery channels.

Users

Role/profile/expiry, auto-search access, invite access, and cross-system ban/remove actions.

Invite management

Master template, profile assignment, invite access policy, and invite trace map lineage.

Requests + cache

All-requests view, sync controls, cached request records, and maintenance operations.

Live request page

Event-stream updates for state, action history, and torrent progress without page refresh.

Stall recovery path (decision flow)

  1. Request approved but not in Arr queue run Re-add to Arr.
  2. In queue but no release found run Search releases and inspect options.
  3. Release exists and user should not pick manually run Search + auto-download.
  4. Download paused/stalled in qBittorrent run Resume download.
  5. Imported but not visible to user validate Jellyfin visibility/link from request page.
) }