1. 新增 MQTT 即時通訊與 Topic 規範文件 (.agents/skills/mqtt-communication-specs/SKILL.md)。 2. 建立 MQTT 基礎架構實作計畫文件 (docs/mqtt-implementation-plan.md)。 3. 更新全域開發框架規範 (framework.md),納入 Go Gateway 與 EMQX 架構說明。 4. 重構 IoT 通訊處理規範 (iot-communication/SKILL.md),支援 HTTP 與 MQTT 雙軌管線。 5. 更新背景 API 規範 (api-rules.md) 與技能觸發規則 (skill-trigger.md) 以符合新架構。
12 KiB
trigger
| trigger |
|---|
| always_on |
開發框架規範說明書:Cloud 後台管理系統 (star-cloud)
1. 專案概述
- 目標:打造一個強大且穩定的智能販賣機後台管理系統(Cloud 平台),負責管理機台、商品、銷售數據以及提供給端點機台串接的 API。
- 核心架構:採用 Monorepo 單體式架構,以 Laravel 為核心進行伺服器端渲染 (SSR) 與 API 服務,並搭配 Go MQTT Gateway 作為高併發 IoT 通訊的前置接收層。兩者透過 Redis 進行異步橋接,確保職責分離與系統穩定性。
- 工作流程:後端處理業務邏輯與資料庫存取,並透過 Blade 引擎渲染包含 Tailwind CSS 類別的 HTML。前端互動行為由輕量級 Alpine.js 負責,UI 元件以 Preline UI 為主體。
2. 技術棧 (Tech Stack)
2.1 後端核心 (Laravel)
- 後端框架:PHP 8.5 / Laravel 12
- 核心組件:Redis (用於高併發 IoT 隊列、MQTT 橋接與快取,為系統穩定之必要條件)
- 資料庫:MySQL 8.0
- 開發環境:Laravel Sail (Docker / WSL2)
2.2 IoT 通訊層 (MQTT Gateway)
- MQTT Broker:EMQX 5 (負責維持機台長連線與訊息路由)
- Gateway 語言:Go (負責訂閱 MQTT Topic、預處理訊息、轉發至 Redis)
- 橋接機制:Redis List (
mqtt_incoming_jobs),由 Laravel 常駐指令 (mqtt:listen) 消費
2.3 前端
- 前端視圖 (View):Laravel Blade
- 前端互動 (JS):Alpine.js (專注於行為,不負責渲染)
- 介面與樣式 (CSS):Tailwind CSS + Preline UI (直接寫作於 Blade 模板中)。
- 重要規範:Preline UI 僅作為「原子組件」與「JS 互動邏輯」的參考庫。整體的「佈局」與「美學」必須嚴格遵守「極簡奢華風 UI 實作規範 (SKILL.md)」。
- 前端建置工具:Vite
3. 目錄結構與慣例
3.1 後端 (Laravel)
與標準 Laravel 結構保持一致,無過度拆分的模組化(與 ERP 的 Modular Monolith 區別):
- Controllers:
app/Http/Controllers/,負責接收請求並回傳view()或 JSON。 - Models:
app/Models/{Domain}/,按領域分群 (例如Machine,Member,System)。 - Routes:
routes/web.php用於後台管理介面;routes/api.php提供外部或機台調用介面 (需 V1 版本化)。 - Services (建議):
app/Services/{Domain}/,將商業邏輯與資料異動封裝於 Service 中。 - Traits:
app/Traits/ApiResponse.php用於統一 API JSON 回傳格式。 - Jobs:
app/Jobs/{Domain}/,用於異步處理 IoT 資料寫入、通知發送等背景任務。 - Console Commands:
app/Console/Commands/,包含 MQTT 橋接守護進程 (mqtt:listen) 等常駐指令。
3.2 前端 (Blade / Tailwind / Alpine)
- Views (頁面):位於
resources/views/。通常依功能建立資料夾(如resources/views/admin/machines/index.blade.php)。 - Layouts (版面):位於
resources/views/layouts/。定義全站的共用版面結構(如 header, sidebar, footer)。 - Components (組件):位於
resources/views/components/。封裝可重用的 Blade 元件(如 Button, Modal, Table),支援透過<x-button>語法呼叫。
3.3 MQTT Gateway (Go)
Go 專案以 Monorepo 形式置於專案根目錄下的 mqtt-gateway/ 資料夾,獨立於 Laravel 程式碼:
- 進入點:
mqtt-gateway/main.go - 模組管理:
mqtt-gateway/go.mod/go.sum - 內部分層:
mqtt-gateway/internal/handler/— 各 Topic 的訊息處理邏輯(如 heartbeat、transaction、error)。mqtt-gateway/internal/bridge/— Redis 橋接層,負責將處理後的 JSON 推入mqtt_incoming_jobsList。mqtt-gateway/config/— 環境變數與 EMQX / Redis 連線設定。
Caution
Go Gateway 的職責僅限於「接收、驗證、轉發」。嚴禁在 Go 中實作任何商業邏輯(如庫存扣減、通知發送),所有業務處理必須統一在 Laravel Service 層完成。
4. IoT 通訊架構 (MQTT + HTTP 雙軌制)
本系統的機台通訊採用 MQTT 與 HTTP 雙軌並行 的策略,依據通訊特性選擇最適合的協議。
4.1 整體資料流向
機台 (Android APP)
│
├─ [高頻/即時] MQTT 長連線 ──→ EMQX Broker ──→ Go Gateway ──→ Redis List ──→ Laravel mqtt:listen ──→ Job ──→ MySQL
│
└─ [低頻/大檔] HTTP REST ──→ Laravel API Controller ──→ (必要時) Job ──→ MySQL
4.2 MQTT 通訊端點 (高頻與事件驅動)
以下端點因高頻率或即時性需求,採用 MQTT 協議通訊:
| API 代碼 | Topic 格式 | 用途 | QoS |
|---|---|---|---|
| B010 | machine/{serial_no}/heartbeat |
心跳上報 (每 10 秒) | 0 |
| B013 | machine/{serial_no}/error |
故障與異常狀態上報 | 1 |
| B600 | machine/{serial_no}/transaction |
交易紀錄回傳 | 1 |
雲端→機台指令下發:透過 machine/{serial_no}/command Topic 推送,取代原本 B010 Response 中的 status 欄位輪詢機制,實現毫秒級即時指令。
4.3 HTTP 通訊端點 (資料拉取與敏感操作)
以下端點因資料量大、安全性要求高或為 Request/Response 模式,維持使用 HTTP REST API:
| API 代碼 | 用途 | 維持 HTTP 的原因 |
|---|---|---|
| B000 | 維運人員登入 | 無狀態認證,HTTP 更自然 |
| B012 | 商品配置同步 | 大量資料的 GET 拉取 |
| B014 | 金鑰與參數下載 | 高安全性敏感操作,需嚴格 RBAC |
| B009 | 貨道庫存回報 | 低頻操作,由維運人員觸發 |
4.4 Redis 橋接機制 (Go ↔ Laravel)
Go Gateway 與 Laravel 之間透過 Redis List 進行單向異步橋接:
- Redis Key:
mqtt_incoming_jobs - Go 端 (生產者):將 MQTT 收到的 Payload 包裝成標準 JSON 後,執行
RPUSH mqtt_incoming_jobs {json}。 - Laravel 端 (消費者):常駐指令
php artisan mqtt:listen持續執行BLPOP mqtt_incoming_jobs,取得 JSON 後解碼並分派至對應的 Laravel Job (如ProcessHeartbeat,ProcessTransaction)。
JSON 橋接格式規範:
{
"type": "heartbeat",
"serial_no": "M-001",
"received_at": "2026-04-14T09:00:00+08:00",
"payload": {
"current_page": 1,
"firmware_version": "1.0.5",
"temperature": 25.5
}
}
Important
為何不讓 Go 直接寫入 Laravel Queue? 因為 Laravel Queue 的 Payload 包含 PHP 序列化物件字串 (
serialize()),Go 無法安全產生此格式。透過獨立的 Redis List + 純 JSON,可徹底解耦兩端的技術依賴。
4.5 MQTT 連線認證
機台連線 EMQX 時,使用 serial_no 作為 Username、api_token 作為 Password。驗證流程:
- Laravel 端 (Token 派發時):B014 下發
api_token時,同步執行Redis::set("machine_auth:{serial_no}", hash(api_token))。 - EMQX 端 (連線驗證時):配置 Redis Auth Plugin,直接查詢 Redis 進行極速驗證 (毫秒級),不經過 MySQL。
- Token 更新/撤銷時:Laravel 更新或刪除機台 Token 時,必須同步更新或刪除 Redis 中的對應快取。
5. 開發標準 (Coding Standards)
- 命名規範:
- Controllers:
PascalCaseController.php(例如MachineController.php) - Models:
PascalCase.php(例如Machine.php) - Blade Views:
kebab-case.blade.php或按資源名稱 (例如index.blade.php,create.blade.php) - Routes uri:
kebab-case(例如/machine-logs) - Go 檔案:
snake_case.go(例如heartbeat_handler.go)
- Controllers:
- 回傳格式:
- Web 路由:回傳
view(),表單驗證失敗時直接使用 Laravel 內建的 redirect with errors。 - API 路由:回傳標準 JSON 格式的
JsonResponse。
- Web 路由:回傳
6. UI 與前端開發指南
- 樣式撰寫:全面使用 Tailwind CSS utility classes,避免撰寫自訂 CSS(除非少數特定動畫或覆寫)。
- UI 元件庫:遵循 Preline UI 的類別與 HTML 結構進行開發。
- 前端腳本:
- 優先使用 Alpine.js (
x-data,x-show,@click等) 在 HTML 標籤內完成簡單的 DOM 狀態切換與互動邏輯。 - 避免在 Blade 內撰寫冗長的
<script>Vanilla JS;若邏輯過於複雜,可將 Alpine state 獨立成 js 檔案再於 Vite 引入,但原則上保持輕量。
- 優先使用 Alpine.js (
7. 多語系 I18n 規範 (Multi-language Standards)
- 視圖開發:所有使用者可見的文字、按鈕、提示訊息,必須使用 Laravel 的
@lang('key')或__('key')函式包裹。 - 語系 Key 命名:語系 Key 必須採用 英文原始詞彙 (English phrases) 作為 Key 名稱為原則,以提高代碼可讀性並作為預設回退(除非該字串過長,才建議使用點號分隔的 key)。
- 範例:使用
__('Account Settings')。
- 範例:使用
- 翻譯檔維護:
- 主語系檔案位於
lang/目錄。 - 開發新功能時,必須同步更新以下三個 JSON 翻譯檔:
zh_TW.json(主要)、en.json(預設)、ja.json(日文)。
- 主語系檔案位於
8. AI 協作規則 (給 Antigravity AI)
- 角色設定:你是一位專業的全端開發工程師助手。
- 代碼生成指令:
- 所有的解釋說明請使用 繁體中文。
- 【警告:Preline 冗餘】 Preline UI 的官方範例常包含多餘的控制項(如頂部筆數切換)。嚴禁照抄其佈局,必須確保頂部工具列(Header/Toolbar)維持極簡,重複功能一律收納至底部。
- 【警告】 此專案前端禁用 React / Vue / Inertia.js。所有的前端頁面生成必須使用 Blade 模板 結合 Tailwind CSS 與 Alpine.js。
- 【多語系強制要求】 任何新增的 Blade UI 區塊,禁止硬編碼 (Hard-coded) 中文或英文。必須使用
__('...')並同步在lang/*.json補上翻譯。 - 生成 UI 區塊時,必須優先參考與產生 Preline UI 風格與結構的標記語法。
- 開發新功能時,請建立標準的 Controller 搭配對應的
resources/views/.../目錄。 - 【Go Gateway 開發】 修改
mqtt-gateway/內的 Go 程式碼時,嚴禁加入商業邏輯。Go 僅負責訊息接收、格式轉換與 Redis 轉發。
9. 運行機制 (Docker / Sail)
由於專案運行在 Docker 容器環境中,請勿直接在宿主機 (Host) 執行 php 或 composer 指令。請使用專案內建的 sail 指令:
- 啟動環境:
./vendor/bin/sail up -d(將同時啟動 Laravel、MySQL、Redis、EMQX、Go Gateway) - 執行 PHP 指令:
./vendor/bin/sail php -v - 執行 Artisan 指令:
./vendor/bin/sail artisan route:list - 執行 Composer:
./vendor/bin/sail composer install - 執行 Node/NPM:
./vendor/bin/sail npm run dev
10. 部署與查修環境 (CI/CD)
- 自動化部署:專案具備基於 Gitea Actions 的 CI/CD 自動化部署流程 (
.gitea/workflows/)。 - Demo 環境 (對應
demo分支):- 透過
deploy-demo.yaml,合併或推送到demo分支會自動部署至demo-cloud.taiwan-star.com.tw。 - 登入伺服器查修:
ssh gitea_work,路徑為/var/www/star-cloud-demo。
- 透過
11. 瀏覽器測試規範 (Browser Testing)
當需要進行瀏覽器自動化測試或手動驗證時,必須遵守以下連線資訊:
- 本地測試網址:
http://localhost:8090/(注意:非 8000 或 8080) - 預設管理員帳號:
admin - 預設管理員密碼:
Star82779061
Important
在執行
open_browser_url或進行 E2E 測試時,請務必優先確認 Port 是否為8090,以避免連線至錯誤的服務環境。