180 lines · 7.7 KB
import { createFileRoute, Link, notFound } from "@tanstack/react-router";
import { useState } from "react";
import { z } from "zod";
import { getArtifactsHealth } from "~/fns/artifacts-health";
import type { ArtifactsFailure, ArtifactsOperationStats } from "~/fns/artifacts-health";
import { Button } from "~/ui/Button";
import { EmptyState } from "~/ui/EmptyState";
import { PageContainer } from "~/ui/PageContainer";
import { Panel } from "~/ui/Panel";
import { RelativeTime } from "~/ui/RelativeTime";
import { TextLink } from "~/ui/TextLink";
import { Heading } from "~/ui/Heading";

const WINDOWS = [1, 24, 168, 720] as const;
const MAX_REPORT_REFERENCES = 50;

export const Route = createFileRoute("/admin/artifacts")({
  validateSearch: z.object({ hours: z.number().int().optional(), operation: z.string().optional() }),
  beforeLoad: ({ context }) => {
    if (!context.viewer?.isAdmin) throw notFound();
  },
  loaderDeps: ({ search }) => search,
  loader: ({ deps }) =>
    getArtifactsHealth({
      data: { hours: WINDOWS.find((hours) => hours === deps.hours) ?? 24, operation: deps.operation },
    }),
  component: ArtifactsHealthPage,
});

function rate(stats: ArtifactsOperationStats): string {
  return stats.calls === 0 ? "—" : `${((stats.failures / stats.calls) * 100).toFixed(2)}%`;
}

const HOURS_PER_DAY = 24;

function windowLabel(hours: number): string {
  return hours < HOURS_PER_DAY ? `${hours}h` : `${hours / HOURS_PER_DAY}d`;
}

/** Plain-text incident report for Cloudflare support; mirrors docs/artifacts-report-template.md. */