Files
Cyrene_v2/frontend/web/src/admin/audit.ts
T

36 lines
1002 B
TypeScript

import { create } from "zustand";
import type { AuditRecord } from "../lib/types";
import { getStoredRole } from "../lib/api";
import { now, uid } from "../lib/util";
/**
* Client-side audit trail. Every admin write the panel performs is pushed here
* with who/what/when/result so the 可观测性 → 审计 tab has real content even
* before the backend exposes an audit endpoint. It is also the visual front of
* the "主代理代审 + 审计日志" red line.
*/
interface AuditStore {
records: AuditRecord[];
log: (what: string, result: "ok" | "error") => void;
clear: () => void;
}
export const useAuditStore = create<AuditStore>((set) => ({
records: [],
log: (what, result) =>
set((s) => ({
records: [
{
id: uid(),
who: getStoredRole() ?? "anonymous",
what,
when: new Date(now()).toISOString(),
result,
},
...s.records,
].slice(0, 200),
})),
clear: () => set({ records: [] }),
}));