数据合规性检查案例
1.问题描述
1.1 数据验证的意义
规则引擎可以在数据验证和清洗场景中使用,通过使用规则来验证数据的有效性和一致性,具体如下:
- 数据格式验证:验证数据是否符合特定的格式要求,如邮件地址、电话号码等。
- 数据范围验证:验证数据是否在允许的范围内,如年龄范围、工资范围等。
- 数据一致性验证:验证不同数据项之间的一致性,如邮寄地址和邮编号码的一致性等。
总之,数据验证是确保用户输入数据的有效性和正确性的重要手段,可以使用户提交的数据更加准确可靠,同时提高系统的可用性和安全性。
1.2 表单数据验证常用的几种方式
客户端验证
这种验证方式在用户提交表单之前,先在客户端进行验证。客户端验证的优势在于能够即时发现并纠正用户的输入问题,提高用户体验,它通常使用JavaScript或jQuery等前端技术实现。
这种验证方式针对表单中的每个元素进行验证,包括必填项、长度、格式、类型等。表单元素验证可以提高表单的可用性和用户体验,同时可以减少用户输入错误的可能性。
服务端验证
这种验证方式在用户提交表单后,由服务端进行验证。服务端验证可以防止恶意用户绕过前端验证,确保数据的完整性和安全性。它通常使用后端编程语言如PHP、Java或Python等实现。
数据库验证
这种验证方式在数据存储到数据库之前,对数据进行验证。数据库验证可以确保数据的有效性和一致性,同时可以防止恶意用户绕过前端和后端验证,它通常使用数据库查询语句实现。
总之,做好数据验证工作,可极大地提升数据质量。
2.架构与设计
2.1 架构
应用间交互图
说明
- 推荐采用以上系统间交互方式,通过网关来与规则引擎交互,可能更适应于当前市场主流的微服务体系
- 将鉴权、流控、熔断等都集中在应用服务网关上完成,从而保护规则引擎服务器
- 由于,规则引擎的输入接口数据格式比较特殊,可能需要在应用服务网关转换,以更加适配于目标开发团队现有的技术栈和接口交互标准
规则项目关系图
说明
- 规则项目类型有2种,公共项目和普通项目,我们的uRule产品支持项目间的引用和共享,允许在普通项目中调用公共项目中的规则文件
- 在新建规则时,将本单位的输入规则进行提练,将比较常用的、通用的规则编写在【公共项目】中,然后在【普通项目】中进行引用,按需组合规则并向自己的业务应用系统提供验证服务
2.2 数据较验流程
2.3 设计
用户本地维护的规则编号表
自定义全局编码 | 知识包id | 较验规则说明 |
---|---|---|
CK_USERNAME | 301 | 用户名较验 |
CK_USEREMAIL | 302 | 用户邮箱较验 |
- 开发者自建的对照关系表,即能展示本地特色、方便开发者在前端应用界面中记忆等,又可以与uRule解耦,在迁移项目时知识包id可能会重新编号,出现不能匹配到的问题
- 自建的对照表可以作为组织的知识库公开显示和查询,更能提升工作效率
前端在调用时,输入数据问题
- 规则码如上图所示,标记着调用那个知识包
- 输入数据格式需要抽象,并保持全域(所有的消费方)一致性,方可多路复用,兼容多种复杂的场景
- 输入参数可能是个List集合或者是Map,但不能是个java对象(BOM),可能会涉及到多个表单要素间的组合性检查,输入对象的实例化(Map转换成BOM)应放在调用入口规则上
- 需要注意此处的字段名fieldName输入值来源于“数据字典”,全域公用的,规则引擎中会根据这个fieldName匹配规则算法
{
"ckId":"CK_001",
"inputData":[
{
"fieldName":"myName",
"fieldValue":"张三"
},
{
"fieldName":"myCerKind",
"fieldValue":"1"
},
{
"fieldName":"myCerCode",
"fieldValue":"420322xxxxxxxxxxxx"
}
]
}
{
"ckId":"CK_002",
"inputMap":
{
"custName":"张三丰",
"custCerType":"2",
"custCerCode":"123456789"
}
}
返回到前端的数据,标准结构
{
"resultCode":"200",
"resultMsg":"较验通过"
}
{
"resultCode":"999",
"resultMsg":"较验未通过",
"data":[
{"checkMsg":"不满足最小长度","checkCode":"0","checkFieldName":"myName"},
{"checkCode":"1","checkFieldName":"myCerKind"},
{"checkMsg":"证件号不满足行业规范要求","checkCode":"0","checkFieldName":"myCerCode"}
]
}
3.示例程序
3.1 业务需求
3.1.1 技术要求
- 实现对客户信息的输入项合规性较验,在业务场景发生变更时,能及时调整数据的较验规则,生产系统能及时变更生效,无需走繁杂的项目变更发版流程
- 本单位各业务系统的具有相同业务含义的要素,原则上执行同一套输入标准,以保证数据的完整性和一致性
3.1.2 业务规则
- 客户姓名:元素值是一个长度在[4, 120]区间内的字符串
- 客户证件类型:元素值是一个整型数值,取值范围[1,2] ,身份证和户口本
- 客户证件号码:当证件类型是1-身份证时其长度是18位字符串,而且是一个合法的有效的身份证号码;当证件类型是2-户口本时其长度是9位字符串
3.2 uRule规则引擎实现过程
3.2.1 新建项目
- 新建2个规则项目:公共项目和普通项目
- 在公共项目中编写【客户姓名较验规则】【客户证件类型较验规则】【客户证件号较验规则】
3.2.2 公共规则库项目
3.2.2.1 库文件
变量库(BOM)
- 客户信息
- 输出BOM
- 输入BOM
参数库
- 公共参数库
- 其它参数库
3.2.2.2 客户姓名较验规则
3.2.2.3 客户证件类型较验规则
注意:本示例只允许1-身份证,2-户口本这两种类型
3.2.2.4 客户证件号较验规则
- 户口本号码规则
- 身份证号规则,算法有点复杂,涉及到多个规则文件
- 身份证号较验算法明细
- 以下是身份证号较验算法所需要的转换关系表,在上述规则中有调用
3.2.3 数据分析项目(普通规则项目)
3.2.3.1 客户三要素较验规则
注意:
- 在此规则中需要导入【公共项目】的参数库,也会直接调用公共项目中的规则文件
- 根据输入的【字段名】动态匹配相应的规则执行组,也可以增加一个输入项“规则名”来匹配规则的
- 将输入的Map转换成【变量】对象,方便后续的规则较验逻辑的输入
3.2.3.2 定义公共动作模板
说明:将常用的赋值语句分组定义在动作模板库中,以达到抽象和快速引用目的,提高规则编写效率和可读性;例如上述的规则中就出现了【动作模板:数据较验返回值赋值动作】,二者遥向呼应
3.2.3.3 创建知识包
- 创建知识包
- Rest服务测试
3.2.4 示例项目(普通规则项目)
3.2.4.1 客户姓名较验规则
注意:将输入Map转换成【客户信息】对象
3.2.4.2 创建知识包
- 创建知识包
- Rest服务测试
3.3 测试
3.3.1 在postMan工具中模拟消费方
3.3.1.1 客户三要素较验测试
3.3.1.2 客户姓名较验测试
- 输入数据
[
{
"name": "参数",
"fields": {
"inputMap": {
"custName": "张"
}
},
"class": "java.util.HashMap"
}
]
- 输出数据
{
"output": [
{
"参数": {
"outList": [
{
"checkMsg": "客户姓名违反业务规则:张",
"checkFieldName": "custName",
"checkCode": "0"
}
]
}
}
],
"duration": 6
}
3.3.2 在某个消费方业务系统模拟
3.3.2.1 编写消费方后端api接口
3.3.2.2 验证‘客户姓名合规性’
(1)前端页面代码
(2)测试用例
- 前端输入空值,较验未通过
- 前端输入【张三丰】较验通过
- 前端输入【1234】较验不通过
- 消费方控制台打印日志
3.3.2.3 验证‘客户三要素合规性’
(1)编写前端页面代码
(2)测试用例
- 输入空值,较验不通过
- 输入合规的三要素,验收通过
- 输入不合规的要素值,较验不通过
- 消费方控制台打印日志
3.4 小结
- 规则设计时,只有要确保入口规则数据结构的通用性,才能保证消费方在java端调用规则代码的兼容性,通过【知识包id】和【输入参数】自动触发对应的规则,输入参数结构是固定不变的,与你要调用的规则文件一一对应。
- 规则设计时,若遇到比较复杂的规则,我们通常会声明变量(BOM)在多个规则文件中传递,以提升可读性和便捷性;那么,在入口规则处就得对象实例化,出应当做好入参的检查工作。
- 前端页面在调用规则时,输入参数至少包括该规则文件中要用到的元素值,通常在你的团队开发规范中,会要求每个规则接口的输入和输出都有一个api说明文档。