migration 026 backup_runs; POST ingest (owner) from offsite-backup.sh, GET for the Sacred Valley card showing last run, per-guest sizes, Farm free, schedule. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
31 lines
1.2 KiB
JavaScript
31 lines
1.2 KiB
JavaScript
import { Router } from 'express';
|
|
import { z } from 'zod';
|
|
import { asyncWrap } from '../errors.js';
|
|
import { requireOwner } from '../cap.js';
|
|
import { validate } from '../validate.js';
|
|
import * as backups from '../../db/repos/backups.js';
|
|
|
|
export const router = Router();
|
|
|
|
export const ingest = z.object({
|
|
ok: z.boolean().optional(),
|
|
total_bytes: z.number().int().nonnegative().nullable().optional(),
|
|
won_free_bytes: z.number().int().nonnegative().nullable().optional(),
|
|
guests: z.array(z.object({
|
|
vmid: z.union([z.number().int(), z.string()]),
|
|
name: z.string().max(64),
|
|
bytes: z.number().int().nonnegative()
|
|
})).max(50).nullable().optional(),
|
|
duration_sec: z.number().int().nonnegative().nullable().optional()
|
|
});
|
|
|
|
// POST /api/backups — the offsite-backup script reports a run (owner only).
|
|
router.post('/', requireOwner, validate({ body: ingest }), asyncWrap(async (req, res) => {
|
|
res.status(201).json(await backups.record(req.body));
|
|
}));
|
|
|
|
// GET /api/backups — latest run + count, for the Sacred Valley "Backups" card.
|
|
router.get('/', asyncWrap(async (_req, res) => {
|
|
res.json({ latest: await backups.latest(), count: await backups.count(), schedule: 'Sun 02:00' });
|
|
}));
|