@12-apps/audit

中文文档
5.11.0发布于 2026/10/30MITES Module构建来源已验证近 30 天下载 3.3万

普通、便携式行动审计。 无框架核心(动作/资源词汇和默认 diff 编辑),主机挂载后端表面(./ server: 交易写入器, 每请求的演员上下文, 创建/ 更新后印出)

中文使用文档
文档目录8 节
  1. 它是为了什么
  2. 词汇
  3. 后端的一半
  4. 终点
  5. 允许它打开
  6. 前端的半边
  7. 数据库
  8. 这不能防止

@12-apps/audit

动作审计作为套件: 仅是附件的"谁做了什么"线索, 它的交易 编剧,背后的每个请求的演员背景,两个Prisma扩展 执行它, 保留扫描, 租户范围上市 终点和 观者读之.

词汇表是你的. 这个包船没有动作,没有资源类型, 没有字段许可列表,也没有产品语言——你宣布并传入. 见 采用.md 用于迁移表,如果您来自 1.x (中文(简体) ).

两半,各一厂.

// backend
import { createApiAudit } from '@12-apps/audit/server';
import { auditRouter } from '@12-apps/audit/hono';

// frontend
import { createWebAudit } from '@12-apps/audit/react';

它是为了什么

审计线索只有在事后无法编辑才值得,而且只值得 如果写得对的话,是站不住脚的 这个包是这两个属性, 机械制造:

  • 不可思议. 该条目被写入 INSID 呼叫者的交易, 所以"它 "它被记录下来" 承诺或滚回一起——从来没有 火相与忘却. 后来,模型拒绝了 update 编号 : upsert 编号 : delete 在客户端.
  • 正确归属. 入口带有一个身份的AIR:真正的人类 其全权证书授权写作,而且——当某届会议正在冒充时—— 谁是屏幕声称的。 一个领域无法回答两个问题,而且 拆解它们不能在附件表格中恢复.

词汇

一种价值描述的是可能审计的内容,一行可能说的话,以及人类 读取。 两者都取同物.

import { defineAuditVocabulary } from '@12-apps/audit';

export const AUDIT = defineAuditVocabulary({
  actions: {
    'post.publish': { label: 'Post published' },
    'comment.hide': { label: 'Comment hidden' },
  },
  resources: {
    post: { label: 'Post', fields: ['title', 'state', 'publishedAt'] },
    comment: { label: 'Comment', fields: ['state', 'reason'] },
  },
});

fields 是一个 逐项拒绝授权列表: diff 携带但 词汇表不删除名称, 因此调用者会通过整个数据库行 无法将 PII 泄露到仅包含附件的表格中。 反面是,一个疏漏是 无法在写入站点中隐藏并显示为空洞的条目——列出每个字段 共享资源类型中的每个写入器都会发出.

工厂拒绝,在集会上,一切 使词汇 不安全的后端: 一个空轴, 一个空轴 fields,空白标签,空白或 白空加法 id 或 字段名, 重复字段, 整数式 id 。 每个 其中一个是故障打开,解释在 采用.md 第5节.

后端的一半

const audit = auditRouter({
  db: () => getPrismaClient(),               // the seam: one owned model
  vocabulary: AUDIT,                         // what may be audited
  trackedModels: ['Post', 'Comment'],        // created_by / updated_by
  retention: { floorDays: 365 },
  directory: { getUsers, listActors },       // who a user id is (optional)
  messages: { forbidden: 'No access.' },     // your product's copy
  resolveActor: async (request) => {         // WHO is calling
    const session = await auth(request.raw);
    if (!session) return null;
    const { tenantId, permissions } = await resolveTenant(request.params.tenantSlug, session);
    // Return null — the 401 — rather than an actor with no tenant. An `undefined`
    // tenantId is a cross-tenant read waiting to happen, so the package refuses it
    // with a 500 (ADOPTING.md rule 1).
    if (!tenantId) return null;
    return {
      tenantId,
      userId: session.user.id,
      permissions,
      role: session.role,
      scope: tenantId,
      onBehalfOfUserId: session.impersonating?.subjectUserId ?? null,
    };
  },
});

app.use('*', audit.actorContext);              // stamp every request
app.route('/api/admin/:tenantSlug', audit.router);

你得到什么回来:

routes框架中性描述符,按挂起顺序排列(./hono 适应它们)
write(tx, entry)交易写入器 —— 在您的交易中调用它
extendPrismaClient(client)两次扩展,一次在客户端构建时应用
withActorContext(req, run)演员文本中间软件( nameactorContext 内 ./hono(中文(简体) )
retentionpurgeExpired() 财务报告和审定财务报表 purgeTenantWindow(tenant, since, cutoff)
store租户范围改为: 显示相同行的宿主表面
vocabulary有效的词汇表——标签和验证

终点

方法路径
GET/audit-logs房客的踪迹, 最新的第一—— { data, pagination }
GET/audit-logs/actors观众的演员-过滤选项—— { data }

过滤器 : q (资源id包含, \\ 200个字符), action_in, (中文(简体) ), resourceType_in, (中文(简体) ), actorUserId, (中文(简体) ), resourceId, (中文(简体) ), from编号 :to (含 YYYY-MM-DD, (中文(简体) ), sort, (中文(简体) ), page, (中文(简体) ), pageSize。呼号是配置(pagination),默认为 20 / 100 / 100 / 100 000, 并且它们作为限定整数而不是作为 光线 未知的过滤器值, 不可保存 sort 且日期不正确 400 从未接受和忽视;否认就是 { error } 在顶层 401 编号 : 403。 。 。 .

名单的顺序是 共计数字 : created_at DESC, id DESC 默认,或 ASC, ASC 页:1 ?sort=createdAt:asc —— 说 created_at 是一条线索的一轴, 向前看 事情是如何重建的 领带断了 遵循方向,否则两种观点不会相互颠倒。 审计线索是: 连续写作 created_at 实值 timestamp(3),所以联系是普通的——和 SQL 保证某类无法区分的行顺序 与 skip编号 :take 意思是读者看到一个条目两次,从不看到另一个. 接合断是接合的一部分AUDIT_LOG_ORDER_BY因此,一个非Prisma 而不是重新塑造它.

有一个 无写入结束点条目是由变异体自己写的, 所以这里的POST只是一种 伪造历史的方法.

允许它打开

audit:read 导出为 AUDIT_READ_PERMISSION,因为这个软件包拥有 端点 它守护。 把它写入目录,或者用不同的拼写 与 gatePermissions.read ——常数是默认数,而不是要求.

前端的半边

const { page: AuditLog } = createWebAudit({
  apiBase: '/api/admin/my-store',
  vocabulary: AUDIT,
  labels: { title: 'History' },   // your product's words
});

整个SCREEN,关于共享 DataViews 网格:仪表板头 [i] 及其导出、 搜索框、 动作/ 资源/ 演员过滤器 药丸、 周期范围、 可排序的日期列、 列可见度、 已保存 视图,带有 diff 摘要和服务器-模式寻呼器的线索——以及 作为一行命名的假配对 两者 人类 词汇 与后端部分共享,所以存在的动作是动作 取景器可以标签.

作为 SAME 网格, 主机的其他列表使用是关键: 操作员移动 在Pedidos,Produtos和小道之间学习一个过滤棒. 两个东道方 要求随即提出 DataViewsCopyProvider 在您的根部( 网格本身) 语言是属于你的,它拒绝发明它们 table 包装,如果你 想要保存视图, 因为坚持是一个后端 。 见 通过.md§4b.

复制默认为英语, 日期为运行时的自有地段 。 两者都是 背弃而不是建议——一揽子方案无法了解你的市场,以及 1.x 默认为一个应用程序.

一个读者会说葡萄牙语的东道主 通过了运来的包而不是 重写它: PT_BR_AUDIT_LABELS (单位:千美元)./react改为: labels, (中文(简体) ), PT_BR_AUDIT_MESSAGES (单位:千美元)./server改为: messages。每个都有一个 EN_US_* 双向和标签键地图 (单位:千美元)AUDIT_LABELS, (中文(简体) ), AUDIT_MESSAGES)——通过.md§4.

数据库

软件包拥有一个模型(prisma/audit.prisma及其移徙。 一个主机 复制部分与软件包自己的脚本:

node node_modules/@12-apps/audit/scripts/sync-audit-schema.mjs [<host-schema-dir>]

迁移是 重放安全 (单位:千美元)CREATE TABLE IF NOT EXISTS, (中文(简体) ), ADD COLUMN IF NOT EXISTS, (中文(简体) ), CREATE INDEX IF NOT EXISTS),所以一个宿主已经 有一个 audit_logs 页:1 prisma migrate resolve --applied。 。 。 .

这不能防止

很明显,因为一个没有证件的警卫 会被信任过 他们:

  • Raw SQL 绕过仅附加的守护. $executeRaw* 编号 : $queryRaw* 永远 给一个模型代表,所以任何人 持有客户可以 DELETE FROM audit_logs这是故意的——这是保留的唯一办法 扫描可以运行 - 这意味着警卫 停止AccIDENT,不是决心 操作员。 该级别的保证是数据库权限或触发,以及 两者都归东道主所有.
  • 另一个连接没有受到影响. psql, 一个迁移, 第二个客户端已建立 没有扩展.
  • 主机仍然拥有授权. 许可标识上的包口 宿主决定了,它不计算它们,它不读任何物 演员没有带.

见 采用.md 完全合同,假冒对夫妇 设计、装配拒绝和核对表.

版本与发布记录

@12-apps/audit 共发布 20 个版本,首次发布于 2026/08/13;过去 12 个月发布了 20 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
5.11.0latest2026/10/308 天前
5.10.02026/10/2711 天前
5.9.02026/10/2514 天前
5.8.02026/09/271 个月前
5.7.12026/08/262 个月前
5.7.02026/08/262 个月前

关于 @12-apps/audit 的常见问题

@12-apps/audit 是什么?

普通、便携式行动审计。 无框架核心(动作/资源词汇和默认 diff 编辑),主机挂载后端表面(./ server: 交易写入器, 每请求的演员上下文, 创建/ 更新后印出)

如何安装 @12-apps/audit?

在项目目录运行 npm install @12-apps/audit,或使用 pnpm add / yarn add / bun add。

@12-apps/audit 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/12-apps__audit 是否存在。

@12-apps/audit 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@12-apps/audit 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@12-apps/audit 可以商用吗?

@12-apps/audit 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@12-apps/audit 的下载量有多少?

根据 npm 官方下载统计,@12-apps/audit 在 2026/10/04 – 2026/11/02 这 30 天内被下载 33,353 次,日均约 1,112 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@12-apps/audit 还在维护吗?

最新版本 5.11.0 发布于 2026/10/30(8 天前);至今共发布 20 个版本,其中过去 12 个月发布了 20 个;首次发布于 2026/08/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。