FR-065 · On-premise Installer — 設計文件 · 2026-08-16
把「出貨 bundle → 客戶主機 → 可登入的系統 → 後續換版」整條路標準化成客戶可自助執行的 installer。本文件承接同資料夾需求討論稿的 D1–D13 定案,轉為正式設計:full-stack compose、FE production image、bundle 交付、DB 從零初始化、install.sh、Web 設定精靈、升級回滾與 K8s 預留。
狀態:設計定案(D1–D12 已拍板;D13 大半收斂 2026-08-17;餘 D11.3(樣板 SSP,PM 議)開放)|建立日期:2026-08-16|母案:CM-1189 FR-065 Installer 前作:FR-063 Nuitka 落地版打包 design(image 1.14.0 出貨)/FR-064 防竄改偵測與授權鎖定 design(34 卡 Done) 討論稿(唯一內容真相源,含 e2e-env 借鑑全文與 D 項拍板脈絡):
discussion.html|DB init 細節引用源:db-init-inventory.html(CM-1207)
| 日期 | 變更 | 對應 |
|---|---|---|
| 2026-08-16 | 初版落地:D1–D12 定案轉入,D11 十子項落裁決(8 定案、D11.3/D11.5 保留),D13 待公司討論 | FR-065 母案 CM-1189 |
| 2026-08-17 | 追加 T-2.0(DEV 清理+序號歸位,CM-1266)入 .2 拆分表;D13 大半收斂(root=原廠系統殼、root admin 原廠持有);root admin 密碼永不過期列 FR-065 後另案處理(CM-1267) | 母案 CM-1189 |
| 2026-08-17 | D2 補裁 HTTPS 憑證:install.sh 產 per-install 自簽憑證(Clipboard API secure context 需求);T-1.2/T-2.5 對應更新 | 母案 CM-1189 |
| 2026-08-17 | 補「分工概述(30 秒版)」節(整案一句話+四棒一行表+依賴),置於需求背景之後、決策表之前 | 母案 CM-1189 |
| 2026-08-17 | 實況同步:.1/.2/.3 實作完成+修補三卡(T-2.5b/T-2.5c/T-3.2b,19→23 卡);D6 補裁 license 匯入時機(登入後走既有 FR-062 開通頁、不在精靈內);§6 補 188 真機首測紀錄;追加「出貨前決策清單」節 | 母案 CM-1189 |
| 2026-08-18 | D14 定案:物件儲存 MinIO→SeaweedFS 五點拍板(出廠即啟用/B 案正式 storage type/bundle 帶 image/框架 PDF 隨包出貨/MinIO 選配段移除);§5 追加 FR-065.5 段(3 子任務,23→26 卡,CM-1275~1278)+遷移工具 follow-up CM-1279;§7 第 3 題收口 | 母案 CM-1189/子需求 CM-1275 |
| 2026-08-18 | 排程重整:T-4.3 本次範圍跳過(有真實 Windows 需求時再啟動);.4 前置待收清單成文(CM-1235/CM-1273+CM-1269 併棒/CM-1275 驗收/CM-1270 真機複驗);§7 補第 5 項 PyMuPDF AGPL 替換(CM-1235,出貨合規硬前置已排棒)+剩餘未決盤點;CM-1269 修復方案(就地修復不重匯,四步)回寫該卡 | 母案 CM-1189 |
本案是落地版三階段戰線的第三棒:FR-063 把 BE 編成不帶原始碼的 Nuitka image、FR-064 給了它防竄改與授權鎖定——「跑起來之後」的問題已解完。還沒解的是「怎麼跑起來」:
docker/production/docker-compose.yml+deployment-env.md §0 四步手動流程,寫給自己人不是客戶。GUIDANT_VERSION 重跑 up -d」一句。目標:一份出貨 bundle+一支 installer,客戶自己(或一般 IT 人員照手冊)完成安裝、開通、日後升級,不依賴原廠工程師到場。硬前提承 FR-064 部署假設:客戶環境可能完全 air-gapped,一切須離線自洽。
安裝與開通有「雞生蛋」結構:license 綁機器指紋(sha256(/etc/machine-id)),但取指紋的唯一現成介面需 JWT 登入——所以旅程必須在裝機當下就把指紋交到客戶手上:主展示面是 Web 設定精靈頁(D10),installer fingerprint 為保底(D6)。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
sequenceDiagram
participant V as 原廠(build+LC 簽發站)
participant C as 客戶安裝者
participant H as 客戶主機
participant S as Guidant AI 服務
V->>C: 出貨 bundle(install.sh+image tars+bundle manifest+SQL/seed+手冊)
C->>H: 解開 bundle,執行 install.sh
H->>H: 環境檢查(docker/compose 版本、/etc/machine-id 非空、磁碟/記憶體)
H->>H: docker load 各 image + 比對 bundle manifest digest(D3)
H->>H: 產生基礎設施密碼組(cmmgr/cm_app)+ 寫 guidant.env
H->>H: DB init(one-shot init 容器跑分段腳本:schema+字典 seed,不建 admin,D4)
H->>S: docker compose up -d(PG/Redis/BE api/BE socketio/FE,D1/D2)
S-->>H: healthcheck 全綠
H-->>C: 印出:「請開 http://<主機>/ 完成設定」+ 一次性 setup token(D10)
C->>S: 開站進 Web 設定精靈:貼 setup token → 建 admin 帳號(密碼自設)
S-->>C: 精靈顯示機器指紋(sha256 machine-id,D6)+ license 匯入引導
C->>V: 抄指紋(離線通路:mail/電話)申請簽照
V->>V: LC 簽發站簽 license(綁指紋)
V-->>C: 回傳 .license 檔(PEM armor)
C->>S: 在精靈匯入 license(復用 FR-062 開通頁)→ 完成安裝進登入頁
S-->>C: 開通完成,全功能可用
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
sequenceDiagram
participant V as 原廠
participant C as 客戶安裝者
participant H as 客戶主機
participant D as PostgreSQL
V->>C: 升級 bundle(新版 image tars+增量 migration+manifest)
C->>H: 執行 install.sh --upgrade
H->>D: ① pg_dump 全量備份(落地到指定備份目錄)
H->>H: ② docker load 新 image + digest 驗證
H->>D: ③ one-shot init 容器套增量 migration(依 schema_migrations 判斷起點,align_migrations 演算法移植)
H->>H: ④ 改 GUIDANT_VERSION → docker compose up -d(自動 recreate)
H-->>C: healthcheck 全綠,升級完成
Note over C,D: 回滾=restore 備份 + GUIDANT_VERSION 回舊 tag 重跑 up -d
整案一句話:把前兩案的產物(編譯好的 image+防竄改機制)包成「客戶拿到一包東西,自己裝得起來、開得了通、升得了版」的落地安裝方案。
| 棒 | 做什麼(一句話) | 產出 |
|---|---|---|
| .1 整組服務一鍵起(5 卡) | compose 從「只有後端兩服務」擴成全家桶——DB、Redis、後端×2、前端(反向代理單一入口),乾淨機器 up -d 全起 |
產品版 docker-compose+前端正式 image+.env 範本 |
| .2 建庫+安裝腳本+出貨包(7 卡) | 清乾淨 DEV 做空庫基準 → 建庫腳本 → install.sh(檢查環境/載入 image/建庫/起服務)→ 打成 tar 出貨包(含正式簽章鑰) | install.sh+DB 初始化機制+出貨 bundle |
| .3 開通精靈+升級(5 卡) | 客戶裝完開瀏覽器走設定精靈(建租戶與管理員、抄機器指紋、匯授權開通)+ --upgrade 換版(備份→換 image→補 schema→重起) |
Web 設定精靈(前後端)+升級/回滾流程 |
| .5 SeaweedFS 物件儲存替換(3 卡,2026-08-18 追加) | 出貨包物件儲存從 MinIO 選配改為 SeaweedFS 出廠即啟用(正式 storage type+compose 常駐+框架 PDF 隨包出貨) | jedi 套件 storage type+compose/install.sh 改造+bundle 擴充 |
| .4 手冊+真機驗收(3 卡) | 客戶安裝手冊+乾淨機器全鏈真走一遍(裝→開通→升級→回滾) | 手冊+驗收紀錄 |
依賴:.1→.2→.3→.5→.4 直線。決策者功課:.2 前裁 D11.2/D11.5+備 CMMC 初始化資料、.3 前公司議 root 介面硬擋與否。
2026-08-16 批次拍板:D1–D10/D12 全數定案;D11 十子項 8 定案 2 保留;D13 待公司討論。定案一字內容以討論稿 callout 原文為準,本表為設計文件形狀的收斂。
| # | 一句話定案 | 理由摘要 | 被排除方案 |
|---|---|---|---|
| D1 | 依賴服務形狀:PG/Redis compose 全包為預設,image 隨 bundle 出貨;客戶自備服務時自行修改 compose 切外部(檔內註解引導:改 DB_HOST/REDIS_HOST、移除對應 service 段);MinIO 選配不預設(storage 預設 local);recreate 風險防護進實作設計(傾向 DB/Redis 獨立 compose project,或大字警語+installer 包裝所有 up 指令永遠帶 service 名) |
air-gap 單機客戶是主場景,要求自備等於把最難的一段推回給客戶;up -d 不帶 service 名會 recreate 同 project 的 DB(CLAUDE.md 有案) |
installer 做 --external-db 類參數(列未來可選加分項) |
| D2 | FE production image 與反向代理:nginx.onprem.conf+FE production image+單一入口 port(80/443),進 build 管線、tag 與 BE 同版號;BE 8000/8002 收進內網。HTTPS 憑證(2026-08-17 補裁):install.sh 裝機當下 openssl 產 per-install 自簽憑證(CN/SAN 填客戶主機名/IP,落 volume 掛 nginx),80→443 轉址;動機不只安全——精靈指紋複製鈕走 Clipboard API 需 secure context,http:// |
FE 已具備容器化全部零件(Dockerfile ARG NGINX_CONF、build:PRD 相對路徑同源即可用、nginx.e2e.conf 現成反代範本),缺的只是產品版定案;VITE_DEV_MODE 與 VITE_TURNSTILE_SITE_KEY 實作棒查清語意後定值 |
沿用 zip dist scp 手工擺放;bundle 內帶共用自簽憑證(所有客戶同一把私鑰=沒加密);只跑 80 留 HTTPS 給客戶自理(複製鈕失效) |
| D3 | image 交付通路:docker save tar bundle 為主+bundle manifest digest 比對進 installer 必做;Harbor pull 文件化為有網客戶的替代路徑 | air-gap 客戶拉不到 Harbor,通路只剩實體傳遞;FR-064 D7 已把 image 層驗證劃入本案——確保客戶手上的 image 與原廠出貨一致 | cosign 簽章方案(列評估項,不在 v1 硬性範圍) |
| D4 | DB init 載體:分段 SQL 腳本(B)+one-shot init 容器(C 載體),照 CM-1207 §5.4;基線真相取 DEV pg_dump;init 容器與升級 migration 容器共用同一形態 | 最高權限憑證只存在建庫當下(服務只拿 cm_app 憑證);每段可獨立 review/重跑、參數注入面窄 | A(單一 3 萬行 init.sql,難維護、cluster 層塞不進同一支);C 純 entrypoint 自動 init(服務容器須持有 cmmgr 憑證,違反最小權限) |
| D5 | 升級與回滾:四步包成 install.sh --upgrade(備份→load+digest→套增量 migration→up -d);回滾=restore 備份+回舊 tag,明文為災難逃生非常規操作;相容性檢查 v1 最簡版(bundle manifest 標適用起始版號區間,不符即拒跑) |
align_migrations.sh 的 diff+apply 演算法現成,移植到客戶端形態即可 |
無備份直升;自動回滾機制(v1 不做) |
| D6 | 首次開通雞生蛋:指紋主展示面=Web 設定精靈頁(顯示+複製鈕);installer fingerprint 子命令為保底(裝機尾端自動印+可隨時重跑,服務起不來時可用),演算法與 machine_fingerprint.py 一字不差,實作棒需驗「兩邊算出同值」。2026-08-17 補裁(CM-1259 偏離確認):license 匯入時機定案「裝完後走 Web、不在精靈內」——登入後走既有 FR-062 開通頁匯入,精靈收在顯示指紋 |
取指紋唯一現成介面需 JWT 登入,但簽照又需要指紋;宿主上一行 shell 即可算出同值 | 只靠登入後打 machine-code API(流程繞) |
| D7 | 正式簽章鑰(PROD kid):劃入本案 .2 棒——LC 端生成 PROD 鑰對→public_keys.py 新增 PROD kid→重 build image;出貨 bundle 一律以含 PROD 鑰的 image 產出 |
public_keys.py 現有 DEV/STG/POC 三把、無 PROD 鑰,出貨即「未知的 kid」;四步一組教訓適用 |
延到出貨時再補(硬前置不可延) |
| D8 | 外網依賴:落地版預設停用 Turnstile(BE/FE 一對開關,實作棒查清現況後補齊缺的開關);bundle 手冊附「本產品可能外連清單與停用法」 | Turnstile 內網連不到 Cloudflare 會直接讓登入失敗;LC 在線回報已 best-effort 離線自洽;AI API/Drive 屬功能模組不啟用即不外連——實作棒仍做一次完整外連盤點 | 維持「需評估」懸置 |
| D9 | Windows 支援:僅出評估文件+前提清單,不實作不承諾 | WSL2 /etc/machine-id 穩定性、volume 效能、Docker Desktop 企業授權條款皆未驗證;有真實客戶需求時另開案 |
原生 Windows 版 |
| D10 | installer 形式:純 bash install.sh(不做 TUI)+首次啟動 Web 設定精靈(混合式,Portainer/GitLab/Nextcloud/Jenkins 式)。bash 管基礎設施段(不建 admin,尾端印一次性 setup token 防搶注);精靈管應用設定段(建 admin 密碼客戶自設不經終端留痕);SMTP/storage 裝完後台慢慢設;systemd 不另立 unit(installer 確保 systemctl enable docker 即可) |
業界主流模式,體驗優先(user 拍板值得多一棒工作量) | TUI;純 shell 印生成密碼+首登強制改密(機制現成但體驗差一階,列 fallback) |
| D11 | seed 出貨範圍:十子項見下表(8 定案、2 保留) | 承接 CM-1207 §3.4 待裁決清單 | — |
| D12 | FR-064 出貨遺留歸屬:①進版(version-bump)與②image 推 Harbor 劃入本案出貨動作(掛 .2 bundle 打包段前後);③K8s liveness 鎖定殼 CrashLoop 不在本案實作、但設計預留(見 §4.8) | 出貨 bundle 必然要定版;user 明示「要預留 K8s」——compose 服務契約保持可翻譯性 | 把 K8s 適配一起做(未來另開 FR) |
| D13 | 🔶 大半定案(2026-08-17):root tenant=原廠管理的系統殼——root admin 帳號密碼由原廠持有管理,客戶不碰;Web 設定精靈不建 root admin(DB init seed 建、密碼裝機生成交原廠),精靈建的是「客戶第一個業務租戶+租戶管理員」。殘項收案(2026-08-17 決策者):v1 先不做介面硬擋,照現狀出一版,之後有問題再調。連帶裁示:root admin 密碼永不過期(豁免 90 天政策)=FR-065 後另案處理,卡號 CM-1267 | 市面同構(Keycloak master realm/GitLab Admin Area/Atlassian DC 皆「系統層=管理殼」);我方 B-2 模型下 root 本就是系統資源掛載點,DEV 拿 root admin 做業務是開發便利非設計意圖 | Payload CMS 式「super admin 無租戶歸屬」(與 B-2 架構相反,不可學形狀) |
| D14 | ✅ 定案(2026-08-18)物件儲存 MinIO→SeaweedFS 五點:①出廠即啟用——SeaweedFS 進產品 compose 常駐服務,root tenant 與預設 STORAGE_CONFIG seed 皆指向它,客戶檔案第一天就進物件儲存(不再選配);②B 案(語意乾淨版)——jedi-file-upload 加 SEAWEEDFS 正式 storage type(adapter 繼承 MinIO 版,S3 gateway 已實測全 API 通過),minio type 保留供客戶自備 S3 相容儲存切換;③bundle 帶 seaweedfs:3.99 image(官方現成,~100MB);④框架 PDF(系統檔)隨 bundle 出貨——基線產製時在 SeaweedFS 上匯 CMMC→bucket 匯出 storage-seed/ 打進 bundle→install.sh 原 key 灌回(不經 BE、不改資料列、冪等);⑤MinIO compose 選配段移除+手冊補「更換儲存後端」警語章+遷移工具開 follow-up(CM-1279)不擋 .4。落地=FR-065.5 三卡(§5) |
MinIO 社群版閉源化;SeaweedFS S3 gateway 與既有 minio SDK adapter 全相容(CM-1268 實測,docs/analysis/2026-08-17-seaweedfs-evaluation-and-dev-deployment.md);system-scope 檔讀取走當下 root STORAGE_CONFIG,客戶切換後系統檔立即全斷——故框架 PDF 必須連檔出貨且手冊必須警語 |
沿用 MinIO(閉源化風險);A 案零改碼(minio 標籤裝 SeaweedFS,出貨產品長期語意債);維持選配(切換遷移支線複雜) |
字典類必備 seed(operations/system_menus/ui_routes/capabilities/root tenant+org/Administrator 角色/RUNTIME_CONFIG 等,CM-1207 §3.1)已明確屬出貨集,不在此重列。
| # | 一句話定案 | 備註 |
|---|---|---|
| D11.1 | ✅ 改版定案(2026-08-17):框架只出 CMMC 2.0,由原廠於出貨基線庫匯好——決策者本人在清完的 guidant_ai 上走正規 PDF 匯入 L1/L2,匯入自動產生 AO 級範本一併入基線;bundle 不帶框架檔、客戶不需自行匯入 |
原案「bundle 帶 OSCAL JSON 客戶自匯」(多一個客戶側出錯環節;「DEV 分不出內建」顧慮在乾淨基線庫不存在);seed dump 直灌 catalog 資料列 |
| D11.2 | ✅ 全數定案(2026-08-17):流程範本實查兩張表——① flow_templates(主流程)只帶 id 1 完整稽核流程+id 3 自我評估稽核(兩筆 inactive 內建砍掉);② workflow_templates(AO 級 BPMN)清空不 seed——經程式碼驗證(_init_ao_workflows())它是匯入 catalog 時自動產生的衍生資料,與 D11.1 同模式;T-2.2 驗收補「空庫匯入 CMMC catalog 自動產 AO 範本跑通」 |
seed 照抄 DEV 任一包(59/186 皆歷次匯入測試殘留);人工維護 AO 範本對照表 |
| D11.3 | ⏸ 保留:樣板 SSP/MF defaults 家族——裁示先留空,出貨基線不帶,與 PM 討論後另定範圍 | DEV 現況分不出產品內建 vs 開發試作 |
| D11.4 | 🔄 2026-08-21 決策者推翻,改比照 D11.1「原廠匯好進基線」(CM-1322):原案「隨 bundle 帶檔+管理員 UI 逐支匯入」作廢,理由「不可能讓管理員做,這要預設裝好就有,要比照合規框架」。現行=原廠在基線庫走正規 API 匯好(8 TWGCB+2 dev-sec,解析全 succeeded),三者同時進基線:profile 資料列+upload_files 列(05-seed-catalog.sql)+檔案實體(detection-profiles/storage-seed.map → build 時重建進 storage-seed)。客戶裝完即有 10 套可用基準,零手動步驟。id 已重排為 1..N 連續(決策者要求)。連帶:CINC 解析器不進 BE image(省 ~270MB)——內建基準已解析完成不需它;客戶自傳新基準檔的進階場景改由文件交代 compose override 唯讀掛載 /opt/cinc-auditor(手冊 §10.3) |
原案顧慮的「seed 灌列、檔案不在=壞連結」由三者同時進基線解決(框架 PDF 已走通同模式);本次落地已驗證 8 支檔 MD5 與 seed 資料列 checksum 逐一吻合 |
| D11.5 | ✅ 定案(2026-08-17):FEEDBACK_TYPE 3 筆照帶;FUNCTION 群不沿用舊清單,改以 ui_routes enable=1 且有 url 的頁面 name 重新產生(排除 group-* 分類節點,約 33 筆+others 兜底),seed 腳本從 ui_routes SELECT 產生不硬編;id 1~4 中文舊殘留不帶 |
沿用 DEV 35 筆(textbook-/resource-/cruise-* 為舊產品線殘留) |
| D11.6 | ✅ ISSUE_INTEGRATE_CONFIG 出廠帶 disabled 空殼,客戶後台自行啟用接自己的 GitHub/GitLab |
功能對落地客戶開放 |
| D11.7 | ✅ public.alembic_version 暫留(基線帶此表、不清除) |
舊版 flask-migrate 遺留,user 證實來源已明 |
| D11.8 | ✅ root tenant 顯示名由客戶命名(Web 設定精靈輸入);root id=1 是硬約定不可變,只裁顯示名;DEV 值不沿用為出廠固定值 | 連動:若 D13 採系統殼方案,命名對象改為第一個業務租戶、root 顯示名固定(如 System) |
| D11.9 | ✅ debug view(debug_org_units/v_tenant_parent_debug)確認零引用後連 DEV 一併刪除(grep 全 codebase→開 migration drop、走 sql-migration 流程與 DROP 前安全查核鐵則→出貨基線自然不含);cm_app_group 空群組保留 |
空群組利未來多 app 帳號 |
| D11.10 | ✅ 落地版 DB 名統一 guidant_ai(2026-08-08 DB 命名新制,落地新客戶屬新建置適用新制);installer INIT_DB_NAME 預設值定此 |
— |
| 元件 | 現況 | 本案動作 |
|---|---|---|
| BE image | guidant-ai-be:1.14.0:ubuntu:22.04 基底、中文字型/LibreOffice/WeasyPrint 原生庫已進 image、產物 root:root+entrypoint setpriv 降權 uid 1000、不帶 python/原始碼 |
直接沿用,不動 |
| BE build 管線 | scripts/build/:build_all.sh→smoke→build_image.sh;integrity manifest 簽章在 build_release.sh Step 4 尾端送 LC 簽 |
擴充:FE image build(D2)+bundle 打包段(D3) |
| compose 定式 | docker/production/docker-compose.yml 僅 guidant-api(8000)+guidant-socketio(8002);read_only+tmpfs;7 個掛載(static/log/home/tmp/pki/machine-id/agent 憑證);無 DB/Redis/MinIO/FE;檔頭警語:up -d 必帶 service 名 |
擴充為完整 stack(D1/D2),處理 recreate 風險;既有定式全數保留(§4.1) |
| FE 交付 | 有 Dockerfile(node build→nginx:alpine,ARG NGINX_CONF 可換 conf);build:PRD 走相對路徑(VITE_API_URL=/api/1.0、WS 同源)不需 per-customer rebuild;nginx.e2e.conf 是現成同源反代範本但限 E2E;正式部署=zip scp 手工;build-time 綁死僅剩 VITE_TURNSTILE_SITE_KEY 與 VITE_DEV_MODE(PRD 現值 true,落地要檢討) |
新增 production 容器形態(D2,§4.2) |
| DB 初始化 | 零。DEV 實況 5 schema/186 表/107 條 RLS policy/156 sequence;cmmgr/cm_app 建立紀錄不在 repo;CM-1207 已產出完整基線盤點+方案草案 | 本案核心交付(D4,§4.4) |
| migration/升級 | manifest.tsv active 138 筆(127 筆 envs=*、11 筆環境限定不屬基線);align_migrations.sh diff+apply 演算法現成但 target 寫死內部 IP、密碼讀 repo .env;換版現況無備份/回滾/相容性檢查 |
升級流程(D5,§4.7) |
| license/指紋 | 指紋=sha256(/etc/machine-id);取指紋唯一介面需 JWT 登入;無照態服務照起但 license 軸外全 403(/license/ 與 /login 豁免);license 檔 PEM armor 貼 FE 頁匯入;unlock.token 落 /opt/guidant/pki |
開通旅程(D6,§4.6);宿主前提 /etc/machine-id 非空(CM-1242 實測) |
| 簽章公鑰 | public_keys.py 硬編進 image,現有 DEV/STG/POC 三把、無 PROD 鑰 |
D7(§4.3) |
| 外網依賴 | Turnstile 內網連不到 Cloudflare 登入失敗(「需評估」未定案);LC 回報 best-effort 已離線自洽 | D8 |
| image 交付通路 | 完全沒寫;docker save 先例只有 FR-058 agent image | D3(§4.3) |
| FR-064 出貨遺留 | 未進版(現標 1.14.0);image 未推 Harbor;K8s liveness 下鎖定殼會 CrashLoop(compose 不受影響) | D12(進版+推 Harbor 掛 .2;K8s 預留 §4.8) |
| 客戶側安裝資產 | 零(compose+deployment-env.md §0 四步手動流程) | 本案主體 |
test repo compliance-manager-test/e2e-env/ 的 8-service 全套 compose 每天在驗證「這組服務能在一個 compose 內良好共處」。user 指示:分析借用、不整抄——借拓撲與機制三條線(服務組成/互連/啟動順序),不借資料來源、image 血統、測試編排三條線。可移植 12 項:
| # | 借什麼 | 為什麼 |
|---|---|---|
| 1 | PG service 形態:postgres:16+顯式 POSTGRES_INITDB_ARGS(--encoding=UTF8 --locale=en_US.utf8)+named volume+pg_isready healthcheck |
不顯式指定,客戶主機預設 locale 滲進 initdb,跨機不可重現 |
| 2 | Redis 必須 ACL user 而非 requirepass(--user "$REDIS_USER" on ... "+@all" 段必抄+appendonly no+healthcheck 用 ACL user 實測 ping) |
BE config 組 redis://<user>:<pass>@host 形式,requirepass 只認 default user 會連不上 |
| 3 | 同源 nginx 反代拓撲:/api/1.0→be:8000、/socket.io→be-socketio:8002(必須分開兩 service)、SPA try_files |
與 build:PRD 相對路徑產物互補,單一入口不需 per-customer rebuild |
| 4 | nginx resolver 127.0.0.11 valid=10s+變數 upstream 動態解析 |
不寫的話 BE restart 換 IP 後 nginx 快取舊 IP 全站 502——客戶自己重啟服務是常態 |
| 5 | 反代調校:client_max_body_size 0、API read_timeout 600s+buffering off、socket.io 3600s+WS upgrade |
大檔上傳與長工時匯出(SSP docx/PDF)會踩預設 timeout |
| 6 | depends_on condition: service_healthy 啟動順序鏈 |
DB/Redis ready 才起 BE、BE healthy 才起 FE——「up 完即可用」的前提 |
| 7 | 一 image 兩服務(RUN_MODE)+YAML anchor |
產品 compose 已有同形態,e2e-env 驗證了與 DB/FE 同 compose 也成立 |
| 8 | MinIO 選配段形態:minio+mc init job(--ignore-existing 冪等) |
D1 已定 MinIO 選配,冪等 init job 形態直接可用 |
| 9 | 零硬編憑證+.env.example 規範(只列 key 與用途) |
與本案「密碼由 installer 產生、憑證不入版控」一致 |
| 10 | BE 必要 env 踩坑清單:ENABLE_MULTI_TENANT 必須顯式 "true"(缺了 RLS 靜默擋、查無資料無錯誤);DRIVE_TOKEN_ENCRYPTION_KEY 啟動即檢;DETECTION_TOOL_ENCRYPTION_KEY 是另一支(錯誤訊息會誤導);DB_PORT 顯式 5432(BaseConfig 硬編 25432) |
每一條都是 e2e-env 實踩過的啟動失敗/靜默故障,.env 範本照單全收 |
| 11 | 容器內 vs 對外 port 分離(BE 連 service:5432,對外映射另計) |
客戶主機 port 衝突時只改對外映射,服務互連不動 |
| 12 | HTTPS 是功能必要不是加分:FE aiChatStore 用 crypto.randomUUID(),非 secure context 下為 undefined 且錯誤被吞→登入卡死零訊息 |
443+憑證掛載是必要設計——不上 HTTPS(localhost 之外裸 HTTP)產品直接壞 |
不可抄清單(golden dump/roles 搬遷/sanitize/mailpit/E2E image/ENV=DEVELOP_PREMISE/兩層疊 image/測試編排產物)詳見討論稿〈e2e-env 借鑑分析〉。
服務拓撲(service 名用中性名,不沿用 e2e 的 e2e-postgres 類寫死名):
| service | image | 角色 | 對外 port |
|---|---|---|---|
guidant-db |
postgres:16 | 主資料庫;顯式 POSTGRES_INITDB_ARGS(encoding/locale)+named volume+pg_isready healthcheck |
無(內網 5432) |
guidant-redis |
redis | ACL user 形式啟動(非 requirepass)+appendonly no+ACL user 實測 ping healthcheck |
無 |
guidant-api |
guidant-ai-be | REST API(RUN_MODE 預設);沿用既有定式 |
無(內網 8000) |
guidant-socketio |
guidant-ai-be | SocketIO(RUN_MODE=socketio);與 api 同 image YAML anchor |
無(內網 8002) |
guidant-fe |
guidant-ai-fe | nginx:SPA 靜態+同源反代,唯一對外入口 | 80/443 |
guidant-minio+guidant-minio-init |
minio/mc | 選配段(storage 預設 local 不啟用);mc init job --ignore-existing 冪等建 bucket |
無 |
設計要點:
docker/production/docker-compose.yml 的 7 個掛載(static/log/home/tmp/pki/machine-id/agent 憑證)、read_only+tmpfs、宿主 /etc/machine-id 掛載(CM-1242 指紋修復)全數保留,本案是擴充不是重寫。depends_on condition: service_healthy 鏈——DB/Redis healthy→BE 兩服務→FE。nginx.e2e.conf 為底、upstream 指向 compose service 名):同源反代 /api/1.0→guidant-api:8000、/socket.io→guidant-socketio:8002(含 WS upgrade);resolver 127.0.0.11 valid=10s+變數 upstream;client_max_body_size 0、API read_timeout 600s+buffering off、socket.io 3600s;SPA try_files。crypto.randomUUID() 為 undefined、登入卡死零訊息——不是資安加分項,是功能必要(§3.2 第 12 項)。DB_HOST/REDIS_HOST 環境變數、移除對應 service 段;installer 不做參數化外接模式(D1)。up -d。ENABLE_MULTI_TENANT="true" 顯式、兩支加密 key、DB_PORT=5432 顯式)。nginx.onprem.conf;Dockerfile 既有 ARG NGINX_CONF 換入;build 用 build:PRD(相對路徑產物,同源即可用,不需 per-customer rebuild)。scripts/build/ 管線,tag 與 BE 同版號(guidant-ai-fe:<X.Y.Z>)。VITE_DEV_MODE(PRD 現值 true——語意與影響面查清後定值,落地版直覺上不該開)與 VITE_TURNSTILE_SITE_KEY(現值 Cloudflare 測試 key,與 D8 停用連動)。docker save tar(BE/FE/PG/Redis,MinIO 隨選配)+bundle manifest(各 tar sha256 digest+適用起始版號區間)+SQL init 腳本與 seed 檔(框架與檢測 Profile 於 2026-08-21 起皆走「原廠匯好進基線」,資料列在 04/05、檔案實體走 storage-seed;D11.1/D11.4 改版)+manifest.tsv+客戶手冊。docker load 後逐一比對 manifest digest,不符即拒裝——確保客戶手上的 image 與原廠出貨一致(FR-064 D7 劃入項)。cosign 列評估項不在 v1。public_keys.py 新增 PROD kid→重 build image→出貨 bundle 一律以含 PROD 鑰的 image 產出。連帶 D12:進版(version-bump)與 image 推 Harbor 掛在 bundle 打包段前後執行。引用源:db-init-inventory.md §5(方案比較與共同前提全文)。
scripts/init/):00-cluster.sql(CREATE ROLE cmmgr 降規版/cm_app/cm_app_group、CREATE DATABASE,連 postgres 庫)→01-extensions(uuid-ossp、pg_trgm)→02-schema(DEV pg_dump --schema-only 整理:去 DEV 殘留表、去歷史月分區)→03-grants(default privileges ×5 schema+event trigger trg_auto_grant_cm_app,不逐表 GRANT 400 行,逐項掃描僅作驗收)→04-seed-core→05-seed-catalog→06-admin(本案 D10 下不在 init 建 admin,改由精靈通道;段位保留給精靈 BE 寫入的契約參照)→99-stamp+init.sh。guidant_ai(D11.10);D11.2 清單核對、D11.3/D11.5 依開放項時程補定。ON CONFLICT DO NOTHING;schema 段以 schema_migrations baseline marker 判斷跳過;失敗語意=整庫重建(init 場景可接受)。schema_migrations 登記 __init_baseline_v<版號>__ marker+補登已收斂的 active migration 檔名;schema_version 補基線版號——讓後續增量 migration 與三環境 diff 工具無縫接軌,基線之後的新 migration 照舊制走。薄終端原則:bash 只管基礎設施段,應用設定全部讓給 Web 精靈;不做 TUI。
docker compose plugin;systemctl enable docker(開機自起前提)/etc/machine-id 非空:test -s /etc/machine-id 必過(CM-1242 實測:缺檔時 docker 會建成目錄、指紋退回 MAC 每次重啟漂移;極精簡系統用 systemd-machine-id-setup 補)。⚠️ machine-id 一旦重生成,既有綁機憑證全部失效——只在「本來就沒有」時補docker load+digest 比對(不符拒裝)→產生基礎設施密碼組(cmmgr/cm_app 分別產生,不沿用 DEV 同密碼慣例)+寫 guidant.env→DB init(one-shot init 容器:schema+字典 seed,不建 admin)→docker compose up -d→healthcheck 全綠。http://<主機>/ 完成設定」+一次性 setup token(Jenkins 式防搶注——避免精靈開放期間被非安裝者搶先建帳號)。不印 admin 密碼(密碼由客戶在精靈自設,不經終端留痕)。--config 非互動模式:參數由設定檔提供,供自動化/重跑場景。installer fingerprint 子命令:見 §4.6。sha256(/etc/machine-id) 指紋——這是指紋的主展示面(D6);客戶抄指紋走離線通路(mail/電話)向原廠申請簽照。.license 檔(PEM armor)貼上匯入→完成安裝進登入頁。installer fingerprint 子命令,演算法與 machine_fingerprint.py 一字不差;裝機尾端自動印+可隨時重跑(服務起不來時可用);實作棒需加「installer 與 BE 兩邊算出同值」的驗證步驟。四步包成 install.sh --upgrade:
pg_dump 全量備份(落地到指定備份目錄)docker load 新 image+digest 驗證align_migrations.sh 的 diff+--apply 演算法移植到客戶端形態:連線參數外部注入(現版寫死內部 IP、密碼讀 repo .env,客戶端重做連線層)、SQL+manifest.tsv 隨 bundle 出貨、依 schema_migrations 判斷起點GUIDANT_VERSION→docker compose up -d(自動 recreate)GUIDANT_VERSION 回舊 tag 重跑 up -d。明文告知:回滾會丟升級後產生的資料,屬災難逃生不是常規操作。user 明示「要預留 K8s」——本案不做 cluster 實作,但以下記為未來 K8s 案的起點;compose 寫成乾淨服務契約(服務名/port/env 介面清楚)保持可翻譯性。
鎖定態排除 liveness 的設計要點:FR-064 已知,K8s liveness 下鎖定殼會 CrashLoop(compose 落地不受影響)——上 K8s 時需把「授權鎖定態」排除在 liveness 判定之外(鎖定=業務拒服務但行程存活,不可被 kubelet 視為 unhealthy 重啟)。
cluster 化前提五條(compose→K8s 翻譯是機械工,真門檻在應用層假設,先記錄不動):
sha256(/etc/machine-id))——多節點下每台指紋不同,license 模型要改(改綁 cluster identity 或浮動授權)。/opt/guidant/pki、unlock.token)——多副本共享或各自持有需重新設計。未來有真實需求另開 FR。
實況(2026-08-17):.1/.2/.3 全數實作完成(含追補卡,T-2.5c 進行中除外);.4 三卡未開工。2026-08-18 追加 .5(SeaweedFS 物件儲存替換,D14),插在 .3 之後、.4 之前。
依賴鏈:.1(地基)→ .2(DB init+installer 殼+bundle+PROD 鑰)→ .3(精靈與升級)→ .5(SeaweedFS 替換)→ .4(文件與真機驗收,T-4.1/T-4.2 須含 .5 內容)。.1 依 D1/D2(均已定案)即可開工。開放項影響:D11.2 清單核對與 D11.5 → T-2.2(.2 開工前定);D11.3 → T-2.2 seed 範圍(現裁「留空」可先行,與 PM 議定後若補範圍另起增量);D13 → T-3.2 精靈流程(.3 棒實作前公司裁決)。D12 的進版與推 Harbor 屬出貨動作,掛 T-2.6 前後執行。
DB 先用暫行手段(如手動 restore)驗通拓撲,正式空庫 init 屬 .2。
| # | 子任務 | 驗收 | 依賴 |
|---|---|---|---|
| T-1.1 | 產品 compose 全 stack 骨架:guidant-db(postgres:16 顯式 initdb args+healthcheck)+guidant-redis(ACL user 形式)+BE api/socketio(既有定式 7 掛載/read_only/machine-id 全保留)+depends_on healthcheck 鏈+自備 DB/Redis 註解引導+recreate 風險防護 |
乾淨機器 docker compose up -d 全組 healthy |
—(✅ done 2026-08-17) |
| T-1.2 | nginx.onprem.conf:同源反代(/api/1.0、/socket.io 含 WS upgrade)+resolver 動態解析+timeout 調校+SPA try_files+443 憑證掛載(掛載路徑約定+80→443 轉址;憑證產生在 T-2.5,本卡開發驗證可自簽一張) |
反代全路由通;BE restart 後不 502;自簽憑證 HTTPS 下登入通(secure context 驗證) | T-1.1(✅ done 2026-08-17) |
| T-1.3 | FE production image:Dockerfile ARG NGINX_CONF 換入 onprem conf+build:PRD;查清 VITE_DEV_MODE/VITE_TURNSTILE_SITE_KEY 語意並定值 |
image build 過、同源登入通;兩個 build-time 值有定案紀錄 | T-1.2(✅ done 2026-08-17) |
| T-1.4 | MinIO 選配段+mc init job(--ignore-existing 冪等) |
啟用選配段時 bucket 自動建成、重跑不炸 | T-1.1(✅ done 2026-08-17) |
| T-1.5 | .env 範本(零硬編憑證、踩坑清單照單全收)+暫行 DB(手動 restore)驗通全鏈 |
照範本填值、乾淨機器 FE 反代登入通 | T-1.1~T-1.3(✅ done 2026-08-17) |
| # | 子任務 | 驗收 | 依賴 |
|---|---|---|---|
| T-2.0 | DEV 資料庫清理非系統資料+序號歸位(出貨基線前置,CM-1266):照 db-init-inventory.md §3.3 清測試租戶 102/131/152/153/158 整族+業務資料全族+三張垃圾表 drop+NOTIFY_CONFIG 真實 secret 筆;保留 §3.1 字典與 root id=1;清完 reset sequences(腳本化逐 schema 掃 sequence 對 max(id));SQL 落 scripts/sql/ 標 dev 專屬;🔴 只動 DEV、清理前先 pg_dump 備份 | DEV 只餘系統資料;sequence 歸位;BE 起服務登入正常;基線 dump 可從此產出 | —(.2 最前置,T-2.1 的輸入)(✅ done 2026-08-17) |
| T-2.1 | 分段 init 腳本 00-cluster…99-stamp+init.sh:DEV pg_dump 整理(去殘留表/歷史分區)、default privileges+event trigger、RLS 107 條建齊、冪等判斷、收尾 stamp |
空庫跑完=schema 全建、cm_app 權限掃描零缺口(CM-1207 附錄語句)、baseline marker 落庫 | —(✅ done 2026-08-17) |
| T-2.2 | seed 落地依 D11:字典類 core seed+root tenant/org id=1+builtin BPMN;開工前與決策者核對 D11.2 清單、定 D11.5 labels;D11.3 現裁留空;CMMC/檢測 Profile 檔案打進 bundle(不 seed 資料列) | seed 冪等重跑不重複;出貨集與裁決一致 | T-2.1(✅ done 2026-08-17) |
| T-2.3 | D11.9 前置 migration:grep 全 codebase 確認 debug view 零引用→drop 兩支 view(DEV 先套,走 sql-migration 流程) | DEV 已 drop、基線 dump 自然不含 | —(✅ done 2026-08-17) |
| T-2.4 | one-shot init 容器(執行載體,與升級 migration 容器同形態):installer 產參數→起容器跑 init.sh→成功才起服務 | 服務容器全程只持 cm_app 憑證;init 失敗語意=整庫重建可重來 | T-2.1(✅ done 2026-08-17) |
| T-2.5 | install.sh:環境檢查清單→load+digest 比對→產雙密碼寫 guidant.env→openssl 產 per-install 自簽憑證(CN/SAN 填主機名/IP,落 T-1.2 約定路徑)→DB init→起 stack→尾端印 setup token(不建 admin);--config 非互動 |
空機一鍵裝到「服務全綠、待精靈設定」;digest 不符拒裝 | T-2.2/T-2.4、T-1.*(✅ done 2026-08-17) |
| T-2.6 | bundle 打包(docker save 全 image+manifest digest+SQL/seed/手冊骨架)+Harbor pull 替代路徑文件化+PROD 簽章鑰四步(LC 生鑰對→public_keys.py 新增 kid→重 build→出貨 image 含 PROD 鑰);D12 進版與推 Harbor 掛此段前後 | bundle 可完整離線裝機;PROD kid 驗章通過;版號已 bump、image 已歸檔 Harbor | T-2.5(✅ done 2026-08-17) |
| # | 子任務 | 驗收 | 依賴 |
|---|---|---|---|
| T-3.1 | BE:未初始化態偵測+setup token 驗證+建 admin 一次性通道(用後即封)+精靈用指紋顯示介面 | token 錯誤拒入;admin 建立後通道永久封閉;重放不可 | —(✅ done 2026-08-17) |
| T-3.2 | FE:設定精靈頁(token→建 admin→指紋顯示+複製→license 匯入引導復用 FR-062 開通頁→進登入頁)+root tenant 命名段(依 D13 裁決落法:命名 root 或改建第一個業務租戶) | 空機裝完→瀏覽器精靈建帳號→匯照開通全鏈通 | T-3.1(✅ done 2026-08-17) |
| T-3.3 | installer fingerprint 子命令:演算法與 machine_fingerprint.py 一字不差+兩邊同值驗證步驟 |
installer 與 BE 算出同一指紋;服務未起時仍可查 | —(✅ done 2026-08-17) |
| T-3.4 | install.sh --upgrade 四步+align_migrations 演算法移植(連線外注、bundle 帶 SQL/manifest、schema_migrations 判起點)+相容性檢查 v1+回滾語意(restore+回 tag,災難逃生明文) |
舊版→新版升級通;區間不符拒跑;回滾後系統可用 | T-2.6(✅ done 2026-08-17) |
| T-3.5 | Turnstile 停用落地(BE/FE 一對開關,查清現況補齊缺的)+完整外連盤點收進手冊素材 | air-gap 下登入不失敗;外連清單成文 | —(✅ done 2026-08-17) |
.4 前置待收(2026-08-18 排程重整):CM-1235(PyMuPDF AGPL 替換,出貨合規硬前置)/CM-1273+CM-1269(install log 落檔+系統檔修復,併棒)/CM-1275 驗收/CM-1270 真機複驗。
| # | 子任務 | 驗收 | 依賴 |
|---|---|---|---|
| T-4.1 | 客戶安裝手冊:安裝/開通/升級/回滾/宿主前提/外連清單與停用法/自備 DB-Redis 指引 | 一般 IT 人員照手冊可自助完成 | T-3.* |
| T-4.2 | 乾淨主機端到端真機驗收:§6 全鏈場景+負面案 | 全鏈真機走一遍、負面案全數如預期拒絕 | T-4.1 |
| T-4.3 | ⏸ 本次範圍跳過(2026-08-18 裁示,有真實 Windows 需求時再啟動)——Windows 評估文件(D9):WSL2 machine-id 行為、Docker Desktop licensing、效能界線——不實作不承諾 | 評估文件+前提清單成文 | — |
子需求卡:CM-1275(https://app.notion.com/p/FR-065-5-SeaweedFS-PDF-3c0346da4cd081468eede5e4e735d994)
| # | 卡 | 子任務 | 驗收 | 依賴 |
|---|---|---|---|---|
| T-5.1 | CM-1276 | jedi-file-upload 加 SEAWEEDFS 正式 storage type(adapter 繼承 MinIO 版、factory 註冊、DTO)+主專案 _build_adapter 分支+順修 delete_files_by_uids bug(字串 list→DeleteObject list,含突變驗證);poetry path dependency 開發、發版等 user 明示 |
對 SeaweedFS put/get/單刪/批刪 roundtrip 通過;既有 minio type 不變 | — |
| T-5.2 | CM-1277 | compose 移除 MinIO 選配段、加 guidant-seaweedfs 常駐服務(seaweedfs:3.99 單機 server+S3 gateway、healthcheck、s3.json 掛載、不對外開 port);install.sh 產 S3 憑證+bucket 初始化+storage-seed/ 原 key 灌回(冪等);基線 SQL 5d 段改 root STORAGE_CONFIG 指向內建 SeaweedFS(key 由 install.sh 裝機寫入) |
乾淨機器裝完五+一服務全 healthy、上傳下載通、storage-seed 灌回後框架 PDF key 皆存在 | T-5.1 |
| T-5.3 | CM-1278 | build_bundle.sh 加 seaweedfs image(save+digest)+storage-seed/ 打包段;基線產製 SOP 補「臨時 SeaweedFS→匯 CMMC→bucket 匯出」流程;手冊「更換儲存後端」警語素材(系統檔切換即斷為重點)交 T-4.1 | bundle 內容物齊;SOP 照走可產出含框架 PDF 的完整 bundle | T-5.1/T-5.2 |
派棒註(2026-08-18):CM-1280(T-2.5e compose log rotation)併入本棒排最前(同動 compose 檔避免互踩)——執行序 CM-1280 → T-5.1 → T-5.2 → T-5.3。
follow-up(不擋 .4、出貨後另做):CM-1279 儲存後端遷移工具——掃 upload_files 異型列(含 system-scope 最優先)→讀舊寫新→checksum 過才 UPDATE→冪等續跑(同 CM-1267 性質)。
188 真機首測(見 §6)撞出的問題與決策者追加需求,成三張追補卡:
| # | 卡 | 內容 | 狀態 |
|---|---|---|---|
| T-2.5b | CM-1270 | install.sh 修補四件:①開頭即要求 sudo(root 化後目錄/擁有者腳本自設,零手動)②既有安裝偵測(資料目錄含 guidant.env/certs 即停下警告不覆寫)③資料目錄改名 /srv/guidant-ai(與家族命名對齊,188 現役 /srv/guidant 不動)④追加維運子命令 start/stop/restart/status/logs/uninstall(各自帶 --env-file、uninstall 需輸入固定確認字串且不刪 image) |
✅ done 2026-08-17 |
| T-2.5c | CM-1271 | 憑證管理三件:credentials 查看匯出(--export 供登錄密碼保險庫)/rotate-credentials 輪換 DB 兩組+Redis 密碼(JWT 與加密金鑰不納入)/--config 選填自帶密碼(留空=自產,互動模式不變) |
🔶 進行中 |
| T-3.2b | CM-1272 | 開通成功後自動重抓功能選單——授權資訊不在 JWT 內,開通完自動重抓選單即時從 3 項變 28 項、不必重登;重抓失敗退回「重新登入」按鈕引導 | ✅ done 2026-08-17 |
乾淨機器全鏈場景:
up -d 全組 healthy→印出精靈網址+setup token.license→進登入頁→登入後全功能可用(license 軸外不再 403)--upgrade→備份→migration→recreate→healthcheck 全綠、資料保留負面案:
/etc/machine-id 缺檔或空檔→環境檢查即擋下(不進入安裝,避免指紋漂移事故)--upgrade 拒跑真 bundle(--skip-prod-key-check 測試包)於 188 走通全鏈:install.sh 裝機→Web 精靈建租戶與 admin→機器指紋(installer 與 BE 兩邊算出同值)→LC STG 簽照(issue→activate 離線開通)→匯照開通→功能可用。首測撞出的問題已成三張追補卡(T-2.5b/T-2.5c/T-3.2b,見 §5「追補卡」節)。
2026-08-17 首腦登記(CM-1189 母卡),決策者帶公司議,T-4.1 手冊成文前需定案:
以上皆為 .4 前置。剩餘未決(2026-08-18 盤點):第 1 題 AI 功能/第 2 題 Drive OAuth/第 4 題三件出貨動作(第 3 題已收口、第 5 項已排棒)。