# Direct HTTP: get_workitem_brief 响应解析

当在 Python 直连脚本中调用 `get_workitem_brief` 时，响应结构和解析细节。

## 响应结构

`tools/call` 返回的 `content[0].text` 是 JSON 字符串，尾部带 `\nlog_id:...`。**必须先 strip log_id 行再 `json.loads`**：

```python
import re, json

def strip_log_id(text):
    return re.sub(r'\nlog_id:.*$', '', text.strip()).strip()

def parse_get_workitem_brief(text):
    data = json.loads(strip_log_id(text))
    # data 可能是 {"work_item_attribute": {...}} 直接结构
    # 也可能是 {"result": "<内层JSON字符串>"} 需要二次 loads
    if "result" in data and isinstance(data["result"], str):
        return json.loads(strip_log_id(data["result"]))
    return data
```

## role_members 结构（⚠️ 是 ARRAY，不是 dict）

```json
{
  "work_item_attribute": {
    "role_members": [
      {
        "key": "role_7dd6e0",
        "name": "销售员",
        "members": [
          {"key": "7376312715784011779", "name": "路要峰", "email": "luyaofeng@biori.com"}
        ]
      },
      {"key": "role_02e92d", "name": "客户-协作人"},
      {"key": "role_00a9b7", "name": "下单人", "members": [...]}
    ]
  }
}
```

**正确提取销售员**：
```python
attr = data.get("work_item_attribute", data)
for role in attr.get("role_members", []):
    if role.get("key") == "role_7dd6e0":
        members = role.get("members", [])
        if members:
            salesperson = members[0].get("name")
        break
```

**❌ 错误写法**（血泪教训）：
```python
# role_members 不是 dict！不能按 key 取值
role_members = result.get("role_members", {})  # ← type mismatch
sp = role_members.get("role_7dd6e0", [{}])[0].get("name")  # ← KeyError
```

## 所有角色 key 参考

| key | name | 说明 |
|-----|------|------|
| `role_7dd6e0` | 销售员 | KPI归属 |
| `role_00a9b7` | 下单人 | 实际下单操作人 |
| `role_02e92d` | 客户-协作人 | |
| `role_5ee38b` | 技术支持 | |
| `role_9d3509` | 客户-所属人 | |

## 完整调用示例

```python
def get_salesperson(work_item_id, project_key, sid):
    resp, sid = rpc({
        "jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": {"name": "get_workitem_brief",
                   "arguments": {"project_key": project_key,
                                "work_item_id": work_item_id}}
    }, sid)
    
    if "error" in resp:
        return None, sid
    
    for c in resp["result"]["content"]:
        t = c.get("text", "")
        if not t.strip(): continue
        
        data = parse_get_workitem_brief(t)  # 含 log_id 清理
        attr = data.get("work_item_attribute", data)
        
        for role in attr.get("role_members", []):
            if role.get("key") == "role_7dd6e0":
                members = role.get("members", [])
                return members[0].get("name", "") if members else "", sid
        return "", sid  # 找到了但没有销售员角色
    
    return None, sid
```
