瑞成工程專案管理系統白皮書
為結構工程案件打造的內部專案管理系統
版本 1.0 · 2026 年 6 月 · English Version
執行摘要
瑞成工程專案管理系統是專為 瑞成土木結構技師事務所 的技師團隊打造的內部工具,用於同時管理 30 件以上的工程案件。它不是對外的雲端產品,沒有註冊、沒有金流、也沒有對外的公開頁面 — 每一位使用者 都是事務所成員,以工牌編號登入。
系統環繞三大策略軸心設計,反映工程實務上實際承擔的法律與專業責任:
- 行為留痕、責任可溯 — 每一筆新增、修改、刪除都統一流經單一的
rcLog路徑,記錄時間、工牌、 角色與前後差異。日誌永久保存、不可竄改、可匯出 CSV,因為技師的簽證責任在追訴期內可追溯長達 10 年。 - 依業主工作日的時程燈號預警 — 進度是依照業主的工作日曆來衡量(政府機關跳過春節、建商週六 照常上工、半導體業主全年無休 24/7),轉換為四級燈號並推送到應用內的通知鈴鐺。
- 工牌登入 + 三層權限的責任界線 — 以工牌編號加密碼登入,並透過 10 個權限旗標的矩陣劃下硬界線: 行政人員可代為操作,但只有簽證技師才能調動進度數字。
本白皮書記錄領域模型、責任與稽核設計,以及實現這些設計的 Next.js 架構。
1. 問題
一家結構技師事務所同時進行數十件案子,每一件都有自己的業主、自己的法定期限,以及承擔個人責任的簽證 技師。在瑞成工程專案管理系統之前,這個現實是靠試算表、共用資料夾與記憶在維繫:
- 進度不透明。 一件案子是否在軌道上,取決於你問誰;而「在軌道上」是用通用日曆判斷,而非業主實際 上工的日子。
- 責任歸屬模糊。 當行政人員代技師更新案件時,沒有可靠的紀錄能說明是誰改了什麼、以及他是否有權這麼做。
- 舉證脆弱。 技師的簽證可能在專案結案數年後被挑戰。從散落的檔案重建「我們當時知道什麼、何時知道」 並不可靠。
- 期限被動。 落後的案子通常是在業主來電時才被發現,而非提前察覺。
事務所需要一套單一的內部系統:進度數字由唯一一個角色擁有、每一次變更都可舉證、落後的案子會自己舉手。
2. 領域模型
領域邏輯位於 components/rc/,是整個產品的核心。
2.1 六大案件類別
案件分為六個內建類別(再加上事務所自訂類別),依進度計算方式分群:
| 類別 | 名稱 | 進度模型 |
|---|---|---|
| A1 | 設計監造 | 節點式,自動加總 |
| A2 | 鑑定 | 節點式,自動加總 |
| A3 | 巡查 | 節點式,自動加總 |
| B1 | 建案 | 自填進度 |
| B2 | 計算案 | 自填進度 |
| B3 | 鑑定案 | 彈性混合 |
A 系列屬於 公共工程:進度是已完成節點的確定性加總,而非由人輸入的數字。B 系列由負責技師直接填寫 進度,其中 B3 同時支援兩種模式的混合。
2.2 母子追加案
B2 計算案可衍生 母子追加案 — 掛在母案下的後續工作。子案以狀態追蹤,不計入母案的進度 百分比,因此追加後續工作絕不會扭曲原案件的整體完成度。
2.3 時程燈號預警
每件案子都帶有目標時程。每日 02:00 的掃描會比對「已完成進度」對「已過時間」,並依業主的工作日曆 計算:
- 政府機關業主跳過春節,
- 建商業主週六照常上工,
- 半導體業主全年無休 24/7。
結果呈現為四級燈號:
| 燈號 | 門檻 | 意義 |
|---|---|---|
| 綠燈 | < 50 | 寬裕 |
| 黃燈 | 50–74 | 留意 |
| 橙燈 | 75–89 | 有風險 |
| 紅燈 | ≥ 90 | 危急 |
預警一律透過應用內通知鈴鐺傳遞 — 設計上沒有 Email 管道。
2.4 業主資料庫
一套輕量的客戶資料庫儲存業主屬性、保密協定(NDA)旗標、聯絡窗口(含已離職窗口的歷史紀錄),以及綁定 到每位業主的案件集合 — 讓預警日曆與聯絡紀錄始終隨案件一同流動。
2.5 稽核日誌
每一筆異動都流經 rcLog,記錄時間、工牌、角色與前後狀態。日誌永久保存、不可竄改、可匯出 CSV。其用途 具體明確:作為民事訴訟的證據,因為技師的簽證責任在追訴期內可延續長達十年。
3. 責任與權限
3.1 工牌登入
沒有 Email 登入、沒有 OAuth、也沒有兩階段驗證。使用者以工牌編號(格式 R00001)加密碼登入。 認證由 Auth.js v5 的 Credentials provider 處理,搭配 JWT session 策略(無狀態 — 無 DB session 表)。RBAC 守衛在每一次受保護的操作時都會從資料庫重新讀取角色,而非信任可能過期的 token 宣告。
3.2 三層 RBAC
三個角色對應事務所的真實職位:
| 角色 | 職位 | 界線 |
|---|---|---|
admin | 管理員(技師 / 簽證技師) | 擁有進度數字 |
operator | 行政 | 代為操作的文書作業;不能設定進度 % |
staff | 一般同仁 | 受限的任務存取 |
核心不變式:只有技師(admin)能設定進度百分比。 行政(operator)可代技師對多件案子進行文書性的 代為操作,但進度數字 — 那個承載專業責任的數字 — 保留給技師。
3.3 10 旗標權限矩陣
授權以一個在伺服器端評估的 10 旗標矩陣表達。每一個受保護的 Server Action 第一行就檢查呼叫者的旗標, 因此責任界線是在異動處強制執行,而非僅僅藏在 UI 裡。
4. 架構
4.1 Next.js App Router(Next.js 16)
系統使用 Next.js 16 App Router,採用:
- React Server Components(RSC) 作為預設 — 只在需要瀏覽器 API、事件處理器或 state 時才加上
"use client"。 - Server Actions(
"use server")處理每一筆案件異動 — 受守衛、被稽核,內部狀態不需另設 REST 層。 - Route Handlers(
app/api/)用於少數必須能依排程呼叫的 endpoint(例如 02:00 的時程燈號掃描)。 - 巢狀 Layout 用於路由群組:
(auth)/、(dashboard)/。
4.2 領域引擎
案件類別、節點加總進度、子案狀態追蹤、依日曆計算的燈號,以及 rcLog 稽核路徑,全都位於 components/rc/。把領域引擎集中在一處,正是讓責任界線可被稽核的關鍵。
4.3 認證(Auth.js v5)
- 透過
Credentialsprovider 以工牌編號 + 密碼登入。 - JWT session 策略 — session 無狀態,沒有 DB session 表。這是與 Credentials 登入的刻意搭配。
- 角色守衛在每一次受保護操作時都從資料庫重新讀取角色。
4.4 資料庫(Drizzle + PostgreSQL)
- Drizzle ORM — 型別安全的 Schema,零執行時開銷。
- PostgreSQL 15 — 生產級別,部署於 Zeabur 託管。
- Migration 透過
pnpm db:generate+pnpm db:migrate。 - 核心表格包含使用者(含工牌與角色)、案件、案件節點、子案、業主、業主日曆、時程燈號,以及不可竄改的 稽核日誌。
4.5 介面
介面以 Tailwind CSS v4 與 shadcn/ui 打造,採用瑞成品牌藍(#2C5CB8)。清單與表格視圖使用 共用的 data-table 元件;新增/編輯流程以彈窗開啟而非跳轉,整套 UI 以繁體中文呈現。
5. 不在範圍內
幾項商用雲端產品常見的能力被刻意排除,因為瑞成工程專案管理系統是單一租戶的內部工具 — 租戶就是 事務所本身:
- 沒有付款、訂閱,或任何金流商整合。 沒有東西要收費。
- 沒有可外掛的功能安裝/元件散布機制。 程式碼是單一應用程式,而非可散布零件的目錄。
- 沒有 OAuth、沒有兩階段驗證、沒有 LINE 整合。
- 沒有 Email 通知。 時程預警只存在於應用內的鈴鐺。
- 沒有檔案上傳。 文件以 NAS 連結引用,而非存放在系統內。
這些省略本身就是特性:較小的表面更容易稽核,也更貼近事務所實際的運作方式。
6. 如何打造
瑞成工程專案管理系統以 Claude Code 與一支 Athena agent 團隊開發,跑的是 epic 驅動的 spec → implement → QA → ship 流水線,每一次變更都搭配 TDD 與覆蓋率關卡。這是系統的打造與維護方式, 並非產品本身的賣點。
每次變更的品質關卡:
- 型別檢查:
pnpm typecheck(強制零錯誤) - Lint:
pnpm lint(eslint-config-next) - 單元測試:
pnpm test(Vitest,≥80% 覆蓋率關卡) - E2E 測試:
pnpm test:e2e(Playwright,冒煙測試關卡)
7. 部署
應用程式以單一服務形式部署到 Zeabur,Migration 在啟動時執行。本文件站台則另外部署到 Cloudflare Pages。
8. 結論
瑞成工程專案管理系統把結構技師事務所實際承擔責任的方式化為軟體:進度數字由單一角色擁有、每一次變更 在十年內都可舉證、依業主真實日曆落後的案子會自己舉手。刻意維持小巧的單一租戶表面,正是讓它保持可稽核 的原因。