SPB Git

spb/autoscholar

Public
1.7 KB · 65 lines tsx
1import { listRuns } from "@autoscholar/core";2import Link from "next/link";3import { StatusBadge } from "@/components/StatusBadge";4import { ago } from "@/lib/format";5import { db } from "@/lib/server/db";67export const dynamic = "force-dynamic";89export default async function QualityIndex() {10  const runs = await listRuns(db(), {11    status: [12      "quality_check",13      "quality_failed",14      "ready_to_publish",15      "awaiting_approval",16      "publishing",17      "published",18    ],19    limit: 200,20  });21  return (22    <div className="space-y-6">23      <header>24        <p className="eyebrow">Gates</p>25        <h1 className="title-2 mt-1">Quality</h1>26        <p className="muted mt-1 text-sm">27          Deterministic gate outcomes computed on the control plane. Overrides are limited to soft/structural28          gates and are recorded with a rationale.29        </p>30      </header>31      <table className="table">32        <thead>33          <tr>34            <th>Run</th>35            <th>Status</th>36            <th>Mode</th>37            <th>Updated</th>38          </tr>39        </thead>40        <tbody>41          {runs.length === 0 && (42            <tr>43              <td colSpan={4} className="muted py-8 text-center">44                No run has reached quality evaluation.45              </td>46            </tr>47          )}48          {runs.map((r) => (49            <tr key={r.id}>50              <td>51                <Link href={`/admin/quality/${r.id}`}>{r.title}</Link>52              </td>53              <td>54                <StatusBadge status={r.status} />55              </td>56              <td>{r.researchMode}</td>57              <td className="subtle text-xs">{ago(r.updatedAt)}</td>58            </tr>59          ))}60        </tbody>61      </table>62    </div>63  );64}65
Files · main
Menu

Theme