Files
ccdi/lsfx-mock-server/docs/plans/2026-03-04-inner-flow-response-design.md

6.1 KiB
Raw Blame History

设计文档:修改拉取行内流水接口返回值

日期: 2026-03-04 状态: 已批准 作者: Claude Code

1. 概述和目标

目标

修改 /watson/api/project/getJZFileOrZjrcuFile 接口的返回格式,从当前的错误格式改为返回 logId 数组。

当前实现

{
    "code": "200",
    "data": {"code": "501014", "message": "无行内流水文件"},
    "status": "200",
    "successResponse": true
}

修改后实现

成功场景:

{
    "code": "200",
    "data": [19154],
    "status": "200",
    "successResponse": true
}

错误场景(通过 error_501014 标记触发):

{
    "code": "501014",
    "message": "无行内流水文件",
    "status": "501014",
    "successResponse": false
}

关键特性

  • logId 通过随机数生成范围10000-99999
  • 独立简化管理,不存储到 file_records,不支持后续操作
  • 保留错误模拟功能(通过 error_XXXX 标记触发)

2. 技术实现

修改文件

  • services/file_service.py - 修改 fetch_inner_flow() 方法

具体实现

FileService 类中修改 fetch_inner_flow() 方法:

def fetch_inner_flow(self, request: Union[Dict, object]) -> Dict:
    """拉取行内流水返回随机logId

    Args:
        request: 拉取流水请求(可以是字典或对象)

    Returns:
        流水响应字典包含随机生成的logId数组
    """
    import random

    # 随机生成一个logId范围10000-99999
    log_id = random.randint(10000, 99999)

    # 返回成功的响应包含logId数组
    return {
        "code": "200",
        "data": [log_id],
        "status": "200",
        "successResponse": True,
    }

关键变化

  1. 移除原来的"无行内流水文件"硬编码错误响应
  2. 使用 random.randint(10000, 99999) 生成随机 logId
  3. 返回格式改为 {"code": "200", "data": [log_id], ...}
  4. import random 放在方法内部,避免顶层导入(保持简单)

无需修改的部分

  • routers/api.py - 错误检测逻辑保持不变
  • utils/error_simulator.py - 错误码定义已包含 501014
  • config/settings.py - 无需新增配置

3. 测试计划

测试文件

  • tests/test_api.py

新增测试用例

3.1 测试成功场景

def test_fetch_inner_flow_success(client, sample_inner_flow_request):
    """测试拉取行内流水 - 成功场景"""
    response = client.post(
        "/watson/api/project/getJZFileOrZjrcuFile",
        data=sample_inner_flow_request
    )
    assert response.status_code == 200
    data = response.json()
    assert data["code"] == "200"
    assert data["successResponse"] == True
    assert isinstance(data["data"], list)
    assert len(data["data"]) == 1
    assert isinstance(data["data"][0], int)
    assert 10000 <= data["data"][0] <= 99999

3.2 测试错误场景

def test_fetch_inner_flow_error_501014(client):
    """测试拉取行内流水 - 错误场景 501014"""
    request_data = {
        "groupId": 1001,
        "customerNo": "test_error_501014",
        "dataChannelCode": "test_code",
        "requestDateId": 20240101,
        "dataStartDateId": 20240101,
        "dataEndDateId": 20240131,
        "uploadUserId": 902001,
    }
    response = client.post(
        "/watson/api/project/getJZFileOrZjrcuFile",
        data=request_data
    )
    assert response.status_code == 200
    data = response.json()
    assert data["code"] == "501014"
    assert data["successResponse"] == False

测试命令

# 运行所有行内流水相关测试
pytest tests/test_api.py -k "fetch_inner_flow" -v

# 运行单个测试
pytest tests/test_api.py::test_fetch_inner_flow_success -v
pytest tests/test_api.py::test_fetch_inner_flow_error_501014 -v

4. 文档更新

4.1 README.md

更新接口说明部分,将"模拟无数据场景"改为"返回随机logId"。

4.2 CLAUDE.md

在架构设计部分补充说明行内流水接口的特殊性:

  • 简化管理(不存储到 file_records
  • 随机 logId无需持久化
  • 无后续操作支持(无需解析状态检查)

5. 设计决策

为什么选择随机生成 logId

  • 简化管理:行内流水拉取是独立的简化流程,不需要与文件上传共用复杂的状态管理
  • 无需持久化logId 仅用于返回,不需要存储或后续查询
  • 测试友好:每次调用返回不同的值,避免固定值导致的测试假阳性

为什么不使用配置文件?

  • 响应数据需要运行时动态生成(随机 logId
  • 配置文件适合静态或模板化的响应,不适合需要随机值的场景
  • 保持代码简单直接,避免过度设计

为什么保留错误模拟?

  • Mock 服务器的核心功能之一是模拟各种场景
  • 501014 错误是真实的业务场景(无行内流水文件)
  • 通过 error_XXXX 标记触发错误,与项目整体设计一致

6. 影响范围

直接影响

  • services/file_service.py - 修改 1 个方法
  • tests/test_api.py - 新增/修改测试用例

间接影响

  • API 文档自动更新FastAPI Swagger UI
  • README.md 需要更新示例

无影响

  • 其他 6 个接口的返回格式
  • 错误模拟机制
  • 前端集成(假设前端已按新格式设计)

7. 风险和限制

风险

  • logId 冲突:理论上可能生成重复的 logId但由于不存储不会造成实际问题
  • 前端兼容性:如果前端已按旧格式实现,需要协调更新

限制

  • 不支持后续的解析状态检查
  • 不支持通过 logId 查询流水数据
  • 不支持删除操作

这些限制是设计决策的一部分,符合"简化管理"的目标。

8. 验收标准

  • 修改后接口返回正确的格式(包含 logId 数组)
  • logId 在指定范围内10000-99999
  • 错误模拟功能正常工作
  • 所有测试用例通过
  • 文档已更新
  • 代码通过 pytest 测试

9. 时间线

预计实施时间30 分钟

  • 代码修改10 分钟
  • 测试编写和验证15 分钟
  • 文档更新5 分钟