SPB Git forge

spb/toveli

Public
14commits 1branches 0releases
1.1 MBsize
maindefault branch
4 h agolast push
TypeScript 50.6% JavaScript 46.1% SQL 2.1% Shell 0.6% CSS 0.5%
1.4 KB · 9 lines tsx
Raw Blame History
1import { desc } from "drizzle-orm";2import { db } from "@/db/client";3import { auditEvents } from "@/db/schema";4export const dynamic = "force-dynamic";5export default async function Journal() {6  const rows = await db().select().from(auditEvents).orderBy(desc(auditEvents.createdAt)).limit(300);7  return (<div><h1 className="text-2xl font-extrabold tracking-tight mb-3">Journal d'audit (300 derniers)</h1><div className="tv-card overflow-x-auto"><table className="w-full text-xs"><thead className="text-left text-ink-3"><tr><th className="p-2 font-medium">Date</th><th className="p-2 font-medium">Action</th><th className="p-2 font-medium">Acteur</th><th className="p-2 font-medium">Objet</th><th className="p-2 font-medium">Méta (minimisées)</th></tr></thead><tbody>{rows.map((r) => <tr key={r.id} className="border-t border-line"><td className="p-2 whitespace-nowrap">{r.createdAt.toLocaleString("fr-CA", { timeZone: "America/Toronto" })}</td><td className="p-2 font-medium">{r.action}</td><td className="p-2 font-mono">{r.actorId?.slice(0, 8) ?? "—"}</td><td className="p-2">{r.objectType ? `${r.objectType} ${String(r.objectId ?? "").slice(0, 12)}` : "—"}</td><td className="p-2 font-mono text-ink-2">{JSON.stringify(r.metadataRedacted).slice(0, 80)}</td></tr>)}</tbody></table></div><p className="text-xs text-ink-3 mt-2">Append-only : aucune route ne modifie ni ne supprime ces lignes ; adresses IP hachées, aucun code ni jeton.</p></div>);8}9