---
name: IoT 通訊與高併發處理規範
description: 規範智能販賣機與 Cloud 平台間的高頻通訊處理流程，包含 API 接收、異步隊列、業務邏輯拆分與日誌記錄。
---

# IoT 通訊與高併發處理規範 (IoT Communication Skill)

本規範確保 Star-Cloud 系統在處理成千上萬台機台的高頻發報時，能維持伺服器響應速度與資料一致性。

## 1. 處理管線 (Processing Pipeline)

所有來自機台的非即時性資料（日誌、心跳、狀態上報）必須遵循以下 pipeline。依據通訊協議不同，進入點有兩條路徑：

### 1.1 HTTP 管線 (低頻/大檔操作)
適用於 B000, B005, B009, B012, B014, B017, B018 等低頻、同步需求或大資料量的端點：
1.  **API Controller (接收層)**：驗證 Request 合法性，隨即分派 (Dispatch) 任務至 Queue，並回傳 `202 Accepted`。
2.  **Job (異步層)**：由背景 Worker 讀取隊列任務，呼叫對應 Service 處理。
3.  **Service (邏輯層)**：封裝商業邏輯，更新資料庫。
4.  **Model (儲存層)**：執行資料存取。

### 1.2 MQTT 管線 (高頻/即時操作)
適用於 `heartbeat` (心跳), `error` (異常), `transaction` (交易生命週期: `create`, `finalize` 等) 等高頻或即時性端點：
1.  **Go Gateway (接收層)**：訂閱 EMQX Topic，提取 `serial_no`，包裝成標準 JSON。
2.  **Redis List (橋接層)**：Go 執行 `RPUSH starcloud_database_mqtt_incoming_jobs {json}`。
3.  **Laravel `mqtt:listen` (消費層)**：常駐指令 `BLPOP` 取出 JSON，根據 `type` 分派至對應 Job。
4.  **Job ➜ Service ➜ Model**：與 HTTP 管線後半段相同。

> [!TIP]
> 兩條管線的 **Job / Service / Model 層完全共用**，差異僅在「進入點」。這確保了業務邏輯不會因為通訊協議不同而分裂。

> [!CAUTION]
> **Redis Key 前綴一致性**：Laravel 的 Redis 驅動會自動在 Key 前加上 `REDIS_PREFIX` (預設為 `star_cloud_database_`)。Go Gateway 不使用 Laravel Redis 客戶端，因此已透過讀取 `.env` 中的 `MQTT_REDIS_PREFIX` 來確保雙方前綴一致。另外，EMQX 認證使用 Redis Hash (`HSET`)，嚴禁使用 String (`SET`)。

> [!IMPORTANT]
> **嚴禁**在 API Controller 直接進行資料庫寫入操作（針對機台發訊端點）。

## 2. 異步任務實作範例

### 2.1 API Endpoint
```php
public function storeLog(Request $request, int $id): JsonResponse
{
    // 1. 驗證
    $data = $request->validate([...]);
    
    // 2. 異步分派
    ProcessMachineLog::dispatch($id, $data);
    
    // 3. 快速回應
    return $this->successResponse([], 'Accepted', 202);
}
```

### 2.2 Job 處理邏輯
Job 應保持單純，僅作為 Service 的觸發點：
```php
public function handle(MachineService $service): void
{
    $service->recordLog($this->machineId, $this->logData);
}
```

## 3. 隊列配置規範

- **連接驅動 (Driver)**：預設使用 `Redis` 以確保高併發吞吐量。
- **重試機制 (Retry)**：IoT 任務應設定合理的重試次數，避免因網路短暫波動遺失日誌。
- **失敗處理 (Failed Jobs)**：關鍵業務（如訂單同步）必須監控 `failed_jobs`。

## 4. 速率限制 (Rate Limiting)

### 4.1 HTTP 端點
- 所有的 IoT HTTP API 必須在 `routes/api.php` 中使用 `throttle:api` 或自定義 Middleware。
- 針對單一機台 ID 應限制其每一分鐘的最高連線數，防止遭受攻擊或機台 Bug 導致的連線暴衝。

### 4.2 MQTT 端點
- 限速由 **EMQX Broker** 的 Rate Limiting 功能負責（非 Laravel Middleware）。
- Go Gateway 層可額外實作簡易的 Token Bucket，當某台機台每秒超過閾值時丟棄訊息並記錄 Warning Log。

## 5. 檢核項目 (Checklist)
- [ ] 是否使用了 `ApiResponse` Trait？
- [ ] 業務邏輯是否已封裝至 `App\Services`？
- [ ] 是否使用了 Redis Queue 進行非同步處理？

## 6. API 規格定義 (API Specifications)

> [!IMPORTANT]
> **規格分離原則**：本技能僅規範「通訊處理邏輯」。關於具體的欄位定義與資料格式，請參閱對應的專屬技能規範：
> - **HTTP 端點**：[API 技術規格與通訊協議規範](file:///home/mama/projects/star-cloud/.agents/skills/api-technical-specs/SKILL.md)
> - **MQTT 端點**：[MQTT 即時通訊與 Topic 規範](file:///home/mama/projects/star-cloud/.agents/skills/mqtt-communication-specs/SKILL.md)

### 常見端點處理模式
1.  **$SYS Events**：由 Broker 自動觸發，走 **MQTT 管線**。用於毫秒級更新機台的 `online/offline` 狀態與 `last_heartbeat_at`。
2.  **heartbeat (心跳)**：原 B010。高頻點，走 **MQTT 管線** (`machine/+/heartbeat`)。更新 `last_heartbeat_at` 與感測器快照。
3.  **error (異常)**：原 B013。事件驅動點，走 **MQTT 管線** (`machine/+/error`)。寫入 `machine_logs` 並觸發告警。
4.  **transaction (交易生命週期)**：原 B600/B601/B602。高價值點，走 **MQTT 管線** (`machine/+/transaction`)。透過 `action` 欄位區分 `create` (建立) / `finalize` (完成統整) / `dispense` (出貨結果)。
    - **員工卡/通行碼**：應透過 `action: finalize` 且 `amount: 0` 並帶入對應 `payment_type` (如 41: 員工卡) 進行交易錄入。
5.  **B012 (商品同步)**：大資料量，走 **HTTP 管線**。應確保 Service 層具備緩存 (Cache) 機制。
6.  **B055 (遠端出貨)**：雲端下發指令，走 **MQTT 下行管線** (`machine/{id}/command`)。

---

> [!CAUTION]
> **身份識別機制**：禁止在 Body 傳輸 `machine` 或 `key`。系統強制透過 `Bearer Token` 識別並自動關聯資料。
