SPB Git

spb/autoscholar

Public
3.9 KB · 103 lines tsx
1import { allSettings, getEnv } from "@autoscholar/core";2import { auditEvents } from "@autoscholar/db";3import { desc } from "drizzle-orm";4import { fmtDateTime } from "@/lib/format";5import { db } from "@/lib/server/db";6import { currentSession } from "@/lib/server/session";7import { SettingsControls } from "./SettingsControls";89export const dynamic = "force-dynamic";1011export default async function SettingsPage() {12  const d = db();13  const env = getEnv();14  const settings = await allSettings(d);15  const audit = await d.select().from(auditEvents).orderBy(desc(auditEvents.createdAt)).limit(100);16  const sess = await currentSession();17  return (18    <div className="space-y-8">19      <header>20        <p className="eyebrow">Founder controls</p>21        <h1 className="title-2 mt-1">Settings & security</h1>22      </header>23      <SettingsControls24        settings={{25          dispatchPaused: settings["dispatch.paused"] === true,26          publishingHalted: settings["publishing.halted"] === true,27          haltedModes: (settings["publishing.haltedModes"] as string[]) ?? [],28        }}29      />30      <section className="surface p-4">31        <h2 className="title-3">Environment and providers</h2>32        <dl className="mt-2 grid grid-cols-2 gap-x-6 gap-y-1 text-xs sm:grid-cols-4">33          <dt className="muted">Publishing (env)</dt>34          <dd>{env.PUBLISHING_ENABLED === 1 ? "enabled" : "DISABLED"}</dd>35          <dt className="muted">Dispatch (env)</dt>36          <dd>{env.DISPATCH_ENABLED === 1 ? "enabled" : "DISABLED"}</dd>37          <dt className="muted">Staging mode</dt>38          <dd>{env.STAGING_MODE === 1 ? "on (noindex, synthetic sample allowed)" : "off"}</dd>39          <dt className="muted">Research model</dt>40          <dd className="font-mono">{env.ANTHROPIC_MODEL}</dd>41          <dt className="muted">Reviewer model</dt>42          <dd className="font-mono">{env.ANTHROPIC_REVIEWER_MODEL}</dd>43          <dt className="muted">Default caps</dt>44          <dd>45            ${env.DEFAULT_MAX_BUDGET_USD} · {env.DEFAULT_MAX_RUNTIME_MINUTES} min46          </dd>47          <dt className="muted">Lease TTL</dt>48          <dd>{env.LEASE_TTL_SECONDS}s</dd>49          <dt className="muted">Enrollment secret</dt>50          <dd>{env.WORKER_ENROLLMENT_SECRET ? "configured" : "not set"}</dd>51          <dt className="muted">Anthropic key on control plane</dt>52          <dd>53            {process.env.ANTHROPIC_API_KEY54              ? "present (not needed here)"55              : "absent (expected: keys live on workers)"}56          </dd>57          <dt className="muted">Session</dt>58          <dd>59            {sess?.username} · expires {fmtDateTime(sess?.expiresAt)}60          </dd>61        </dl>62      </section>63      <section className="surface p-4">64        <h2 className="title-3">Audit log (latest 100)</h2>65        <table className="table mt-2">66          <thead>67            <tr>68              <th>When</th>69              <th>Actor</th>70              <th>Action</th>71              <th>Target</th>72              <th>Detail</th>73            </tr>74          </thead>75          <tbody>76            {audit.length === 0 && (77              <tr>78                <td colSpan={5} className="muted py-6 text-center">79                  Empty.80                </td>81              </tr>82            )}83            {audit.map((a) => (84              <tr key={a.id}>85                <td className="subtle whitespace-nowrap text-xs">{fmtDateTime(a.createdAt)}</td>86                <td className="text-xs">87                  {a.actorType}88                  {a.actorId ? `:${a.actorId.slice(0, 8)}` : ""}89                </td>90                <td className="font-mono text-xs">{a.action}</td>91                <td className="text-xs">92                  {a.targetType} {a.targetId?.slice(0, 8)}93                </td>94                <td className="muted max-w-md truncate text-xs">{JSON.stringify(a.detail)}</td>95              </tr>96            ))}97          </tbody>98        </table>99      </section>100    </div>101  );102}103
Files · main
Menu

Theme