使用者手冊 · 更新於 2026-06-27

在證據可見的前提下操作 CMS 平台。

本手冊已加入 2026-06-27 正式部署增補:後端、CMS 與 web 已在 GCP Cloud Run run.app 上線,搭配 Cloud SQL PG17、Upstash Valkey TLS、Secret Manager 與宣告式 Terraform IaC。正式 Cloud SQL 上的 shared-table RLS 也已完成佈建並接入後端。下方截圖仍是既有 2026-06-16 本機視覺證據與 2026-06-21 受治理金流截圖;本次新增的是部署狀態,不是新的正式環境截圖證據。

3個 Cloud Run 服務上線
41張 RLS FORCE 資料表
3個網域憑證佈建中
0張新增截圖
增補 · 2026-06-27

正式部署狀態 — GCP Cloud Run 已上線,RLS 已接入(無新增截圖)

平台現在具備受管理的正式部署路徑:後端、CMS、web 使用 GCP Cloud Run;資料庫為透過 Auth-Proxy unix socket 存取的 Cloud SQL PG17;快取為 TLS 連線的 Upstash Valkey;密鑰在 Google Secret Manager;並建立 apiwwwadmin 的 Cloud Run domain mappings。本次手冊更新記錄部署狀態與操作邊界,不取代既有本機/manual 截圖。

LIVE · Cloud Run

執行期與 IaC 權威

後端以 prd 啟動、GraphQL 回應 HTTP 200,並觀察到 Cloud SQL + Upstash 連線。CMS 與 web 在 run.app 上健康。infra/terraform/envs/gcp-cloudrun/ 是宣告式權威;實際後端資源已 import 並 0-destroy reconcile。

LIVE · RLS 已佈建

Shared-table RLS 不再只是本機證明

正式 Cloud SQL 現在有 cms_tenant_app 非 superuser app role、41 張資料表 ENABLE+FORCE RLS,且 verify-rls PASS。後端 env/secrets 已透過 Secret Manager 接入 SCHEMA_TIER_APP_USER / password。

待完成

自訂網域與公開網域查核

apiwwwadmin 的 Google-managed certificates 仍在佈建。因此本手冊尚不宣稱自訂網域端到端瀏覽器證明,也不宣稱公開網域 /mcp 跨租戶證明。

未宣稱

延後的執行期表面

Worker runtime、AGE/GraphRAG、多區域與 UAT sign-off 不屬於本次證據。既有截圖維持 predecessor/local 證據;金流捐款截圖則保留其受治理 browser-full-integration 層級。

權威來源:.agents/specs/production-deployment-topology/{review.md,adr/ADR-DEPLOY-003-gcp-cloudrun-cloudsql-cloudflare.md}.agents/specs/{SPECS.md,NEXT_STEPS.md,RTM.md,ISSUE_LOG.md}、以及 infra/terraform/envs/gcp-cloudrun/品牌:已套用 provisional NAELT CIS 紅/灰/橙色票。
增補 · 2026-06-24

韌性與 fail-closed 強化(無新增截圖)

一批後端/測試層級的正式環境就緒工作以多個 PR(#107/#108/#110/#111/#112/#113)提交至 dev,以可執行的 chaos 與 fail-closed 測試強化平台的失效行為,並修復過程中發現的一個真實接線缺陷。這些變更的是後端行為而非操作畫面,因此下方截圖仍然成立;此為依據 spec/PR 的內容說明,並非重新執行期擷取。對操作者的實際效果是:訊息/金流 webhook 在並發洪峰下能安全去重、資產上傳與 AI 生成皆 fail-closed(不留孤兒記錄、不洩漏 DB 連線),且 AI 配額在真正的交易路徑上獲得驗證。

  • Webhook 洪峰並發去重(REQ-RCC-006,PR #113) — 於受管控的 PostgreSQL 驗證:對同一則 provider 訊息發出 8 個並發 IngestMessage → 僅有一筆草稿與一筆日誌留存,其餘去重且無孤兒記錄。封閉最後一個相鄰相依的 chaos 缺口。
  • AI 生成交易洩漏修復(PR #110) — 無效的生成型別過去會在未回滾已開啟交易的情況下返回,緩慢洩漏連線池中的 DB 連線;現已修復並加上回歸守門測試。
  • Fail-closed 覆蓋鎖定(PR #104/#107/#108) — 交易範圍內的 AI 配額強制、GraphRAG 在 embedding provider 失效時降級、以及資產儲存後端失效時 fail-closed(不留孤兒資產記錄)。
  • 決策邏輯覆蓋(PR #111/#112) — 推薦排序(行為權重 × 時間衰減)與 MCP 連線池 LRU 淘汰,兩者先前皆未受測試守護。
證據來源:依據 spec/PR 的測試(此增補無執行期截圖)。 覆蓋層級:unit + property + 手動擊殺變異 + 自包含與受管控 PostgreSQL chaos/resilience。 就緒狀態:僅本機證明;無受管控 bundle 瀏覽器、真實外部 provider/OAuth/AI、託管 Postgres、多節點/真實映像 HA、DNS/TLS/部署/UAT/正式環境。 權威來源:.agents/specs/resilience-chaos-coverage/review.mdISSUE_LOG.mdCHAOS-COVERAGE-EXT-001 已解決)、backend/test/TESTS.md、PR #104/#107/#108/#110/#111/#112/#113。
增補 · 2026-06-18

正式環境就緒強化(無新增截圖)

一條後端/設定層級的強化工作以 PR #71 形式提交至 dev,源自一次全庫 mock/stub/false-green 稽核(prod-readiness-wireup-hardening)。它變更的是安全性與接線行為,而非操作畫面,因此下方截圖仍然成立;此為依據 spec/PR 的內容說明,並非重新執行期擷取。

  • 租戶資料庫連線在正式環境改為 fail-closed。站台(租戶)資料庫連線過去在正式環境可能退回預設帳密與非 TLS;現在當 ENV=production 時會拒絕預設帳號/密碼並要求 TLS(require/verify-ca/verify-full),與平台資料庫的驗證一致。本機/開發行為不變。
  • AI provider 金鑰改為僅伺服器端。CMS 不再讀取 NEXT_PUBLIC_*_API_KEY(會把密鑰打包進瀏覽器);產生內容改走後端 BYOK 路徑,且管理端 endpoint 退回機制會在 Vercel 式正式環境標記下 fail-closed。
  • 真實相依的健康檢查證據。一個空的占位測試被替換為真實的 chaos/resilience 測試,證明 Postgres 當機會回報 HTTP 503(unhealthy)且有界(不會卡住)。
  • 文件校正。低估了已實作成熟度的模組指南(OAuth Google/Facebook/Microsoft/Cognito + SAML + LDAP、storage S3/GCS/Azure/R2/local、真實 data-binding)已更正。
  • 故障注入下的可靠性已證明(PR #72–#74)。新增 chaos/resilience 測試證明平台會有界地優雅降級、絕不卡死:連線池耗盡時不超過上限且能恢復;租戶資料庫短暫中斷不會被快取、資料庫回來後路由自我修復;AI provider 卡住時以有界的具型別錯誤失敗(客戶端逾時為有限值)。
  • 輸入清理器與 fail-closed 守衛已鎖定(PR #75–#77)。名稱→租戶 ID/資料庫名稱清理器,以及正式環境帳密/TLS fail-closed 守衛,新增 property-based + 接線測試,避免未來變更悄悄削弱「使用者輸入與資料庫名稱之間唯一防線」或重新開啟不安全連線路徑。
證據來源:依 spec/PR 的測試(本增補無執行期截圖)。覆蓋層級:unit + property-based + 人工擊殺 mutation(後端)+ vitest/tsc(cms)+ 自足式與受治理 PostgreSQL chaos/resilience。就緒狀態:僅本機證明;無受治理 bundle 瀏覽器、真實外部 provider/OAuth/AI、託管 Postgres、多節點/真實映像 HA、DNS/TLS/部署/UAT/正式環境。權威來源:.agents/specs/{prod-readiness-wireup-hardening,resilience-chaos-coverage}/review.mdRTM.md、PR #71–#80。
補充 · 2026-06-21

金流 / 捐款 / 電商(已於瀏覽器驗證)

一個通用、site-scoped 的金流 / 捐款 / 電商模組已以 PR #86 併入 devpayment-plugin)。捐款只是通用 Payment* 核心的其中一個 purpose 預設。以下是直接由 DB 頁面資料、對真實後端渲染的捐款頁。

公開捐款表單 — PaymentForm(DB 驅動)

已 seed 的 NAELT /site/naelt/support/donate 頁完全由 DB 頁面資料渲染通用 PaymentFormdonation-form manifest 預設):預設金額、自訂金額、付款人欄位,以及由供應商驅動的送出(Stripe 轉址 / 藍新金流 form-post)。密鑰不會進入瀏覽器 — 後端依 siteID 解析該站的 BYOK 供應商。

由 DB 驅動頁面資料渲染的公開捐款 PaymentForm
證據來源:受治理的 multi-tenant web 環境、真實後端(MSW 關閉)、Playwright 2/2。覆蓋層級:browser-full-integration。就緒狀態:DB→manifest→PaymentForm 渲染與即時 seed 預設金額 PASS;無真實外部供應商結算。

CMS 後台 — 捐款與金流 + 商品與服務

CMS 設定頁新增 捐款與金流 分頁(供應商型錄、引導設定 精靈、遮罩 BYOK 密鑰輪替、捐款/訂單清單 + ezPay 電子發票狀態)與 商品與服務 分頁(型錄 CRUD、SKU 變體、Udemy 式數位內容編輯:公開預覽 vs 付費)。後台 GraphQL 受 RBAC 控管(site.payment.* / site.catalog.*)。

證據來源:受治理的 cms-e2e bundle、真實 /api/auth/login + 真實 GraphQL(MSW 關閉)、Playwright 3/3(即時供應商型錄、型錄分頁、viewer 被拒)。覆蓋層級:browser-full-integration。就緒狀態:後台分頁 PASS;後台主動退款 + 真實結算為殘留項(ISSUE_LOG.md PAY-REFUND-001)。

能力 8 — 金流 / 捐款 / 電商。 通用公開 createPaymentCheckout(purpose) + 供應商註冊表驅動(Stripe Checkout 一次性 + 訂閱;藍新金流 MPG 2.0 + 定期定額)+ ezPay 電子發票自動開立 + BYOK 各站密鑰 + 商品/服務型錄 + 數位授權(付款後自動授予、fail-closed 存取);donation-form page-builder 元件渲染通用 PaymentForm;單一掛載開關 PAYMENT_MODULE_ENABLED。權威:.agents/specs/payment-plugin/review.md、PR #86。

操作範例 · 2026-06-18

平台能力 — 端到端詳細範例

showcase 租戶作為標準範例(其首頁 + /components 元件展示頁已涵蓋全部 11 個 page-builder 元件),提供平台「內容創作與執行期」能力、依真實契約撰寫的詳細範例。證據層級:依真實 GraphQL/路由/manifest 契約撰寫的示意範例(後端/CLI 層級的命令與 payload 證據), live-demo 截圖;各能力下方標註 claim-cap。就緒與否的權威仍為各 spec 的 review.md

1. 頁面建構器(manifest 驅動、DB 儲存、免重建)

頁面是 sections 陣列;每個 section 指定一個來自 component-manifest SSOT 的元件(componentManifests GraphQL ← backend/internal/componentmanifest/manifests.json)與其 props。CMS 的 Pages 建構器編輯 sections,並以 updatePageSections(id, sections: [JSON!]!) 整個 section 陣列覆寫儲存。公開路由為 force-dynamic,因此把已註冊元件加到頁面是 純 DB 資料變更 — 不需重建映像

# showcase 首頁由這些 manifest 元件組成(backend/seeds/showcase-pages.json):
HeroSection · FeatureGrid · ContentList · EventSection · ImpactStats · CTASection
# /components 展示頁額外示範:
ResourceGrid · ContentSection · EnhancedContentList · EnhancedEventCalendar

# 儲存已編輯頁面(整陣列覆寫)— 來自 CMS 頁面建構器:
mutation { updatePageSections(id: "<pageId>", sections: [ /* 完整且有序的 section 陣列 */ ]) { id } }

Claim-cap:經 manifest 驗證的 section 創作;加入已註冊元件為 runtime-proven 的純 DB 操作;不含新元件的重建路徑。權威:shadcn-component-library-a2ui-authoring/review.md

2. AI 內容生成(後端 BYOK)

生成在伺服器端透過 generateAIContent(prompt, providerId) 執行;CMS 不在瀏覽器持有 provider 密鑰(見 2026-06-18 安全強化)。每個站台宣告自己的 provider 設定檔(Google Vertex/Gemini、AWS Bedrock、Azure AI/OpenAI、OpenAI、Anthropic、TensorZero、OpenCode),含 BYOK 密鑰 metadata 與用量帳本。

mutation { generateAIContent(prompt: "為我們的新工作室撰寫一篇上線部落格文章", providerId: "") { content model tokensUsed } }
# providerId "" = 使用站台預設設定檔;後端解析 BYOK 金鑰,瀏覽器永遠不接觸金鑰。

Claim-cap:後端路由的生成契約;本手冊不含真實外部 provider 呼叫。權威:site-byok-ai-provider-settings/review.md

3. 內容管理(內容型別 · 草稿/發布 · 表單投稿 · RBAC)

內容以內容型別建模,並經 draft → published → unpublished 狀態生命週期(依狀態列表)。公開表單投稿進入受治理的投稿流程(送出 → 核准/退回)於 CMS 審核。每個操作皆經權限檢查(例如 site.content.*site.social.read/manage)。

# 公開站台表單區塊(showcase /contact)→ 後端發出 submissionId → CMS 審核佇列(核准/退回)。
# 內容列表/詳情頁依 contentType(article/event)透過 ContentList/ContentSection 渲染 DB 內容。

Claim-cap:草稿/發布廣度 + 投稿流程於 unit/後端層級證明(LAUNCH-007);受治理 bundle 執行時,CMS 審核為 backend-backed。

4. MCP 與 Agent 友善介面

每個站台提供 agent 友善的讀取介面:Model Context Protocol 端點 /mcp(list/get/search contents)、MCP 探索文件 /.well-known/mcp.json、以及每站台與平台層級的 llms.txt。非 VIP 租戶的讀取在啟用 SCHEMA_TIER_APP_USER 時由 D2 Row-Level Security(路由的非超級使用者角色)限制。

# 透過 MCP(HTTP/JSON-RPC)探索 + 讀取站台:
GET /.well-known/mcp.json        # server 描述
POST /mcp  → tools: list_contents(site) · get_content(site, slug) · search_contents(site)
GET /site/showcase/llms.txt      # agent 友善站台摘要

Claim-cap:/mcp 讀取路徑於完整本機 stack 為 backend-backed,且以非超級使用者角色於受治理 PG 受 RLS 限制;雲端部署/UAT 仍為 owner/infra(SPTR-LIVE-WIRING-001)。權威:schema-per-tenant-routing-rls/review.md

5. Agent Skills(每站台宣告式 skill 範本)

站台定義宣告式 skill/prompt 範本internal/skilltmpl;seeds skills-platform.json/skills-naelt.json)用於轉換/優化內容 — 無腳本/程式碼執行、無 sandbox。範本有版本控制,透過 upsertSkillTemplate 管理(建立 ⇒ v1;更新 ⇒ 版本遞增;已發布範本不可變;跨站台 fail-closed;@requirePermission("site.social.manage"))。

mutation { upsertSkillTemplate(input: { id: 0, kind: "post-conversion", name: "LINE→部落格", body: "..." }) { id version kind } }
# id:0 → 建立版本 1;id>0 → 更新 + 版本遞增。

Claim-cap:宣告式範本契約(無程式碼執行);service + RBAC 於 enttest 層級證明。權威:messaging-ingest-social-publishing/review.md

6. A2UI(agent 透過 manifest 創作頁面)

A2UI agent(backend/internal/adk)從同一份 component-manifest 目錄創作 page-builder sections,經 manifest 驗證關卡 + design-contract「不杜撰事實」誠實邊界 + 不可信內容邊界。它提出符合 manifest 的 sections,由你透過正常的 updatePageSections 儲存 — 因此 agent 產出與人工頁面建構編輯受完全相同的契約約束。

# A2UI 流程:目錄提示(componentManifests)→ agent 提出 sections → manifest 驗證關卡
#            → design-contract 誠實檢查 → 人工審核 → updatePageSections(儲存)。

Claim-cap:經 manifest 驗證的創作 + 誠實邊界於 unit/contract + dev-web 瀏覽器層級證明;不含 live-LLM 往返主張。權威:shadcn-component-library-a2ui-authoring/review.md

7. 社群媒體 — 完整流程(接收 → AI 轉換 → 審核 → 發布)

平台無關、整合優先的管線(messaging-ingest-social-publishing):入站訊息進入單一標準 webhook、正規化、經站台 AI provider + 宣告式 skill 範本轉為貼文草稿、排入審核佇列,再透過可插拔 publisher drivers 發布。全程站台範圍 RBAC(site.social.read/manage/publish/secret);密鑰為站台 BYOK。

# 1) 接收 — providers 自我註冊;每平台/站台單一標準入站路由:
POST /api/webhooks/messaging/{platform}/{site}    # 例如 line、telegram、whatsapp(簽章驗證、fail-closed)

# 2) 轉換 — 正規化訊息 → 貼文草稿,經 SiteAIProviderResolver + 每站台 skill 範本(無 sandbox)。
# 3) 審核 — 草稿進入 CMS「Messaging & Social」審核佇列:
mutation { updatePostDraft(input: { id: "<draftId>", blocks: [...], metadata: {...} }) { id status version } }   # 已發布草稿不可變
# 4) 發布 — 透過可插拔 SocialPublisher driver(例如 Facebook Graph):
mutation { publishPostDraft(id: "<draftId>") { id status } }   # @requirePermission("site.social.publish")

Claim-cap:repo-local 整合功能 + 受治理 cms-e2e backend-backed Messaging & Social 瀏覽器 smoke(T16.6);不含真實 LINE/Telegram/WhatsApp 傳遞、真實 Facebook 發布、真實 OAuth、或 live-AI 品質。權威:messaging-ingest-social-publishing/review.md

證據來源:真實 GraphQL/路由/manifest 契約 + spec review.md(無新增執行期截圖 — 屬 worked-example/契約層級)。覆蓋層級:見上方各能力的 claim-cap(backend-backed、unit/contract、runtime-backed 混合)。就緒狀態:僅本機證明;無託管 Postgres、真實外部 provider/OAuth/AI、DNS/TLS/部署/UAT/正式環境。權威來源:.agents/specs/SPECS.mdRTM.md、以及上方引用的各 spec review.md
增補 · 2026-06-17

本次查核後新交付的後端工作(無新增截圖)

在下方 2026-06-16 執行期擷取之後,有兩條後端/API 層級的工作以 PR 形式提交至 dev。它們新增的是後端行為,而非新的操作畫面,因此本頁截圖仍然成立;此為依據 spec/PR 的內容說明,並非重新執行期擷取。

  • Spawn 現在會佈建 VIP 實體資料庫(PR #68)。先前一個已 spawn 的 VIP 站台只是指向「不存在的資料庫」的控制平面紀錄(這正是先前備份證明必須手動建立 cms_showcase 的原因)。SpawnSite 現在會為 VIP 站台建立實體 cms_<slug> 資料庫並將 schema 遷移進去;非 VIP(SCHEMA/D2)站台則依設計維持「僅紀錄」。失敗即關閉(fail-closed):若佈建失敗,會回滾站台紀錄,不留下懸空項目。
  • Messaging & Social 草稿/範本編輯 API(PR #69)。updatePostDraft(於發佈前編輯草稿的 blocks/metadata——已發佈貼文不可變更)與 upsertSkillTemplate(建立,或更新並遞增版本,技能範本)兩個 GraphQL 操作現已實作,皆以 site.social.manage 權限把關。CMS 內對應的編輯 UI 為已追蹤的後續項目。
證據來源:依 spec/PR 的後端測試(本增補無執行期截圖)。覆蓋層級:unit/property/mutation/enttest + 受治理 PostgreSQL 整合測試(spawn)。就緒狀態:後端行為已於本機證實;Messaging & Social 分頁的受治理 bundle 後端實證瀏覽器 smoke 為已追蹤殘留項。無 DNS/TLS/部署/UAT/正式環境。權威來源:.agents/specs/RTM.md(2026-06-17 lanes 1+2 rollup)、PR #68/#69。

開始上手/起步素材

請優先使用已納管的 seed/demo 資料。請勿自行捏造一次性的手動範例。

Seed 資料(4 個站台)

backend/seeds/{platform,naelt,showcase,tenant-demo}-*.json 提供頁面、內容、提交類型、主題、導覽與技能。tenant-demo 帶有 "tenancyTier":"schema",因此會以非 VIP 站台的形式進行 seed。使用 python scripts/ops.py db seed {platform|naelt|showcase|tenant-demo} 進行 seed。

E2E 範例資料

scripts/seed_e2e_data.py / scripts/seed_e2e_data.sql 記載了可重複測試/demo 流程所需的標準角色與範例租戶(8 個執行期使用者:platform_admin、site_admin、editor、viewer、MFA、兩位租戶管理員)。標記為 MOCK-DEV-ONLY-* 的密碼絕非正式環境憑證。

最新素材

最新的截圖與 CLI 文字記錄存放於 docs/manual/assets/,命名為 *-manual-2026-06-16.png*-cli-2026-06-16.txt,於 2026-06-16 從執行中的本機堆疊(真實資料/API)擷取。

核心操作者流程

除非已明確指定並佈建了正式環境目標,否則請在本機執行期上依循這些路由。

CMS 儀表板導覽

開啟 http://localhost:23000,透過設定好的流程驗證身分,並確認儀表板範圍。平台管理員會看到平台控制平面外殼,內含平台站台指標(現在共 4 個站台)、最近活動 (Recent Activity) 與快速操作 (Quick Actions);站台管理員則看到站台範圍的工作區。範圍權威來自已驗證的角色與當前的 site/tenant 情境,而非視覺提示。

CMS platform dashboard current runtime screenshot
證據來源:本機 CMS 執行期、CMS 驗證 API cookie 啟動。覆蓋層級:hybrid。就緒狀態:儀表板可見性為 PASS,並非完整的瀏覽器登入證明。

Manifest 驅動的頁面建構器(Pages)

開啟 http://localhost:23000/pages。此清單是進入 manifest 驅動頁面建構器的入口:每頁的版面 (Layout)(default / content-detail / event-detail)、狀態、依標題/slug 搜尋、狀態與版面篩選,以及每列的 預覽/編輯/刪除。把一個已註冊的平台元件加入頁面屬於資料庫資料變更——不需要重建前端。

CMS Pages / manifest-driven page builder current runtime screenshot
證據來源:本機 CMS 執行期截圖(cookie 啟動)。覆蓋層級:hybrid。就緒狀態:已 seed 的 Pages 介面為 PASS;即時頁面儲存/發佈與 A2UI apply 屬於獨立的工作流程證明。

公開平台首頁(shadcn / Tailwind v4)

開啟 http://localhost:23001/site/platform。此 seed 支援的行銷介面建立在 shadcn/Tailwind-v4 基礎上:漸層 hero、功能格、上手步驟、平台指標與 CTA 區塊。

Platform homepage current runtime screenshot
證據來源:本機公開截圖。覆蓋層級:本機瀏覽器路由證據。就緒狀態:有樣式的公開渲染為 PASS;正式環境的視覺/SEO/CDN 仍屬獨立項目。

非 VIP 站台 — tenant-demo(SCHEMA 層級 · D2 共用資料表 RLS) 新增

開啟 http://localhost:23001/site/tenant-demo。這第四個 seed 站台為非 VIP (non-VIP):其內容存放於共用平台資料表中,並透過以站台 slug 為鍵的 PostgreSQL Row-Level Security 進行隔離(即「D2」模型),而非存放於專屬資料庫。它的渲染與 VIP 站台完全相同——證明此隔離模型對終端使用者而言是不可見的。

tenant-demo non-VIP schema-tier public site current runtime screenshot
證據來源:已 seed 之非 VIP 站台的本機公開截圖。覆蓋層級:本機瀏覽器路由證據。就緒狀態:已 seed 的非 VIP 渲染為 PASS;公開讀取路徑於請求時的即時 RLS 路由受主機/部署條件限制(見主機預檢)。

Showcase 站台(第三個 seed 站台)

開啟 http://localhost:23001/site/showcase——「Showcase Studio」,一個獨立的 DB 驅動 demo 站台,證明可透過 site config/theme/page seed 從單一程式碼庫交付多站台。

Showcase site home current runtime screenshot
證據來源:本機公開截圖。覆蓋層級:本機瀏覽器路由證據。就緒狀態:已 seed 的多站台渲染為 PASS。

平台聯絡流程

開啟 http://localhost:23001/site/platform/contact 以檢視平台的公開提交路由。

Platform contact current runtime screenshot
證據來源:本機公開截圖。僅為路由渲染;提交/回讀的廣度不會因此截圖而升級。

NAELT 志工報名

開啟 http://localhost:23001/site/naelt/volunteer/register。已 seed 的 manifest 會渲染繁體中文欄位群組(志工報名)與必填欄位。

NAELT volunteer form current runtime screenshot
證據來源:本機公開截圖。覆蓋層級:路由/表單渲染。提交成功/管理員審核屬於獨立的工作流程證明。

租戶生命週期與 DR 管理

平台從單一 VIP 旗標決定每個站台的資料隔離架構:VIP ⇒ database-per-tenant(站台取得自己的實體資料庫);非 VIP ⇒ 共用資料表 Row-Level Security(即「D2」模型——共用資料庫與 schema,以站台為鍵透過 RLS 隔離,並於執行期透過非 superuser 的應用程式角色強制執行)。VIP 目前由平台控管。

平台超級管理員 —「Sites & DR」(CMS /platform/sites

平台超級管理員開啟 http://localhost:23000/platform/sites,即可從單一表格管理所有站台。每一列顯示站台、VIP 星號、層級 (tier)(SCHEMA 或 DATABASE)、base URL,以及自訂網域驗證狀態。每列操作:

  • 設定/移除 VIP — 開啟一個確認對話框,說明它會自動遷移架構:將站台設為 VIP 會將它移至自己的實體資料庫;移除 VIP 則會將它降級回共用 schema + RLS。此遷移會執行一個故障安全的 pg_dump/restore 序列(佈建目標、複製、驗證,最後才刪除來源)。注意 tenant-demo 顯示設定 VIP,而三個 DATABASE 站台顯示移除 VIP
  • 關閉 (Close) — DR 安全的退役。它要求輸入站台 slug 以確認,並在刪除前先將站台備份。沒有預設為 true 的意外確認。
  • 驗證 (Verify) — 驗證一個待處理的自訂網域(檢查所需的 DNS-TXT 記錄)。

Spawn siteBackup(configure/run/restore-test)操作呈現為停用狀態——那些操作尚未可用。

Platform Sites & DR admin table with 4 seeded sites including a SCHEMA-tier non-VIP site
證據來源:本機 CMS 執行期截圖,hybrid 驗證(cookie 啟動),顯示 Sites & DR 表格含 4 個真實 seed 站台——三個 DATABASE/VIP 與一個 SCHEMA/非 VIP(tenant-demo覆蓋層級:mocked-GraphQL 元件層級 + 本次 hybrid 後端支援的擷取。就緒狀態:管理介面為 PASS;並非完整的後端支援瀏覽器 e2e。

租戶管理員 —「DR & Domain」(CMS /settings/dr

站台/租戶管理員開啟 http://localhost:23000/settings/dr 以管理自己的站台。層級 (Tier)VIP 顯示為唯讀(由平台控管;若要變更,請聯絡平台)。此面板也顯示 base URL自訂網域 DNS-TXT 驗證狀態,再加上一個 URL 設定表單:選擇站台的存取方式——子網域(slug.platform)、路徑 fallback(platform/slug),或選用的自訂網域——並儲存。

注意:目前四個 seed 站台都將其網域設為 none,因此待處理網域的「驗證」功能仍未被 seed 演練;而本次未擷取每租戶的 /settings/dr 面板(見差距)。

主機預檢與部署操作者流程 新增

後端/CLI 介面(無瀏覽器)。在將非 VIP 讀取路徑指向任何 PostgreSQL 主機之前,你要先確認該主機能滿足 D2 模型,然後執行單一的冪等佈建腳本。此處的證據是命令文字記錄,而非截圖。

1 · 能力預檢 — migrate db-doctor

對任何候選 Postgres 執行,以確認它能執行 D2 讀取路徑(建立一個非 superuser 的應用程式角色,並讓 FORCE RLS 確實將其侷限),以及它是否具備執行期 GraphRAG 所需的 pgvector + Apache AGE(屬建議性質——它們的缺席不會阻擋 D2)。db-doctor inspect 為唯讀;預設模式會執行一個用完即丟的角色往返。對照受治理 PG15 的文字記錄:

$ migrate db-doctor
ℹ️  [INFO] server-version       PostgreSQL 15.18
✅ [PASS] privileged-role-can-create-app-role
✅ [PASS] app-role-is-non-superuser
✅ [PASS] app-role-non-bypassrls
✅ [PASS] force-rls-confines-app-role
⚠️  [WARN] tls                  NOT using TLS — set sslmode=require for a hosted DB
ℹ️  [INFO] max-connections      max_connections=100
⚠️  [WARN] extension:age        age NOT available — runtime GraphRAG cannot run here
⚠️  [WARN] extension:vector     vector NOT available — runtime GraphRAG cannot run here

✅ HOST OK for the D2 shared-table-RLS read path (advisory WARN items do not block D2).
證據來源:對照受治理 PG15 的真實 CLI 文字記錄(docs/manual/assets/host-doctor-cli-2026-06-16.txt)。覆蓋層級:backend-tool-cli/runtime-backed。就緒狀態:此主機具備 D2 能力;GraphRAG 在此資料庫上屬建議性質而不可用(無 pgvector/AGE)——這正是 doctor 存在所要凸顯的主機選擇訊號。

2 · 佈建 — scripts/provision_schema_tier_rls.py

單一冪等命令會佈建非 superuser 的應用程式角色、seed 非 VIP 站台、安裝共用資料表 RLS,並驗證隔離。先用 --dry-run 預覽確切計畫(印出命令 + 一個已遮蔽密鑰的 DSN,不執行任何動作):

$ provision_schema_tier_rls.py --dry-run tenant-demo
D2 shared-table RLS on host=db.example.com … password=*** sslmode=require | app_role=cms_tenant_app app_password=***

--dry-run: the following idempotent steps WOULD run (nothing executed):
  ▶ 1/4 provision non-superuser app role:  migrate provision-app-role
  ▶ 2/4 seed schema-tier site 'tenant-demo': migrate migrate tenant-demo
  ▶ 3/4 install shared-table RLS + grant:    migrate rls-rollout-shared
  ▶ 4/4 verify RLS isolation:                migrate verify-rls tenant-demo

執行期環境契約記載於 .env.schema-tier.example;經路由的 /mcp 公開讀取路徑僅在後端啟動時設定了 SCHEMA_TIER_APP_USER 時才會開啟(預設關閉/可逆)。部署後,一個部署後的 /mcp 跨租戶 UAT 冒煙測試(環境變數 MCP_UAT_BASE_URL)會對照真實 URL 確認隔離。

證據來源:真實 CLI 文字記錄(docs/manual/assets/provision-dryrun-cli-2026-06-16.txt)。覆蓋層級:backend-tool-cli/本機 runtime-backed。就緒狀態:此操作者流程在受治理 PG15 上為 runtime-backed;對照真實託管 Postgres 執行仍屬擁有者/基礎設施動作。

來源清單 (Source Manifest)

這些是本次手冊更新所使用的確切輸入。RTM.md 僅為可追溯性情境;spec 內的審查與執行期報告仍為證明權威。

來源使用方式
.agents/specs/{SPECS,NEXT_STEPS,ISSUE_LOG,RTM}.md2026-06-27 rollup — Cloud Run 部署、正式 Cloud SQL RLS follow-up,以及既有 D2/manual 證據。RTM 僅為 rollup,並非就緒權威。
.agents/specs/schema-per-tenant-routing-rls/{tasks.md (Slice 8), review.md, adr/ADR-RLS-002-NON-VIP-CANONICAL-D2.md}D2(非 VIP)標準模型 + 主機預檢區段中記載的主機預檢/dry-run/UAT-smoke/transaction-pool-safety 交付項目。RLS 僅在應用程式以非 superuser 角色連線時才會強制執行。
.agents/specs/tenant-lifecycle-dr-admin/{design-cms-ui.md, requirements.md, tasks.md}平台 Sites & DR 表格與租戶 DR & Domain 面板的 DR 管理 UI 形態。(此 spec 沒有 review.md — 依指南允許,退而採用 design/requirements/tasks 鏈。)
backend/seeds/{platform,naelt,showcase,tenant-demo}-*.json4 個 seed 站台的標準 seed/demo/範例資料(新的 tenant-demo 帶有 tenancyTier:schema)。
docs/manual/assets/*-2026-06-16.{png,txt}本次透過 scripts/capture_manual_2026_06_16.mjs 與 migrate CLI 從執行中本機堆疊擷取的 9 張最新截圖 + 2 份 CLI 文字記錄。
docs/MANUAL_GENERATION_GUIDE.md + 審查指南手冊工作流程與來源清單規則(已加入 2026-06-16 備註)。
docs/*FEATURE*.md本次此 repo 中沒有符合的檔案(依指南允許,清單退回 spec/report 鏈)。

自上次查核以來的差距與變更

對照 2026-06-15 的手冊版本。

本次已解決的差距(2026-06-16)

  • 非 VIP / SCHEMA 層級現已視覺演練:在 SCHEMA(非 VIP)層級 seed 了第四個站台 tenant-demo,因此 DR 管理表格現在會以真實資料顯示 SCHEMA 標章設定 VIP(相對於移除 VIP)的區別,且非 VIP 的 D2 公開站台會渲染/site/tenant-demo
  • 主機預檢操作工具已記載:全新的 migrate db-doctor 能力探測(含 pgvector/AGE 偵測)與 provision_schema_tier_rls.py --dry-run 計畫現以真實 CLI 文字記錄呈現。
  • Seed 命令已修正:scripts/ops.py db seed 原本呼叫舊的單檔 go run cmd/migrate/main.go(在 migrate 套件被拆成多個檔案後失效);已更正為 go run ./cmd/migrate,使 seed 再次可用。
  • 所有公開路由對照真實後端仍為 200,現在包含 /site/tenant-demo(共 6 條路由)。

仍存在的視覺差距

  • 待處理網域「驗證」+ /settings/dr 面板:四個 seed 站台都將網域設為 none,因此自訂網域的待處理/驗證狀態仍未被 seed 演練,且本次未擷取每租戶的 DR & Domain 面板。請新增一個帶有待處理自訂網域挑戰的站台。
  • Backup/spawn 停用:backup 與 spawn 操作呈現為停用(尚未建置)。
  • 未顯示具 GraphRAG 能力的主機:受治理的測試資料庫缺少 pgvector/AGE,因此 db-doctor 將它們顯示為建議性 WARN;尚未擷取兩者皆已安裝的主機。
  • Hybrid CMS 擷取 + dev overlay:CMS 截圖使用驗證 API cookie 啟動(hybrid),並非完整瀏覽器登入;CMS 擷取中出現一個 Next dev「1 Issue」overlay 標章(dev overlay,非產品缺陷)。

正式環境目標

target_id 仍未決定;後端主機尚未佈建;app/API 主機名稱缺少 DNS/TLS/部署綁定。

正式環境視覺/SEO/CDN

目前截圖為本機執行期擷取;正式環境的 DNS/TLS/CDN/快取失效與爬蟲廣度仍屬外部/最終關卡工作。

託管 D2 切換

D2 讀取路徑在受治理 PG15 上已端對端 runtime-backed,且主機預檢/操作者流程已建置,但對照真實託管 Postgres 執行(並確認透過公開網域的 /mcp)仍屬擁有者/基礎設施動作。

DR 管理證明層級

租戶生命週期 DR 管理 UI 在 mocked-GraphQL 元件層級 + 本次 hybrid 後端支援擷取下獲得證明——並非完整的後端支援瀏覽器 e2e。

瀏覽器登入廣度

CMS 儀表板/頁面建構器/DR 管理擷取使用驗證 API cookie 注入;屬 hybrid 證據,非完整瀏覽器登入。

即時頁面儲存/A2UI apply

頁面建構器截圖顯示已 seed 的 Pages 介面;即時頁面儲存/發佈與 A2UI agent apply 屬獨立工作流程證明,未在此擷取。