核心经营系统概览

规则、权限、口径存成带版本的数据,单据的判定、写入与留痕走同一套入口

核心经营系统管一笔单据从进入到留痕的全过程,也是 AI 接进经营要先打好的底子。它先把规则、权限和统计口径存成带版本的数据,一笔单据当时怎么判的、一条规则谁改的,事后都查得到。模型缺省关闭,开启后起草的每一步都走同一套权限、审批和留痕,所以 AI 能经手涉及钱的单据,又不会越过任何一道关。制度还没成文,或业务量小到靠人盯得住时,这套系统的收益抵不上搭建成本。

一笔单据怎样走

一笔单据从进入到留痕

图里只有「取规则并建单」一步,把当时命中的规则行冻进了单据;其余各步在各自的位置留下可查的数据。

步做什么细节
准入判定授权入口回答「这个人能不能做这个动作」,拒绝行先于允许行,没有命中就拒绝谁能做什么
取规则并建单按单型与时点取金额档位行,把命中的那一行快照写进单据审批流转
签核谁能签由签核位与资格决定,状态转移由一支纯函数判定审批流转
终局写业务批准之后,执行业务写入,资金流水只追加资金流水与更正
追加留痕每条写入命令追加一条审计事件,事件之间用哈希串成链留痕与证据链

纯函数指同样的输入得到同样的输出,不读外部状态。哈希链指每条记录带着前一条的指纹,中间抽掉一条,校验时序号对不上。

因为档位行是建单时的快照,之后规则怎么改,已建的单都不回头变。审计拿出一张旧单,看到的是建单那天的规则,旧单也能按当时的判据重放。

查一笔单据,沿图里的步骤逐个核对,每一步都有对应的记录。

模型起草的单据也走同样的步骤,没有为模型另开的通道。它的输出只能成为待审批的草案,经过权限、审批、留痕才写入业务。

工作台总览。右下「判定轨迹」把 A-1024 的各步排成一列:读取单据、流水核对、命中 R-07 · v3、财务复核进行中、归档未开始 · 演示数据
示意 · 演示数据工作台总览。右下「判定轨迹」把 A-1024 的各步排成一列:读取单据、流水核对、命中 R-07 · v3、财务复核进行中、归档未开始 · 演示数据

图里命中的规则带着版本号 v3,这就是建单时冻进单据的那一行;复核停在待签,系统只记停留时长,不替人批准。

版本记在各处

一份规则「每次改动都有版本」,这句话对,但版本不止一处。

版本落在哪回答什么
规则行版本规则表每一行,每次变更自增,旧行保留这条规则改过几次,谁改的、为什么改
签法版本与档位快照审批单这张单按哪一版审批链、哪一档金额线走
口径版本口径定义表报表上这个数按哪一版算法算出
权限集版本号会话快照这个会话按哪一版权限判定
投影版本模型调用留痕这次调用送进模型的字段是哪一版

要回答「这笔单据当时依据什么」,得按单据的类型去对应的一处查,没有一个全局版本号能一句话答完。各类规则按各自的节奏改,版本也各记各的。

技术选型

核心经营系统用通用、成熟的组件搭成。下表只写会影响判断的取舍。

层选择这一层承担什么代价或限制
数据库PostgreSQL 16,手写 SQL,不用 ORM,只启用 pgcrypto 一个扩展规则与闸放在应用绕不过的一层:约束、触发器、行级隔离、定义者函数、窄权限角色一部分判定逻辑写在 SQL 里;库内与应用内各有一份解释器时,要逐键对拍
服务端Node.js,用 node:http 自建服务,不用 Web 框架判定写成纯函数,形状靠契约校验与真库用例保证路由自己维护
前端React 18、Vite 5、TypeScript;表格用 TanStack Table,图表用 ECharts现场有较老的浏览器,构建目标钉到较老的内核;ECharts 自托管,页面只加载本站脚本可用的新特性受构建目标限制
契约zod 定义,导出 JSON Schema入参与出参的格式只定义一次:前端读 zod 的类型,服务端读 JSON Schema 做运行时校验契约包是两端的共同依赖,改契约两端一起动
库结构变更自写:顺序 SQL 文件、依赖序清单、台账回滚只回代码,所以库结构变更一律只加不改;待执行的结构变更脚本是清单与台账的差集;克隆库重放两遍,第二遍零变动工具自己维护,细节见发布与回滚
大模型自写网关,缺省关闭,不引入模型 SDK进入模型的字段走白名单,输出按契约校验,每次调用留痕,失败回退规则文本依赖少,功能也比成品网关少,见接入模型服务
测试后端 node:test;数据库用例连一次性的真 PostgreSQL 实例数据库里的触发器、行级隔离、定义者函数,靠真库用例验证全量数据库用例需要能起一次性实例的环境

表中 Web 框架、ORM、测试运行器这三项只写它们承担的职责。

触发器是数据库在写入时自动执行的检查。行级隔离是数据库按会话里的租户过滤能看到的行。定义者函数是以函数所有者的权限执行的写入入口,业务角色不能直接写表,只能调它。

核对每一层放什么、规则改在哪,对着这张表即可;每行右侧的代价,就是可以追问的地方。

限制与不适用

  • 规则与约束放进 PostgreSQL,数据库成了系统的核心,换库要重写判定。
  • 新增一种判据要发版,判据种类在代码里。
  • 没有全局统一的规则集版本号,「依据」分散在几处。
  • 备份恢复指标与密钥管理这里不给,按企业要求在合同中约定。
  • 制度还没成文、业务量小到靠人盯得住时,搭这套系统的收益抵不上成本。

与常见做法对照

约束放在哪一层,决定谁能绕过它。

放法谁能绕过代价
应用代码不经过这段代码的连接判据易在多处各有一份
独立的策略引擎,如 OPA不经引擎直接访问数据的路径多一个进程,多一门策略语言
数据库内的约束与行级隔离(SZV)表属主、超级用户,以及带 BYPASSRLS 属性的角色判定逻辑与数据库绑得更紧

PostgreSQL 文档写明,表属主通常不受行级安全约束,除非对表设了 FORCE ROW LEVEL SECURITY;超级用户和带 BYPASSRLS 的角色始终绕过。「应用之外的连接也要过闸」只在应用用普通角色连库时成立,它防的是代码漏写条件,不防数据库管理员。

其他做法

做法它解决什么为什么不用
规则与约束写在应用代码里开发快,数据库可以换应用之外的连接不经过它;同一判据在库与应用各有一份时,两份会漂。SZV 把规则与闸放进库,另用代码扫描拦截业务代码里的第二份判断
回滚时连库一起回版本与数据结构保持一致库里已有新数据时,回库会丢数据;每份库结构变更还要再写一份回退脚本并测试。SZV 只回代码,库结构变更因此一律只加不改

扫描是启发式的,拦得住照抄的判断,证明不了语义上只剩一份。

本章各页

页回答的问题
审批流转一张单按哪一版链走,没人签时系统怎么办
修改一条规则改一条规则要经过哪几步
配置一个人的权限一个人的能力由哪几层叠加
资金流水与更正更正怎样不改旧行,核对怎样做
客户资料与统计口径来源资料保留,报表怎样只算一次
查询与导出操作记录怎样查整条经过,导出怎样限时
接入模型服务网关、名册与开关
发布与回滚上线出问题,怎样只回代码

验收时可以问的问题

  • 生产备份的恢复点与恢复时间,在合同里怎样约定。
  • 密钥由谁管理、怎样轮换,在合同里怎样约定。

相关页

这页有帮助吗谢谢,我们会据此改进这一页。

需要帮助?联系我们

想先知道我们怎么想?关于 SZV

联系我们

企业人员规模(人)

试用工作台