# 工單要兩項技能，誰可以接？

先對技能、可接狀態及空位，逐位看哪些同事符合今張工單。

## 所需技能要全部符合

這份假設接收台記錄中，T1 要 cantonese 及 exports 兩項技能。各項技能齊、狀態為 active 且尚有空位，才可接單。狀態只屬本例，不是員工出勤記錄。null 表示未知；只要已有一項明確不符，即使另一項未明，也不能列為合資格。

T1 已填同事對照表

| 同事 | 已記技能 | 狀態 | 空位 | 結果 |
| --- | --- | --- | --- | --- |
| A | cantonese, exports | active | 1 | 可接 |
| B | cantonese | active | 3 | 欠 exports |
| C | cantonese, exports | inactive | 2 | 目前不可接 |

## 逐項保留未符合原因

只有 A 可接。B 較多空位，卻欠 exports；C 技能齊，但目前不可接。結果只列合資格同事，不會自動派單。多人符合時，本模型也不替你選其中一位。

1. 查看工單所需技能
2. 逐位對已記技能
3. 核狀態及空位
4. 保留逐項判斷

技能記錄未明，不能當作同事一定會。

B 加上已記 exports 技能後，誰可接？

A、B 都可接；C 仍不可接。這個核對不會再選最後派給哪位。

## 改一項資料，再看名單

可勾選或取消 B 的 exports 技能，名單由 A 變 A、B，再回到 A。工單仍要兩項技能。「還原例子」會回復原來三位同事。

A 的技能未知時，A 列為待核；B、C 仍有明確不符原因。輸入最多 30 個不同編號，技能字樣非空且不重複，空位用 0 至 1,000 整數或 null。資料無效便拒絕整次核對，不派出半份結果。

名單意外沒有同事時，可接着看渠道空位例子。工單的影響優先程度仍另行判斷。

## 完整本地記錄與逐項結果

```json
{
  "issuer": "Astera Technology",
  "resource": "ops-route-required-capabilities",
  "locale": "zh-HK",
  "contract": "這份假設接收台記錄中，T1 要 cantonese 及 exports 兩項技能。各項技能齊、狀態為 active 且尚有空位，才可接單。狀態只屬本例，不是員工出勤記錄。null 表示未知；只要已有一項明確不符，即使另一項未明，也不能列為合資格。",
  "input": {
    "required": [
      "cantonese",
      "exports"
    ],
    "agents": [
      {
        "id": "A",
        "skills": [
          "cantonese",
          "exports"
        ],
        "status": "active",
        "spare": 1
      },
      {
        "id": "B",
        "skills": [
          "cantonese"
        ],
        "status": "active",
        "spare": 3
      },
      {
        "id": "C",
        "skills": [
          "cantonese",
          "exports"
        ],
        "status": "inactive",
        "spare": 2
      }
    ]
  },
  "output": {
    "ok": true,
    "state": "complete",
    "result": {
      "eligible": [
        "A"
      ],
      "unknown": []
    },
    "trace": [
      {
        "id": "A",
        "skills": true,
        "available": true,
        "spare": true,
        "remaining": 1,
        "decision": "eligible"
      },
      {
        "id": "B",
        "skills": false,
        "available": true,
        "spare": true,
        "remaining": 3,
        "decision": "ineligible"
      },
      {
        "id": "C",
        "skills": true,
        "available": false,
        "spare": true,
        "remaining": 2,
        "decision": "ineligible"
      }
    ]
  },
  "verificationCases": [
    {
      "name": "baseline",
      "input": {
        "required": [
          "cantonese",
          "exports"
        ],
        "agents": [
          {
            "id": "A",
            "skills": [
              "cantonese",
              "exports"
            ],
            "status": "active",
            "spare": 1
          },
          {
            "id": "B",
            "skills": [
              "cantonese"
            ],
            "status": "active",
            "spare": 3
          },
          {
            "id": "C",
            "skills": [
              "cantonese",
              "exports"
            ],
            "status": "inactive",
            "spare": 2
          }
        ]
      },
      "expected": {
        "ok": true,
        "state": "complete",
        "result": {
          "eligible": [
            "A"
          ],
          "unknown": []
        }
      }
    },
    {
      "name": "material-edit",
      "input": {
        "required": [
          "cantonese",
          "exports"
        ],
        "agents": [
          {
            "id": "A",
            "skills": [
              "cantonese",
              "exports"
            ],
            "status": "active",
            "spare": 1
          },
          {
            "id": "B",
            "skills": [
              "cantonese",
              "exports"
            ],
            "status": "active",
            "spare": 3
          },
          {
            "id": "C",
            "skills": [
              "cantonese",
              "exports"
            ],
            "status": "inactive",
            "spare": 2
          }
        ]
      },
      "expected": {
        "ok": true,
        "state": "complete",
        "result": {
          "eligible": [
            "A",
            "B"
          ],
          "unknown": []
        }
      }
    },
    {
      "name": "fresh-boundary",
      "input": {
        "required": [
          "cantonese",
          "exports"
        ],
        "agents": [
          {
            "id": "A",
            "skills": null,
            "status": "active",
            "spare": 1
          },
          {
            "id": "B",
            "skills": [
              "cantonese"
            ],
            "status": "active",
            "spare": 3
          },
          {
            "id": "C",
            "skills": [
              "cantonese",
              "exports"
            ],
            "status": "inactive",
            "spare": 2
          }
        ]
      },
      "expected": {
        "ok": true,
        "state": "unknown",
        "result": {
          "eligible": [],
          "unknown": [
            "A"
          ]
        }
      }
    }
  ],
  "meaningOfNull": "該欄位未知或沒有已建立的值；請按逐項結果判斷。",
  "businessSideEffects": false
}
```
