← back to Homesonspec

apps/admin/src/app/snapshots/page.tsx

46 lines

import { prisma } from "@homesonspec/database";
import { CreatedChip } from "@homesonspec/shared-ui";

export const dynamic = "force-dynamic";

export default async function SnapshotsPage() {
  const snapshots = await prisma.rawSnapshot.findMany({
    orderBy: { retrievedAt: "desc" },
    take: 100,
    include: { source: { select: { name: true } }, _count: { select: { staged: true } } },
  });

  return (
    <div>
      <h1 className="text-2xl font-bold">Raw snapshots</h1>
      <p className="mt-1 text-sm text-neutral-500">
        Immutable fetched bodies (stored on disk) — the audit trail behind every extraction.
      </p>
      <div className="mt-4 overflow-x-auto rounded-xl border border-neutral-200 bg-white shadow-sm">
        <table className="w-full text-left text-sm">
          <thead className="border-b border-neutral-200 text-xs uppercase text-neutral-500">
            <tr>
              <th className="px-3 py-2">Source</th>
              <th className="px-3 py-2">URL</th>
              <th className="px-3 py-2">Hash</th>
              <th className="px-3 py-2">Staged</th>
              <th className="px-3 py-2">Retrieved</th>
            </tr>
          </thead>
          <tbody>
            {snapshots.map((snapshot) => (
              <tr key={snapshot.id} className="border-b border-neutral-100">
                <td className="px-3 py-1.5 text-xs">{snapshot.source.name}</td>
                <td className="max-w-md truncate px-3 py-1.5 text-xs text-neutral-600">{snapshot.url}</td>
                <td className="px-3 py-1.5 font-mono text-xs">{snapshot.contentHash.slice(0, 12)}…</td>
                <td className="px-3 py-1.5">{snapshot._count.staged}</td>
                <td className="px-3 py-1.5"><CreatedChip date={snapshot.retrievedAt} /></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}