star-cloud/.agents/rules/framework.md
sky121113 e3ad7dd44f [DOCS] 修正並對齊 Demo 環境基礎設施資訊
1. 更新 README.md 與 framework.md 中的 Demo 環境網域、伺服器指令、部署路徑。
2. 更新 Gitea Workflow (.gitea/workflows/) 中的 Gitea 官方網址 (gitea.setdomains.work)。
3. 更新遠端部署模板中的舊 IP、路徑與機器人信箱,確保全站文件一致性。
2026-04-17 10:30:05 +08:00

13 KiB
Raw Blame History

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 BrokerEMQX 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 區別):

  • Controllersapp/Http/Controllers/,負責接收請求並回傳 view() 或 JSON。
  • Modelsapp/Models/{Domain}/,按領域分群 (例如 Machine, Member, System)。
  • Routesroutes/web.php 用於後台管理介面;routes/api.php 提供外部或機台調用介面 (需 V1 版本化)。
  • Services (建議)app/Services/{Domain}/,將商業邏輯與資料異動封裝於 Service 中。
  • Traitsapp/Traits/ApiResponse.php 用於統一 API JSON 回傳格式。
  • Jobsapp/Jobs/{Domain}/,用於異步處理 IoT 資料寫入、通知發送等背景任務。
  • Console Commandsapp/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_jobs List。
    • 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
  • Redis Key (實際名)starcloud_database_mqtt_incoming_jobs (含 Laravel 前綴)
  • Go 端 (生產者):將 MQTT 收到的 Payload 包裝成標準 JSON 後,執行 RPUSH starcloud_database_mqtt_incoming_jobs {json}。Go 程式碼中透過 "starcloud_database_" + cfg.IncomingQueueKey 手動加入前綴。
  • Laravel 端 (消費者):常駐指令 php artisan mqtt:listen 持續執行 BLPOP mqtt_incoming_jobsLaravel Redis 驅動自動加上前綴),取得 JSON 後解碼並分派至對應的 Laravel Job (如 ProcessHeartbeat, ProcessTransaction)。

Caution

Redis 前綴一致性Laravel 的 Redis 驅動會自動在 Key 前加上 config('database.redis.options.prefix') (預設 starcloud_database_)。Go 端不使用 Laravel 的 Redis 客戶端,因此必須在程式碼中手動加上此前綴,否則雙方會操作不同的 Key導致訊息永遠無法傳達。

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 (SHA256) 作為 Password。驗證流程

  1. Laravel 端 (Token 派發時)B014 下發 api_token 時,同步執行 Redis::hset("machine_auth:{serial_no}", "password", hash('sha256', $api_token))
  2. EMQX 端 (連線驗證時):配置 Redis Auth Plugin使用 HMGET machine_auth:${username} password 查詢 Redis Hash 進行極速驗證 (毫秒級),不經過 MySQL。
  3. Token 更新/撤銷時Laravel 更新或刪除機台 Token 時,必須同步更新或刪除 Redis 中的對應 Hash。
  4. Go Gateway 認證Gateway 使用固定帳號 star-cloud-gateway 連線 EMQX其認證資料同樣以 Hash 結構存放於 Redis (machine_auth:star-cloud-gateway)。

Caution

認證資料結構為 Redis Hash (HSET),非 String (SET)。EMQX 5.x 預設的 Redis 認證插件使用 HMGET 指令讀取,若誤用 SET 儲存為 String 類型,認證將永遠失敗。 批量同步指令:php artisan mqtt:sync-auth

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)
  • 回傳格式
    • Web 路由:回傳 view(),表單驗證失敗時直接使用 Laravel 內建的 redirect with errors。
    • API 路由:回傳標準 JSON 格式的 JsonResponse

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 引入,但原則上保持輕量。

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 CSSAlpine.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.setdomains.work
    • 登入伺服器查修:ssh demo-sc-103,路徑為 /workspace/mama/star-cloud

11. 瀏覽器測試規範 (Browser Testing)

當需要進行瀏覽器自動化測試或手動驗證時,必須遵守以下連線資訊:

  • 本地測試網址http://localhost:8090/ (注意:非 8000 或 8080)
  • 預設管理員帳號admin
  • 預設管理員密碼Star82779061

Important

在執行 open_browser_url 或進行 E2E 測試時,請務必優先確認 Port 是否為 8090,以避免連線至錯誤的服務環境。