star-cloud/.agents/skills/api-technical-specs/SKILL.md
sky121113 d740fc5ab8 [FEAT] 實作機台物理刪除功能與資料庫結構優化
1. 於機台設定頁面新增刪除功能,並限制僅系統管理員 (Super Admin) 可操作。
2. 移除機台模型 (Machine) 的 SoftDeletes Trait,將刪除邏輯改為物理刪除。
3. 建立並執行 Migration 移除 machines 資料表的 deleted_at 欄位。
4. 清除資料庫中原有的 51 筆機台軟刪除紀錄。
5. 更新繁中、英文、日文語系檔,加入機台刪除成功與確認視窗之翻譯。
6. 更新 B000 管理員登入 API 之回應格式,統一包含 success 與 code 欄位。
7. 同步更新 API 技術規格文件 (SKILL.md) 與 api-docs.php 配置。
8. 微調商品新增/編輯頁面之 UI 元件 z-index 層級。
2026-05-06 15:47:58 +08:00

334 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: API 技術規格與通訊協議規範
description: 本技能規範定義了 Star Cloud 系統中所有機台 (IoT) 與後端 (Cloud) 通訊的 API 細節、參數命名規則、狀態代碼對照與認證機制,作為系統開發的唯一規格來源。
---
# API 技術規格與通訊協議規範 (API Technical Specs)
本文件集中定義所有機台與雲端通訊的 API 規格,確保硬體端與軟體端在資料交換格式與業務定義上保持完全一致。
## 1. 核心命名原則
- **語意化優先**:捨棄舊版 M_ 前綴,統一使用 snake_case (如 firmware_version)。
- **類型嚴格**:文件定義的類型 (Integer, Float, String) 必須在後端 Model 與前端文件中心嚴格遵守。
## 2. 身份認證 (Authentication)
本系統採用兩階段認證模式:
### 2.1 維運人員認證 (User Authentication)
- **核發端點**B000 (登入)。
- **方式**:使用 Laravel Sanctum 核發之 **User Token**
- **Header**`Authorization: Bearer <user_token>`。
### 2.2 機台通訊認證 (Machine Authentication)
- **適用 API**B012, B009 等後續通訊。
- **方式**:使用機台專屬之 **api_token**
- **Header**`Authorization: Bearer <api_token>`。
---
## 3. 機台核心 API (IoT Endpoints)
### 3.1 B000: 機台本地管理員同步登入
用於機台 Android 端維護人員登入與進入設定頁。此 API 需帶入機台 API Token 進行認證。
- **URL**: POST /api/v1/app/admin/login/B000
- **Authentication**: Bearer Token (Header)
- **Headers**:
- `Content-Type: application/json`
- `Authorization: Bearer <api_token>`
- **Request Body:**
| 參數 | 類型 | 必填 | 說明 | 範例 |
| :--- | :--- | :--- | :--- | :--- |
| Su_Account | String | 是 | 系統管理員或公司管理員帳號 | admin |
| Su_Password | String | 是 | 密碼 | password123 |
| ip | String | 否 | 機台本地 IP | 192.168.1.100 |
- **Response Body:**
| 參數 | 類型 | 說明 | 範例 |
| :--- | :--- | :--- | :--- |
| success | Boolean | 請求是否成功 | true |
| code | Integer | 業務狀態碼 | 200 |
| message | String | 驗證結果 (Success 或 Failed) | Success |
| token | String | **臨時身份認證 Token** (可選,供未來擴充使用) | 1\|abcdefg... |
---
### 3.2 B005: 廣告清單同步
用於機台端獲取目前應播放的廣告檔案 URL 清單。
- **URL**: GET /api/v1/app/machine/ad/B005
- **Request Body:** 無 (GET 請求)
- **Response Body:**
| 參數 | 類型 | 說明 | 範例 |
| :--- | :--- | :--- | :--- |
| success | Boolean | 請求是否成功 | true |
| code | Integer | 內部業務狀態碼 | 200 |
| data | Array | 廣告物件陣列 | [{"t070v04": "https://..."}] |
**data 陣列內部欄位:**
- t070v01: 廣告名稱 (Name)
- t070v02: 播放長度 (Duration) — 秒數,若後台未設定,預設為 15 秒。
- t070v03: 廣告位置 (Position/Flag) — (3: 待機廣告, 1: 販賣頁, 2: 來店禮)。
- t070v04: 廣告 URL。
- t070v05: 播放順位 (Sort Order)。
---
### 3.3 B009: 貨道庫存即時回報 (Supplementary Report)
當維修或補貨人員在機台端完成操作後,將目前的貨道實體狀態同步回雲端。
- **URL**: PUT /api/v1/app/products/supplementary/B009
- **Authentication**: Bearer Token (Header)
- **Request Body:** 無 (由 Token 自動識別機台)
| 參數 | 類型 | 必填 | 說明 | 範例 |
| :--- | :--- | :--- | :--- | :--- |
| data | Array | 是 | 貨道數據陣列 | [{"tid":"1", "t060v00":"1", "num":"10"}] |
- **data 陣列內部欄位:**
| 欄位 | 類型 | 說明 | 範例 |
| :--- | :--- | :--- | :--- |
| tid | Integer | 貨道編號 (Slot No) | 1 |
| t060v00 | String | 商品資料庫 ID (或是 Barcode) | "1" |
| num | Integer | 實體剩餘庫存數量 | 10 |
| type | Integer | 貨道物理類型 (1: 履帶, 2: 彈簧)。若未提供,預設為 1。 | 1 |
> [!TIP]
> **自動化上限同步邏輯**
> 當後端收到 B009 時,會根據 type 自動從該商品的配置中選取 spring_limit 或 track_limit 並自動更新該貨道的 max_stock 欄位。機台端無需手動計算上限。
- **Response Body (Success 200):**
| 參數 | 類型 | 說明 | 範例 |
| :--- | :--- | :--- | :--- |
| success | Boolean | 同步是否成功 | true |
| code | Integer | 內部業務狀態碼 | 200 |
| message | String | 回應訊息 | Slot report synchronized success |
| status | String | 固定回傳 49 代表同步完成 | "49" |
---
### 3.5 B012: 商品配置與商品主檔同步 (Unified Sync)
用於機台端獲取目前所有可販售商品的詳細配置。
- **URL**: GET /api/v1/app/machine/products/B012
- **Authentication**: Bearer Token (Header)
- **Request Body:** 無 (由 Token 自動識別機台)
#### 運作邏輯 (Client-side Logic):
- **GET**:執行 **全量同步**。App 應於收到成功回應後,先執行 deleteAll() 再進行 insertAll() 以確保與伺服器完全一致。
- **PATCH**:執行 **增量更新**。App 於收到成功回應後,僅對記憶體中的既存商品進行欄位值覆蓋 (Patching)。
| 欄位 | 型別 | 說明 | 範例 |
| :--- | :--- | :--- | :--- |
| t060v00 | String | 商品資料庫 ID | "1" |
| t060v01 | String | 商品名稱 | 可口可樂 330ml |
| t060v01_en | String | 英文名稱 | Coca Cola |
| t060v01_jp | String | 日文名稱 | コカコーラ |
| t060v03 | String | 商品規格/簡述 | Cold Drink |
| t060v06 | String | 圖片 URL | https://.../coke.png |
| t060v09 | Float | 標準零售價 | 25.0 |
| t060v11 | Integer | **貨道庫存上限** (預設履帶) | 10 |
| t060v30 | Float | 會員價 | 20.0 |
| t063v03 | Float | 本機銷售價格 (同定價) | 25.0 |
| t060v40 | String | 行銷計畫 (Marketing Plan) | Buy 1 Get 1 |
| t060v41 | String | 物料編碼 (Material Code) | SKU-001 |
| spring_limit | Integer | **彈簧貨道上限** (建議使用此欄位) | 10 |
| track_limit | Integer | **履帶貨道上限** (建議使用此欄位) | 15 |
---
### 3.6 B013: [DEPRECATED / REMOVED] 機台故障與異常狀態上報
> [!WARNING]
> **此 REST API 已廢棄並移除**。機台異常上報已全面遷移至 **MQTT** 即時通訊架構。
> 詳細錯誤代碼請參閱:[MQTT 通訊規範 - B013 硬體代碼對照表](file:///home/mama/projects/star-cloud/.agents/skills/mqtt-communication-specs/SKILL.md#32-異常與錯誤上報-b013)
### 3.7 B014: 機台參數與金鑰下載 (Config Download)
用於機台引導階段 (Provisioning),向雲端請求支付金鑰、發票設定及機台正式 API Token。
- **URL**: GET /api/v1/app/machine/setting/B014
- **Authentication**: None (由 Query String 帶入 `machine` 參數識別)
- **Request Body:** 無
| 參數 | 類型 | 必填 | 說明 | 範例 |
| :--- | :--- | :--- | :--- | :--- |
| machine | String | 是 | 機台編號 (serial_no) | M-001 |
- **Response Body (Success 200):**
| 欄位 (Key) | 說明 | 備註 |
| :--- | :--- | :--- |
| **t050v01** | 機台序號 | 即 machine_id |
| **api_token** | **機台正式 Token** | 初始化後應存於本地,後續 API 認證用 |
| **t050v41** | 玉山特店編號 | ESUN Merchant ID |
| **t050v42** | 玉山終端編號 | ESUN Terminal ID |
| **t050v43** | 玉山 Hash Key | ESUN Hash |
| **t050v34** | 發票特店 ID | Invoice Merchant ID |
| **t050v35** | 發票 Hash Key | Invoice Key |
| **t050v36** | 發票 Hash IV | Invoice IV |
| **TP_APP_ID** | 趨勢支付 AppID | TrendPay ID |
| **TP_APP_KEY** | 趨勢支付 Key | TrendPay Key |
---
### 3.8 B017: 貨道庫存同步 (Slot Synchronization)
用於機台端**主動**向遠端後台拉取目前所有貨道的最新庫存、效期與配置狀態。通常發生於機台開機初始化、補貨/維護模式結束,或是機台需要確保本地端庫存資料與雲端一致時主動請求。
- **URL**: GET /api/v1/app/machine/reload_msg/B017
- **Authentication**: Bearer Token (Header)
- **Request Body:** 無 (由 Token 自動識別機台)
- **Response Body:**
| 參數 | 類型 | 說明 | 範例 |
| :--- | :--- | :--- | :--- |
| success | Boolean | 請求是否成功 | true |
| code | Integer | 200 | 200 |
| data | Array | 貨道數據陣列 (依 slot_no 排序) | 見下表 |
**data 陣列內部欄位:**
| 欄位 | 類型 | 說明 | 範例 |
| :--- | :--- | :--- | :--- |
| tid | String | 貨道編號 | "1" |
| num | Integer | 當前庫存數量 | 10 |
| expiry_date | String | 商品效期 | "2026-12-31" |
| batch_no | String | 批號 | "B202604" |
| product_id | Integer | 商品 ID | 1 |
| capacity | Integer | 貨道容量上限 | 15 |
| status | String | 貨道狀態 ("1": 啟用, "0": 停用) | "1" |
---
### 3.9 B660: 取貨碼驗證 (Pickup Code)
處理機台端的 8 位數代碼取貨流程。
- **URL**: POST /api/v1/app/machine/pickup/verify/B660
- **Authentication**: Bearer Token (Header)
- **運作模式**:
- **POST (驗證)**: 提交 `code` 驗證。成功後回傳 `pickup_code_id` 與建議 `slot_no`
- **消耗機制**: 出貨完成後,由機台發送 MQTT `finalize` 訊息,並在 `payment_type` 帶入 `6` (取貨碼) 完成扣減。
| 參數 | 類型 | 說明 | 範例 |
| :--- | :--- | :--- | :--- |
| code | String | 8 位數取貨碼 | "12345678" |
---
### 3.10 B670: 通行碼驗證 (Pass Code)
專供維修或工程人員現場測試使用的通行碼。僅做身分確認,不涉及庫存消耗。
- **URL**: POST /api/v1/app/machine/passcode/verify/B670
- **Authentication**: Bearer Token (Header)
- **Request Body:**
| 參數 | 類型 | 必填 | 說明 | 範例 |
| :--- | :--- | :--- | :--- | :--- |
| code | String | 是 | 8 位數通行碼 | "88888888" |
**Response (Success 200):**
- `name`: 持有者姓名 (如:維護部 A 員)。
- `status`: "active"。
---
### 3.11 B680: 員工卡身分驗證 (Staff Card Verification)
機台端感應員工卡 (RFID/NFC) 後驗證卡片 UID。
- **URL**: POST /api/v1/app/machine/staff/verify/B680
- **Authentication**: Bearer Token (Header)
- **Request Body:**
| 參數 | 類型 | 必填 | 說明 | 範例 |
| :--- | :--- | :--- | :--- | :--- |
| code | String | 是 | 卡片 UID 碼 | "A1B2C3D4" |
**Response (Success 200):**
- `name`: 員工姓名。
- `code_id`: 員工卡 ID (用於 MQTT 交易關聯)。
- `status`: "active"。
> [!WARNING]
> **鎖定機制**B660, B670 與 B680 若連續錯誤 5 次,該機台將被鎖定驗證功能 1 分鐘。
---
### 3.12 B027: 贈品碼/優惠券驗證 (Free Gift Verify)
用於處理行銷贈品券、0 元購活動或特定的優惠券核銷流程。
- **URL**: POST /api/v1/app/sell/free-gift/B027
- **Authentication**: Bearer Token (Header)
- **運作模式**:
- **POST**: 提交 `passCode` 驗證。成功後雲端會回傳對應活動 ID 與商品配置。
- **消耗機制**: 出貨完成後,由機台發送 MQTT `finalize` 訊息進行消耗。
---
### 3.13 B650: 會員身分驗證 (Member Verification)
機台端掃碼後驗證會員身分。
- **URL**: POST /api/v1/app/machine/member/verify/B650
- **Authentication**: Bearer Token (Header)
- **Request Body:**
| 參數 | 類型 | 必填 | 說明 | 範例 |
| :--- | :--- | :--- | :--- | :--- |
| code | String | 是 | 會員代碼 | "MEMBER12345" |
## 4. 已遷移至 MQTT 的端點索引
以下端點的 HTTP REST API 已廢棄,改為透過 MQTT 即時通訊架構處理。詳細的 Payload 定義請參閱 [MQTT 通訊規範](file:///home/mama/projects/star-cloud/.agents/skills/mqtt-communication-specs/SKILL.md)。
| 原 API 代碼 | 名稱 | MQTT Topic | 備註 |
| :--- | :--- | :--- | :--- |
| B010 | 心跳上報 | `machine/{serial_no}/heartbeat` | [已遷移](#312-b010-deprecated--removed-心跳上報與狀態同步) |
| B013 | 異常上報 | `machine/{serial_no}/error` | [已遷移](#36-b013-deprecated--removed-機台故障與異常狀態上報) |
| B600 | 交易建立 | `machine/{serial_no}/transaction` | `action: create` |
| B601 | 發票紀錄 | `machine/{serial_no}/transaction` | `action: invoice` |
| B602 | 出貨結果 | `machine/{serial_no}/transaction` | `action: dispense` |
| B600+ | 交易完成(統整) | `machine/{serial_no}/transaction` | `action: finalize` |
| B055 (PUT) | 遠端出貨回報 | `machine/{serial_no}/command/ack` | GET 查詢路由保留 |
---
## 附錄 (Appendix)
### Appendix A: B600 支付類型對照表 (`payment_type`)
此對照表依據機台 B600 規格定義,用於解析 `order.payment_type`
| 代碼 | 支付方式 | 備註 / 說明 |
| :--- | :--- | :--- |
| `1` | 信用卡 | 一般實體信用卡刷卡 |
| `2` | 電子票證 | 包含悠遊卡、一卡通等 |
| `3` | 掃碼支付 | 一般掃碼支付 |
| `4` | 投幣機支付 | 實體紙鈔機 |
| `5` | 通行碼 | 現場維護人員測試使用 |
| `6` | 取貨碼 | 包含 8 位數取貨碼與 0 元贈品碼 |
| `7` | 來店禮 | |
| `8` | 問卷 | |
| `9` | 零錢 | 硬幣投幣機 |
| `21` ~ `25` | 線下付款 + X | `21`=線下+1, `22`=線下+2... `25`=線下+9 |
| `30` | TapPay - LINE Pay | |
| `31` | TapPay - 街口支付 | |
| `32` | TapPay - 悠遊付 | |
| `33` | TapPay - Pi 拍錢包 | |
| `34` | TapPay - 全盈+PAY | |
| `40` | 會員驗證取貨商品 | |
| `41` | 員工卡 | RFID / NFC 刷卡 |
| `50` ~ `54` | 線下付款 + TapPay | `50`=線下+30, `51`=線下+31... `54`=線下+34 |
| `60` | 點數 / 優惠卷全額折抵 | 點數全額折抵出貨 或 優惠卷全額折抵出貨 |
| `61` ~ `69` | 會員 + X | `61`=會員+1, `62`=會員+2... `69`=會員+9 |
| `90` ~ `94` | 會員 + TapPay | `90`=會員+30, `91`=會員+31... `94`=會員+34 |