Ops-dashboard/app/settings/backups/page.tsx
Scrum4Me Agent 09050d5ce7 feat(backup): add /settings/backups UI page with Backup now button
Server component fetches backup list via list_ops_backups agent command
and parses filename/size output. Client BackupsPanel component shows a
backup table and a Backup now button that triggers the backup_ops_db
flow with streaming terminal output and audit log link.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:07:34 +02:00

59 lines
1.8 KiB
TypeScript

import Link from 'next/link'
import { redirect } from 'next/navigation'
import { getCurrentUser } from '@/lib/session'
import { execAgent } from '@/lib/agent-client'
import BackupsPanel from './_components/backups-panel'
export const dynamic = 'force-dynamic'
export interface BackupFile {
name: string
sizeBytes: number
label: string
}
function parseBackupList(output: string): BackupFile[] {
return output
.split('\n')
.map((line) => line.trim())
.filter(Boolean)
.map((line) => {
const [name, sizeStr] = line.split('\t')
const sizeBytes = parseInt(sizeStr ?? '0', 10) || 0
const m = name?.match(/ops_db_(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})\.dump/)
const label = m ? `${m[1]}-${m[2]}-${m[3]} ${m[4]}:${m[5]}` : (name ?? '')
return { name: name ?? '', sizeBytes, label }
})
.filter((b) => b.name)
}
export default async function BackupsPage() {
const user = await getCurrentUser()
if (!user) redirect('/login')
let backups: BackupFile[] = []
let listError: string | null = null
try {
const output = await execAgent('list_ops_backups')
backups = parseBackupList(output)
} catch (err) {
listError = err instanceof Error ? err.message : 'failed to list backups'
}
return (
<div className="min-h-screen bg-background p-6">
<div className="mx-auto max-w-4xl space-y-6">
<div className="flex items-center gap-3">
<Link href="/" className="text-sm text-muted-foreground hover:text-foreground">
Home
</Link>
<span className="text-muted-foreground">/</span>
<h1 className="text-2xl font-semibold tracking-tight">Backups</h1>
</div>
<BackupsPanel backups={backups} listError={listError} />
</div>
</div>
)
}