> ## Content Index
> Fetch the complete content index at: http://localhost:2368/llms.txt
> Use this file to discover other available public pages before exploring further.

# 內部系統標準架構說明與新專案設定流程
- URL: http://localhost:2368/architecture-setup-guide/
- Published: 2026-07-07T01:56:21.000Z
- Updated: 2026-08-23T13:54:26.000Z
- Description: 四套內部系統共用架構的每一層說明，與新專案從零到上線的十步設定流程、常見陷阱速查表。
- Author: yuchang23
- Tags: #article

*四套內部系統（品管、生產日報 OEE、圖面管理、零件核准）共用同一套架構。這份文件說明架構的每一層是什麼、為什麼這樣選，以及開一個新專案時從零到上線的完整設定流程。實作細節由 AI 代勞，這裡記載的是「有哪些步驟、每步要準備什麼、雷在哪」。*

## 一 架構總覽

一張圖看懂資料怎麼流

使用者（公司帳號登入 Entra ID / MSAL）
   │
   ▼
Azure Static Web Apps ──────────────────────────────┐
   │  前端：React（Vite）或 Next.js（static export）│
   │                                                │
   │  /api/* ──▶ Azure Functions（TypeScript/Python）│
   │               │            │                   │
   │               ▼            ▼                   │
   │        Azure SQL      Azure Blob Storage       │
   │        或 Dataverse   （附件、照片、PDF）       │
   └────────────────────────────────────────────────┘
   ▲
   │ push main 自動部署（GitHub Actions）
   │     └─ 部署成功 → Teams 頻道通知（Adaptive Card）
GitHub Repo ──── PR → 預覽環境（獨立網址與設定）
任務追蹤：Teams Planner（sprint 卡片 + checklist）
    
| 層     | 採用技術                                            | 為什麼                                            |
| ----- | ----------------------------------------------- | ---------------------------------------------- |
| 前端    | React（Vite） 或 Next.js static export \+ Tailwind | 純靜態檔案、部署簡單；不需要 SSR                             |
| 後端    | Azure Functions（多為 TypeScript，圖面系統為 Python）     | 用多少付多少，跟 SWA 原生整合，/api/\* 自動接上                 |
| 結構化資料 | Azure SQL（共用伺服器、各系統獨立 schema）或 Dataverse        | SQL 省授權費好查詢；Dataverse 有內建版本戳記與 M365 整合         |
| 檔案    | Azure Blob Storage（各系統獨立容器）                     | 附件照片不進資料庫；存取一律經後端（Managed Identity 或後端簽發的 SAS） |
| 身分    | Entra ID \+ MSAL（前端登入）＋後端 JWT 驗證                | 公司帳號單一登入；權限控制在後端做                              |
| 部署    | GitHub Actions → Azure SWA，含 Teams 部署通知         | push 即上線；PR 自動開預覽環境                            |
| 任務追蹤  | Teams Planner（sprint 規格自動同步成卡片）                 | 進度與規格單一來源，主管同事直接看                              |

### 共用資源與爆炸半徑

四套系統共用一台 SQL 伺服器與一個儲存體帳戶，但用**隔離機制控制爆炸半徑**：每套系統一個獨立 schema（如 `instrument`、`oee`、`partapproval`）、一個權限只限自家 schema 的專屬資料庫帳號、一個獨立的 Blob 容器。任何一套系統出 bug，都動不到別套的資料。新專案照抄這個慣例，不要用全庫管理員帳號連線。

## 二 新專案設定流程

從零到上線十個步驟。「你」欄位是你要做的事，其餘 AI 代勞

### STEP 0 規格先行

**你：講清楚痛點與期望 → 拍板決策點**

讓 AI（planner 角色）把需求展開成 SDD 規格：範圍、驗收條件、不做什麼、sprint 拆分。規格確認前不動工。

### STEP 1 開 Repo、抄骨架

**你：決定專案名稱與 public/private**

GitHub 開 private repo。後端不從零寫——**直接複製品管系統 repo 的 `api/src/shared/`**（資料庫連線池、JWT 驗證、錯誤碼、全域錯誤攔截四個模組），這份骨架已被四套系統驗證過。

**雷：**`api/package.json` 的 name 欄位不能是空字串，否則雲端 build 會失敗且錯誤訊息很難懂。

### STEP 2 建 Azure 資源

**你：確認訂閱與資源群組、核可費用等級**

要開的資源：SWA 一個（免費層通常夠用）；共用 SQL 伺服器上**新增 schema + 專屬帳號**（不開新伺服器）；共用儲存體帳戶上**新增 Blob 容器**。資料表結構用編號 SQL 檔管理（`plans/sql/01-xxx.sql`），日後可重建。

**雷：**SQL 防火牆要開「允許 Azure 服務存取」，否則後端連不上資料庫；本機開發要另外加自己的 IP。

### STEP 3 Entra ID 應用程式註冊

**你：用管理員帳號核可（或請 IT）**

建立 app registration 給前端 MSAL 登入用，登記正式網址的 redirect URI（含 `/blank.html`）。拿到的 client ID 放進前端環境變數。

**雷：**SPA 的 redirect URI 不支援萬用字元——之後每個 PR 預覽網址都要各別補登記（見 STEP 7）。

### STEP 4 接上部署管線

**你：無（AI 設定 workflow 與 deployment token）**

GitHub Actions workflow：自己 build 前端與後端（`skip_app_build`），部署到 SWA。前端輸出目錄（Vite 是 `dist`、Next 是 `out`）與 `api_location` 要對。

**雷：**部署後 `/api/*` 全 404 → 十之八九是 `api_location` 指錯；前端打 API 全 404 → 檢查 `.env.production` 是否有 commit。

### STEP 5 設環境變數（正式與預覽各一份）

**你：提供/核可資料庫密碼與 JWT 密鑰的存放**

SWA 後台設定：SQL 連線四項、`JWT_SECRET`（32 字元以上隨機值）等。正式與預覽環境的變數完全獨立、不會互相繼承——這是「同一份程式，正式好的預覽壞的」的頭號原因，兩邊都要設。

### STEP 6 Teams 部署通知

**你：提供部門的 Teams Webhook（通常沿用同一條）**

workflow 加一步：部署成功後把本次 push 的 commit 清單做成卡片發到 Teams 頻道。webhook 網址存進 repo secret。

**雷：**通知步驟寫在功能分支上時，正式環境的通知要等 PR 合併後才會生效。

### STEP 7 預覽環境

**你：在預覽網址實際登入測一次**

開 PR 就自動有預覽環境（獨立網址，連結會貼在 PR 留言）。第一次登入會報 `AADSTS50011`——把預覽網址補登記到 redirect URI 就好。

**建議：**固定用同一個 PR 當開發預覽，不要一直開新 PR，可以少補很多次 redirect URI。

### STEP 8 Planner 任務同步

**你：在 Teams 開好 Plan、告訴 AI Plan ID**

sprint 規格文件同步成 Planner 卡片（每張卡帶 checklist，進度自動計算）。Plan ID 記進專案記憶，之後同步都自動。

### STEP 9 上線前檢查清單

**你：逐條驗收**

- 正式網址登入 → 打一支需要身分的 API 有資料回來（不是只看登入畫面）
- 權限測試：一般使用者看不到管理功能；管理操作前後端都有擋
- 中文檔名上傳下載正常；快速連續切換清單不會顯示錯資料
- 隔天早上第一個開系統：冷啟動提示有出現、等待可接受（或已設預熱排程）
- Teams 收到部署通知；Planner 卡片狀態與實際一致

## 三 常見陷阱速查表

症狀 → 先查什麼（全部來自四套系統的實戰紀錄）

| 症狀                   | 先查什麼                                                     |
| -------------------- | -------------------------------------------------------- |
| 登入成功但所有 API 都回「驗證失敗」 | SWA 會攔截 Authorization 標頭——後端改讀自訂 X-Auth-Token（骨架已內建，別改掉） |
| 同一份程式，正式好的、預覽壞的      | 預覽環境的環境變數沒設（兩邊獨立）；redirect URI 沒登記預覽網址                   |
| 每天第一個使用者特別慢          | SQL Serverless／Functions 冷啟動——預熱排程＋前端「啟動中」提示雙保險          |
| 中文檔名下載失敗或亂碼          | HTTP 標頭只能放英文（RFC 5987 編碼處理，骨架已內建）                        |
| 兩人同時編輯互相蓋掉           | SQL 用條件更新、Dataverse 用版本戳記（ETag）——驗收時開兩視窗實測               |
| 切換太快顯示到別筆資料          | 前端查詢競態——取消舊查詢＋過期回應丟棄雙保險                                  |
| 部署後 /api/\* 全 404    | api\_location 指錯、或 api build 失敗（先看 Actions log）          |
| 雲端 build 失敗訊息難懂      | api/package.json name 空字串、或 workflow 的輸出目錄設錯             |

### 本地開發備忘

兩個終端機：前端 `npm run dev`、後端 `cd api && func start`；前端的 `/api/*` 在開發模式要設 proxy 指到本機後端（骨架的設定檔已含）。連正式資料庫需先在 SQL 防火牆加本機 IP。

## 四 預留與例外

什麼時候這套架構不適用、未來要接機台怎麼預留

- **機聯網（IIoT）預留**：未來要接 CNC 機台訊號的系統，現在就在資料表預留「資料來源」欄位（手填/機器）與機台識別欄位，並規劃獨立的資料接收端點——之後才不用痛苦搬遷。生產日報系統已照此預留。
- **不適用的情況**：需要伺服器先組好第一個畫面（SSR）、需要長連線即時互動（非 IoT 場景）、或後端要給多個前端共用——這些要改用別的架構，先跟 AI 討論再動工。
- **資料層搬遷**：任何「換資料庫/換儲存」的需求，一律用絞殺榕式漸進遷移（逐種資料換底、留舊路徑可回退），不重寫。

**維護這份文件的方式**：架構或流程有變動時（例如新的共用模組、新的陷阱），把變動寫成筆記丟進知識庫 inbox，讓管線更新對應條目；這份文章則在大版本變動時整篇更新。

設定流程的每一步都有對應的可重用指南（skill），實際執行時 AI 會自動套用——你只需要照「你」欄位準備東西。

配套閱讀：[給新人的 AI 協作手冊](https://claude.ai/code/artifact/2e561194-61e5-4197-a726-8c415654ff0b?ref=localhost)（觀念與方法）、[與 AI 協作的六個月：廠內系統篇](https://claude.ai/code/artifact/59d0d5ce-08ea-463f-bf86-d3fb6577bc72?ref=localhost)（這套架構的演進史）