proxy 本身不提供回滚或审计能力,但可作为统一钩子,在 set/deleteproperty 中触发快照、比对与日志;需结合外部系统实现持久化、权限校验与通知闭环。

用 Proxy 拦截模型变更,本身不直接提供回滚或审计能力,但它是构建这两项能力的理想“钩子”。关键不是让 Proxy 自己存历史或写日志,而是把它作为统一入口,在 set 和 deleteProperty 等陷阱中触发状态快照、变更比对与日志落库动作。
一、在 set 里捕获变更并生成审计日志
每次字段赋值前,先记录原始值、目标字段路径、操作时间、调用上下文(如可传入 traceId),再执行赋值。日志结构建议含:field(如 "user.profile.phone")、oldValue、newValue、timestamp、operator(可从调用栈或外部注入)。
- 若字段支持点号路径(如 "order.items[0].price"),需在 set 中解析路径并递归访问原值,避免浅层取值错误
- 日志可同步推送到前端控制台用于调试,异步写入后端 audit_log 表(类似数据库触发器逻辑,但前置到应用层)
- 不建议在 Proxy 内部直接发 HTTP 请求;应通过回调函数或事件总线(如 emit('audit', log))解耦
二、为每次变更保存“前镜像”,支撑自动回滚
回滚的前提是知道“变之前什么样”。可在首次访问字段时懒加载快照,或在每次成功 set 后,将变更前的完整路径值深拷贝存入一个 _snapshots Map 中,键为字段路径,值为 { value, timestamp }。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 回滚单字段:调用 rollback('user.email') → 查 _snapshots['user.email'] → 恢复值 → 清除该条快照
- 回滚整组:如表单提交失败,调用 rollbackAll() → 遍历所有已记录路径,按顺序还原 → 清空快照池
- 注意避免循环引用导致深拷贝失败,可用 structuredClone 或第三方 safe-clone 工具
三、结合 schema 实现语义化回滚约束
不是所有字段都允许任意回滚。例如库存字段被扣减后,若业务规则禁止“加回”,则应在 set 时检查 schema 中是否标记了 immutableAfterSet: true 或 rollbackPolicy: 'deny' | 'confirm' | 'auto'。
- schema 可定义字段级回滚策略,比如 status 字段只允许从 'draft' → 'published',反向回滚需人工确认
- 在 rollback 方法中校验策略,不符合则拒绝执行并返回 reason
- 把策略和审计日志关联,形成“谁在何时因何策略允许/拒绝了哪次回滚”的可追溯链
四、与外部系统协同,补齐能力闭环
Proxy 层负责感知和驱动,但持久化、通知、权限校验等应交由上层协作:
- 审计日志最终落库走标准 service 层,带事务保障,避免日志写一半失败
- 回滚操作需校验用户权限(如只有管理员可 rollback 'payment.amount'),Proxy 只传递意图,不越权决策
- 可对接消息队列,将关键变更广播给监控系统或告警服务,实现“改一笔,全链路感知”










