compliance/docs/Correct_Multi_Key_Delete_Logic.md
2025-08-07 22:44:57 +08:00

6.1 KiB
Raw Blame History

正确的多主键删除逻辑实现

🎯 问题分析

您指出了一个关键问题:我之前的实现逻辑是错误的。

错误的逻辑(之前)

基于schema的items.type判断
- items.type == "string" → 单主键(字符串数组)
- items.type == "object" → 多主键(对象数组)

正确的逻辑(现在)

基于identityId列表长度判断
- len(identityId) == 1 → 单主键(字符串数组)
- len(identityId) > 1 → 多主键(对象数组)

🔧 实现修正

1. DMSEndpoint增强

添加了identity_id_list属性来存储完整的identityId配置

class DMSEndpoint(BaseEndpoint):
    def __init__(self, ..., identity_id_list: Optional[List[str]] = None):
        # ...
        self.identity_id_list = identity_id_list or []

2. DMS API解析增强

在解析DMS API时根据identityId长度自动生成正确的删除schema

# 获取identityId列表
identity_id_list = model.get("identityId")

if isinstance(identity_id_list, list) and len(identity_id_list) > 1:
    # 多主键生成对象数组schema
    delete_request_body_schema = {
        "type": "object",
        "properties": {
            "version": {"type": "string"},
            "data": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {pk1: schema1, pk2: schema2, ...},
                    "required": [pk1, pk2, ...]
                }
            }
        }
    }
else:
    # 单主键生成字符串数组schema
    delete_request_body_schema = {
        "type": "object",
        "properties": {
            "data": {
                "type": "array",
                "items": {"type": "string"}
            }
        }
    }

3. CRUD Stage逻辑修正

删除请求体构建现在直接基于identityId列表

def _build_delete_request_body(self, scenario, pk_name, pk_value, create_payload):
    delete_op = scenario.get('delete')
    identity_id_list = getattr(delete_op, 'identity_id_list', [])
    
    if len(identity_id_list) > 1:
        # 多主键:使用对象列表
        return self._build_multi_key_delete_body(identity_id_list, pk_name, pk_value, create_payload)
    else:
        # 单主键:使用字符串列表
        return {"data": [pk_value]}

📊 支持的配置和格式

配置示例

单主键配置

{
  "identityId": ["proppantId"]
}

生成的删除格式

{
  "data": ["proppant_001", "proppant_002"]
}

双主键配置

{
  "identityId": ["projectId", "surveyId"]
}

生成的删除格式

{
  "version": "1.0.0",
  "data": [
    {"projectId": "项目1_ID", "surveyId": "工区1_ID"},
    {"projectId": "项目2_ID", "surveyId": "工区2_ID"}
  ]
}

三主键配置

{
  "identityId": ["wellId", "layerId", "sampleId"]
}

生成的删除格式

{
  "version": "1.0.0",
  "data": [
    {"wellId": "井001", "layerId": "层001", "sampleId": "样本001"},
    {"wellId": "井002", "layerId": "层002", "sampleId": "样本002"}
  ]
}

🎯 核心改进

1. 准确的业务逻辑

  • 直接基于DMS的identityId配置
  • 不再依赖schema结构推测
  • 准确反映业务意图

2. 自动schema生成

  • 解析器根据identityId自动生成正确的删除schema
  • 单主键自动生成字符串数组schema
  • 多主键自动生成对象数组schema

3. 智能字段处理

  • 从创建负载中自动提取相关主键
  • 为缺失的主键字段生成默认值
  • 支持批量删除(生成多个对象)

4. 优雅回退

  • 当identityId为空时回退到简单格式
  • 确保删除操作始终可以执行

🔄 工作流程

1. DMS API解析
   ↓
2. 读取identityId配置
   ↓
3. 判断主键数量
   ├─ len(identityId) == 1 → 生成字符串数组schema
   └─ len(identityId) > 1 → 生成对象数组schema
   ↓
4. 创建DMSEndpoint包含identity_id_list
   ↓
5. CRUD Stage执行
   ↓
6. 根据identity_id_list长度构建删除请求体
   ├─ 单主键 → {"data": ["key1", "key2"]}
   └─ 多主键 → {"version": "1.0.0", "data": [{"key1": "val1", "key2": "val2"}]}

📝 测试验证

所有测试场景均通过:

  • 单主键删除identityId长度=1
  • 多主键删除identityId长度=2
  • 三主键删除identityId长度=3
  • 空identityId回退处理
  • 缺失字段自动生成

💡 使用示例

DMS配置

{
  "name": "projectSurvey",
  "model": {
    "identityId": ["projectId", "surveyId"],
    "properties": {
      "projectId": {"type": "string"},
      "surveyId": {"type": "string"},
      "relationName": {"type": "string"}
    }
  }
}

自动生成的删除端点

{
  "path": "/api/dms/test/v1/projectSurvey",
  "method": "DELETE",
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "properties": {
            "version": {"type": "string"},
            "data": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "projectId": {"type": "string"},
                  "surveyId": {"type": "string"}
                },
                "required": ["projectId", "surveyId"]
              }
            }
          }
        }
      }
    }
  }
}

生成的删除请求

{
  "version": "1.0.0",
  "data": [
    {"projectId": "项目1_ID", "surveyId": "工区1_ID"},
    {"projectId": "项目1_ID", "surveyId": "工区2_ID"}
  ]
}

🎉 总结

通过这次修正DMS合规性测试工具现在能够

  1. 正确理解业务配置基于identityId而不是schema推测
  2. 自动生成正确格式:单主键用字符串数组,多主键用对象数组
  3. 支持任意主键组合1个、2个、3个或更多主键
  4. 智能处理缺失字段:自动生成默认值
  5. 提供批量删除支持:生成多个删除对象

这确保了测试数据完全符合DMS系统的实际业务规则和API设计