Process 1 build 0203261953

This commit is contained in:
2026-03-02 19:54:14 +13:00
parent b0ef455498
commit 9c69d9fd17
22 changed files with 672 additions and 279 deletions

View File

@@ -104,7 +104,7 @@ const SECTION_DESCRIPTIONS: Record<string, string> = {
qbittorrent: 'Downloader connection settings.',
requests: 'Control how often requests are refreshed and cleaned up.',
log: 'Activity log for troubleshooting.',
site: 'Sitewide banner, version, and changelog details.',
site: 'Sitewide banner and version details. The changelog is generated from git history during release builds.',
}
const SETTINGS_SECTION_MAP: Record<string, string | null> = {
@@ -555,7 +555,8 @@ export default function SettingsPage({ section }: SettingsPageProps) {
const isCacheSection = section === 'cache'
const cacheSettingKeys = new Set(['requests_sync_ttl_minutes', 'requests_data_source'])
const artworkSettingKeys = new Set(['artwork_cache_mode'])
const hiddenSettingKeys = new Set([...cacheSettingKeys, ...artworkSettingKeys])
const generatedSettingKeys = new Set(['site_changelog'])
const hiddenSettingKeys = new Set([...cacheSettingKeys, ...artworkSettingKeys, ...generatedSettingKeys])
const requestSettingOrder = [
'requests_poll_interval_seconds',
'requests_delta_sync_interval_minutes',
@@ -608,7 +609,7 @@ export default function SettingsPage({ section }: SettingsPageProps) {
items: (() => {
const sectionItems = groupedSettings[sectionKey] ?? []
const filtered =
sectionKey === 'requests' || sectionKey === 'artwork'
sectionKey === 'requests' || sectionKey === 'artwork' || sectionKey === 'site'
? sectionItems.filter((setting) => !hiddenSettingKeys.has(setting.key))
: sectionItems
if (sectionKey === 'requests') {
@@ -940,8 +941,10 @@ export default function SettingsPage({ section }: SettingsPageProps) {
setSectionFeedback((current) => ({
...current,
[sectionGroup.key]: {
tone: 'status',
message: `Test email sent to ${data?.recipient_email ?? 'the configured mailbox'}.`,
tone: data?.warning ? 'error' : 'status',
message: data?.warning
? `SMTP accepted a relay-mode test for ${data?.recipient_email ?? 'the configured mailbox'}, but delivery is not guaranteed. ${data.warning}`
: `Test email sent to ${data?.recipient_email ?? 'the configured mailbox'}.`,
},
}))
return

View File

@@ -106,9 +106,9 @@ export default function AdminSystemGuidePage() {
const rail = (
<div className="admin-rail-stack">
<div className="admin-rail-card">
<span className="admin-rail-eyebrow">Guide map</span>
<h2>Quick path</h2>
<p>Identity Intake Queue Download Import Playback.</p>
<span className="admin-rail-eyebrow">How it works</span>
<h2>Admin flow map</h2>
<p>Identity Request intake Queue orchestration Download Import Playback.</p>
<span className="small-pill">Admin only</span>
</div>
</div>
@@ -116,8 +116,8 @@ export default function AdminSystemGuidePage() {
return (
<AdminShell
title="System guide"
subtitle="Admin-only architecture and operational flow for Magent."
title="How it works"
subtitle="Admin-only service wiring, control areas, and recovery flow for Magent."
rail={rail}
actions={
<button type="button" onClick={() => router.push('/admin')}>
@@ -129,7 +129,8 @@ export default function AdminSystemGuidePage() {
<div className="admin-panel">
<h2>End-to-end system flow</h2>
<p className="lede">
This is the exact runtime path for request processing and availability in the current build.
This is the runtime path the platform follows from authentication through to playback
availability.
</p>
<div className="system-flow-track">
{REQUEST_FLOW.map((stage, index) => (
@@ -155,6 +156,51 @@ export default function AdminSystemGuidePage() {
</div>
</div>
<div className="admin-panel">
<h2>What each service is responsible for</h2>
<div className="system-guide-grid">
<article className="system-guide-card">
<h3>Magent</h3>
<p>
Handles authentication, request pages, live event updates, invite workflows,
diagnostics, notifications, and admin operations.
</p>
</article>
<article className="system-guide-card">
<h3>Seerr</h3>
<p>
Stores the request itself and remains the request-state source for approval and
media request metadata.
</p>
</article>
<article className="system-guide-card">
<h3>Jellyfin</h3>
<p>
Provides user sign-in identity and the final playback destination once content is
available.
</p>
</article>
<article className="system-guide-card">
<h3>Sonarr / Radarr</h3>
<p>
Control queue placement, quality-profile decisions, import handling, and release
monitoring.
</p>
</article>
<article className="system-guide-card">
<h3>Prowlarr</h3>
<p>Provides search/indexer coverage for Arr-side release searches.</p>
</article>
<article className="system-guide-card">
<h3>qBittorrent</h3>
<p>
Executes the download and exposes live progress, paused states, and queue
visibility.
</p>
</article>
</div>
</div>
<div className="admin-panel">
<h2>Operational controls by area</h2>
<div className="system-guide-grid">
@@ -172,19 +218,48 @@ export default function AdminSystemGuidePage() {
</article>
<article className="system-guide-card">
<h3>Invite management</h3>
<p>Master template, profile assignment, invite access policy, and invite trace map lineage.</p>
<p>
Master template, profile assignment, invite access policy, invite emails, and trace
map lineage.
</p>
</article>
<article className="system-guide-card">
<h3>Requests + cache</h3>
<p>All-requests view, sync controls, cached request records, and maintenance operations.</p>
</article>
<article className="system-guide-card">
<h3>Live request page</h3>
<p>Event-stream updates for state, action history, and torrent progress without page refresh.</p>
<h3>Maintenance + diagnostics</h3>
<p>
Connectivity checks, live diagnostics, database repair, cleanup, log review, and
nuclear flush/resync operations.
</p>
</article>
</div>
</div>
<div className="admin-panel">
<h2>User and invite model</h2>
<ol className="system-decision-list">
<li>
Jellyfin is used for sign-in identity and user presence across the platform.
</li>
<li>
Seerr provides request ownership and request-state data for Magent request pages.
</li>
<li>
Invite links, invite profiles, blanket rules, and invite-access controls are managed
inside Magent.
</li>
<li>
If invite tracing is enabled, the lineage view shows who invited whom and how the
chain branches.
</li>
<li>
Cross-system removal and ban flows are initiated from Magent admin controls.
</li>
</ol>
</div>
<div className="admin-panel">
<h2>Stall recovery path (decision flow)</h2>
<ol className="system-decision-list">
@@ -205,6 +280,24 @@ export default function AdminSystemGuidePage() {
</li>
</ol>
</div>
<div className="admin-panel">
<h2>Live update surfaces</h2>
<div className="system-guide-grid">
<article className="system-guide-card">
<h3>Landing page</h3>
<p>Recent requests and service summaries refresh live for signed-in users.</p>
</article>
<article className="system-guide-card">
<h3>Request pages</h3>
<p>Timeline state, queue activity, and torrent progress are pushed live without refresh.</p>
</article>
<article className="system-guide-card">
<h3>Admin views</h3>
<p>Diagnostics, logs, sync state, and maintenance surfaces stream live operational data.</p>
</article>
</div>
</div>
</section>
</AdminShell>
)