手冊首頁 / 溝通協作 / 問卷設計器

問卷設計器(Survey Designer)

功能群:問卷|資料模型與雙生命週期先讀 功能群總覽

事實基準:2026-07-05 從 FE(views/survey-v2/SurveyDesigner.vue 等)/ BE(api/survey、jedi-survey 套件)code 掃出;表結構取自 db_schema.jsonsurvey schema);error code 對 jedi_survey/common/enum/error_code.py

1. 功能描述

問卷設計器是單一問卷的內容編輯器:左欄維護頁面樹(章節),中欄編輯選中頁的題目——題型、選項、權重、必填、子題、流程規則。頂列可儲存、另存新版、發布、預覽。設計器編輯的是作者端範本is_snapshot=0);範本發布後才能被專案規劃頁的稽核任務綁定消費(綁定取快照,見 _overview §4)。

主要使用者:問卷範本作者(由問卷管理頁點「編輯」進入)。實際 endpoint 僅 @jwt_required(),無角色細分(見 §3)。

角色速覽(作者端以選單能力控管,見 _overview §5):

角色 一句話
問卷作者 由問卷管理頁進入;本頁全部編輯(endpoint 僅 jwt,無角色細分,見 §3)

1.1 功能總覽(本頁全部功能)

# 功能 說明 位置 詳述
1 載入問卷結構 GET 問卷含 pages / questions 樹 進頁 §6.2
2 頁面樹 遞迴樹、搜尋、選中頁;每頁顯示題數 左欄 §5
3 新增頁面 編號 / 排序 / 名稱 / 父頁 / 描述 左欄 → AddPageDialog UC-SVD-04
4 編輯 / 刪除頁面 右鍵選單;刪除連子頁 + 題目 CASCADE 左欄右鍵 UC-SVD-02
5 頁面排序 / 移動 拖動排序、改父頁(不可移到自己底下) 左欄 UC-SVD-02
6 題目清單 選中頁的題目卡(型別 / 必填 / 權重 / 選項預覽 / 子題) 中欄 §5
7 新增 / 編輯題目 三步精靈:基本 → 選項 → 進階 中欄 → AddQuestionDialog UC-SVD-01
8 題型 7 種:text / textarea / radio / dropdown / checkbox / fileupload / link 精靈步驟1 §1 表下
9 選項 + 補充輸入 選擇題選項含 label / 描述 / 補充輸入切換 精靈步驟2 §10
10 子題 題目掛在母題下(pid) 精靈步驟3 §9
11 流程規則 選某選項 → 跳某題(FE flowRules) 精靈步驟3 §12
12 題目排序 / 複製 / 移動 上下移、複製、移到他頁 題目卡操作 UC-SVD-02
13 儲存 就地更新(不動版本) 頂列 [儲存 ▾] UC-SVD-03
14 另存新版 保留舊版、同 group_id 新 version_no 頂列 [儲存 ▾] UC-SVD-03
15 發布 / 取消發布 release 頂列 UC-SVD-03
16 預覽 開唯讀預覽頁 頂列 ↗ 問卷填寫 / 預覽
17 問卷資訊設定 名稱 / 對象 / 有效期 / 發布 / 範本 / 描述 頂列 ⚙ dialog §6.2

題型(survey-mock-data.jstext 文字輸入・textarea 多行文字・radio 單選題・dropdown 下拉選擇・checkbox 核取方塊・fileupload 檔案上傳・link 連結。僅 radio / dropdown / checkbox 有選項步驟。

UC(§2)展開本頁所有具實質後端寫入的功能:新增頁面(3, UC-SVD-04)、頁面編輯 / 刪除 / 排序 / 移動與題目排序 / 複製 / 移動(4-5, 12, UC-SVD-02)、新增 / 編輯題目含選項 / 子題(7, 9-10, UC-SVD-01)、儲存 / 另存新版 / 發布(13-15, UC-SVD-03)。問卷資訊設定(17)走 UC-SVD-03 同一 PUT /survey/{uid} 存檔路徑,不另立 UC。純載入 / 顯示 / 導覽類(1 載入、2 頁面樹、6 題目清單、8 題型、16 預覽)見 §5 / §6 / 交叉連結;流程規則(11)由 FE 組成、BE 不驗證(§12 坑 6),無後端邏輯故不展開。

每個 UC 對應的 §1.1 功能:UC-SVD-01→7 / 9 / 10、UC-SVD-02→4 / 5 / 12、UC-SVD-03→13 / 14 / 15(含 17 資訊設定存檔)、UC-SVD-04→3。

2. Use Case

角色速覽(作者端以選單能力控管,見 _overview §5):

角色 一句話
問卷作者 由問卷管理頁進入;本頁全部編輯(endpoint 僅 jwt,無角色細分,見 §3)

流程圖視覺慣例:菱形 = 判斷、橘底 = 例外 / 擋下、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。

UC-SVD-01 新增 / 編輯題目(三步精靈)

項目 內容
角色 問卷作者
前置條件 已選中一個頁面
產出 / 後置條件 新增 → POST /survey-question;編輯 → PUT /survey-question/{uid}(部分更新);選項步驟僅選擇題型出現
uc_svd_01 UC-SVD-01 新增 / 編輯題目(三步精靈) start 選中頁面 → [+新增題目] / 卡片編輯 s1 步驟1 基本 編號·題目文字·說明·權重·必填·型別 start->s1 needopt 型別是 radio/dropdown/checkbox? s1->needopt s2 步驟2 選項 新增/編輯/刪除選項 (label·描述·補充輸入切換) needopt->s2 s3 步驟3 進階 父題(子題)·補充說明 流程規則(選項→跳題) needopt->s3 否(跳過選項步) s2->s3 submit 送出 s3->submit create POST /survey-question {page_uid,no,question,type,weights, sort,required,pid,options[],description} submit->create 新增 update PUT /survey-question/{uid}(部分更新) submit->update 編輯既有 ok mapQuestionFromApi → 插入題目卡 create->ok update->ok
UC-SVD-01:基本→(選擇題才有選項步)→進階→送出建立/更新題目

UC-SVD-02 頁面 / 題目樹操作(移動 / 刪除)

項目 內容
角色 問卷作者
前置條件
產出 / 後置條件 移頁到自己底下擋 SURVEY_409005;刪頁 = 硬刪除、子頁 + 題目 CASCADE(不可還原);排序 / 移動題目更新 sort / page_id
uc_svd_02 UC-SVD-02 頁面 / 題目樹操作(移動守門 · 刪除 CASCADE) movep 移動頁面(改父) POST /survey-page/move selfchk 目標父 = 自己 / 自己的子孫? movep->selfchk selferr SURVEY_409005 無法移動到自己底下 selfchk->selferr moveok 更新 pid selfchk->moveok delp 刪除頁面 DELETE /survey-page/{uid} delok 硬刪除頁面 子頁 + 題目一併 CASCADE (無 is_delete 欄、不可還原,§12) delp->delok reorder 排序 POST /survey-pages/reorder POST /survey-questions/reorder moveq 題目移到他頁 POST /survey-question/move
UC-SVD-02:移動守門 409005、刪除 CASCADE(頁 / 題無 is_delete)

UC-SVD-03 儲存 / 另存新版 / 發布

項目 內容
角色 問卷作者
前置條件
產出 / 後置條件 儲存 = PUT /survey/{uid} 就地;另存新版 = POST /survey as_new_version 保留舊版、URL 換新 uid;發布 = PUT .../release 後可被任務選用
uc_svd_03 UC-SVD-03 儲存 / 另存新版 / 發布 start 頂列 [儲存 ▾] / 發布⇄ save 儲存 PUT /survey/{uid} 就地更新、不動 version_no start->save newv 另存新版 POST /survey as_new_version=true + group_id 保留舊版、新增 version_no 列 start->newv pub 發布 / 取消發布 PUT / DELETE /survey/{uid}/release start->pub navnew URL 換成新版 uid (router.replace) newv->navnew pubok release=1 → 可被規劃頁任務選用 (/surveys/menu) pub->pubok
UC-SVD-03:儲存就地 / 另存新版換 uid / 發布可被任務選用

UC-SVD-04 新增頁面(章節)

項目 內容
角色 問卷作者
前置條件 已在設計器內(載入了一份問卷)
產出 / 後置條件 POST /survey-page 新增一列 survey.survey_pagespid=null 為根頁、指定父頁則掛其下;頁面樹即時插入新節點
uc_svd_04 UC-SVD-04 新增頁面(章節) start 左欄 [+新增頁面] → AddPageDialog form 填編號·名稱·描述·排序·父頁 (父頁 pid = null → 根頁) start->form submit 送出 form->submit create POST /survey-page {survey_uid, no, name, description, sort, pid} submit->create ok mapPageFromApi → 插入頁面樹 (parentId ↔ pid) create->ok
UC-SVD-04:填編號/名稱/排序/父頁 → POST /survey-page → 頁面樹插入

3. 權限矩陣

作者端角色基調見 _overview §5。本頁實際檢查點:

操作 FE 判定 BE 強制 BE 檢查位置
進入 / 載入問卷 route meta.requiresAuth @jwt_required() api/survey/routes/survey_route.py::SurveyRoute.get
頁面 CRUD / 排序 / 移動 選單能力顯示 @jwt_required(),無角色守門;移頁擋 409005 api/survey/routes/survey_page_route.py(全部僅 jwt)
題目 CRUD / 排序 / 移動 選單能力顯示 @jwt_required(),無角色守門 api/survey/routes/survey_question_route.py(全部僅 jwt)
儲存 / 另存新版 / 發布 @jwt_required() survey_route.py::SurveyRoute.putSurveyReleaseRoute

⚠️ 問卷管理頁 §3 的缺口:設計器所有寫入端點只有 JWT、無角色守門——任何登入者只要拿到問卷 uid 就能改題目結構。收進 §12。

4. 狀態機與前置條件

設計器改的是作者端範本;相關狀態是發布生命週期surveys.release)。本頁 gate:

條件 效果 出處
移動頁面目標 = 自身或子孫 SURVEY_409005(無法移動到自己底下) jedi_survey/domain/service/survey_page_domain_service.py:332
刪除頁面 硬刪除;子頁與題目經 FK ON DELETE CASCADE 一併刪 survey_pages FK fk_survey_pages_pid_survey_pages / ..._survey_id_surveys
另存新版 保留原版、同 group_id 產生新 version_no 列,前端 URL 換為新 uid jedi_survey/app/service/survey.py::add_survey(as_new_version=True)
儲存(PUT) 就地更新當前版本,不 bump version_no SurveyRoute.put
發布 release=1 → 出現在 /surveys/menu,可被規劃頁任務選用 SurveyReleaseRoute

5. UI 設計

📸 實際畫面截圖待補(一律亮色模式拍攝;截圖另有專責 session)。預計補到 assets/img/: ① 三欄整頁(頁面樹 + 題目卡)designer-overview.png ② AddQuestionDialog 三步(基本 / 選項 / 進階)designer-question-wizard.png ③ 題目卡(型別標籤 / 選項預覽 / 子題)designer-question-card.png ④ 問卷資訊設定 dialog designer-info-dialog.png

版面骨架與區塊職責(三欄設計工作區:左頁面樹選中頁 → 中欄載入題目卡,頂列動作+兩個 dialog;彩色區塊可點跳對應小節錨點,API 僅標代表性):

Header 動作列:⚙ 問卷資訊設定 ・ 預覽 ↗ ・ 發布/取消發布 ・ [儲存 ▾](就地/另存新版) PUT /survey/{uid} ・ POST /survey(as_new_version)・ PUT /survey/{uid}/release 三欄設計工作區 — 左頁面樹選中頁 → 中欄載入該頁題目卡 跳至 §2 Use Case(UC-SVD-02 頁面樹操作/UC-SVD-04 新增頁面) 左頁面樹(章節) 遞迴樹/搜尋/選中頁 每頁題數・右鍵 CRUD 拖動排序/改父頁 POST /survey-page POST /survey-page/move DELETE /survey-page/{uid} → 點我跳 §2 UC-SVD-02/04 跳至 §2 Use Case(UC-SVD-01 新增/編輯題目) 中欄題目編輯 — 選中頁的題目卡清單 7 題型・必填/權重/選項預覽/子題 卡片操作:上下移/複製/移到他頁 POST /survey-question ・ PUT /survey-question/{uid} POST /survey-question/move ・ /survey-questions/reorder → 點我跳 §2 UC-SVD-01 AddQuestionDialog 三步精靈 基本 →(選擇題才有選項步)→ 進階 送出 → POST/PUT /survey-question ⚙ 問卷資訊設定 名稱/對象/有效期 發布/範本/描述 走 PUT /survey/{uid} 彩色=可點跳本頁小節錨點(框內標錨點+代表性 API)|灰=本頁描述|虛線框=依操作才開的 dialog 層 API 僅列代表性 2~3 條,完整規格見 §6
問卷設計器版面 wireframe:頂列動作、左頁面樹、中題目編輯、AddQuestionDialog 三步精靈與問卷資訊設定 dialog

問卷結構模型(設計器操作對象):

svd_question_model 問卷結構模型:頁面樹 → 題目(型別 / 選項 / 流程規則 / 子題) survey 問卷 survey (設計器載入 GET /survey/{uid}) page 頁面 survey_pages 樹(pid)· no · sort survey->page survey_id q 題目 survey_questions 樹(pid 子題)· no · weights type · required · sort page->q page_id subq 子題(pid 指向母題) q->subq pid(同頁子題) opt 選項 options[] jsonb key/name/content ext_answer(補充輸入)/ext_answer_desc q->opt radio/dropdown/checkbox flow 流程規則(FE flowRules) 選某選項 → 跳某題 q->flow 選項驅動跳題 types 型別 type: text 文字輸入 · textarea 多行文字 radio 單選 · dropdown 下拉 · checkbox 核取 fileupload 檔案上傳 · link 連結 q->types
問卷結構:頁面樹 → 題目(型別 / 選項 / 流程規則 / 子題)

狀態呈現:頁面樹用遞迴 PageTreeNode(展開 / 收合 / 選中 / 右鍵);題目卡顯示型別圖示、必填星號、權重與流程規則標籤;選中頁切換時中欄重載題目。無 socket——設計器不即時協作(即時協作只在填寫頁);另存新版後 router.replace 換 URL 到新版 uid。

6. API 規格

Envelope:成功 {"status": true, "data": …}、失敗 {"error_code": "…", "msg": "…"}

6.1 總清單(本頁呼叫的全部 endpoint)

分類 Method + Path 說明 完整規格
載入 GET /survey/{uid} 問卷含 pages / questions 樹 §6.2
頁面 POST /survey-page 建立頁面 §6.2
頁面 PUT /survey-page/{uid} 部分更新頁面 §6.2
頁面 DELETE /survey-page/{uid} 刪除頁面(CASCADE 子頁 + 題目) §6.2
頁面 POST /survey-pages/reorder 同層排序 GAI-SD-02
頁面 POST /survey-page/move 改父頁(擋 409005) §6.2
題目 POST /survey-question 建立題目 §6.2
題目 PUT /survey-question/{uid} 部分更新題目 §6.2
題目 DELETE /survey-question/{uid} 刪除題目 GAI-SD-02
題目 POST /survey-questions/reorder 同頁排序 GAI-SD-02
題目 POST /survey-question/move 移到他頁 §6.2
儲存 PUT /survey/{uid} 就地更新問卷 manage §6.2
版本 POST /surveyas_new_version=true+group_id 另存新版 manage §6.2
發布 PUT /survey/{uid}/release・DELETE .../release 發布 / 取消 manage §6.2

6.2 核心 endpoint(欄位對照 serializer / service,出處標段末)

[POST] /survey-page ・ [PUT] /survey-page/{uid} — 頁面建立 / 更新

建立 Request:

欄位 型別 必填 說明
survey_uid string 所屬問卷 UID
no string 編號
name string 名稱
description string 描述
sort int 排序
pid int|null 父頁 DB id,null = 根

更新為部分更新(只送有改的 no / name / description / sort)。頁面不存在擋 SURVEY_404003。出處:api/survey/routes/survey_page_route.py、serializer api/survey/serializers/survey_page.py

[POST] /survey-page/move — 移動頁面

Request:

{
  "page_uid": "string",
  "target_parent_uid": "string"  // null = 移到根
}

目標 = 自身 / 子孫時擋 SURVEY_409005。出處:survey_page_route.pyjedi_survey/domain/service/survey_page_domain_service.py:332

[POST] /survey-question ・ [PUT] /survey-question/{uid} — 題目建立 / 更新

建立 Request:

欄位 型別 必填 說明
page_uid string 所屬頁面 UID
no string 題目編號
question string 題目內容
type string 題型
weights int 題目權重(預設 1)
sort int 排序
required int 必填(0/1)
pid int 母題 DB id,子題用
options array 選項陣列
description string 說明

更新為部分更新(含可改 page_uid 搬頁)。選項 jsonb 每項:{key, name, content, ext_answer, ext_answer_desc}(FE ↔︎ API 對照見 §10)。題目不存在擋 SURVEY_404004。出處:api/survey/routes/survey_question_route.py、serializer api/survey/serializers/survey_question.py

[GET] /survey/{uid} — 載入問卷結構

回問卷主檔 + pages(樹)+ questions(含 options / tags / references jsonb);供設計器渲染。同時回 has_answer。出處:api/survey/routes/survey_route.py::SurveyRoute.get

問卷資訊設定(⚙ dialog)

name / release_target(對象)/ release_at(有效期)/ release(發布切換)/ is_sample(範本切換)/ description → 走 PUT /survey/{uid}(見 manage §6.2)。version / folder 唯讀。

7. 前端檔案地圖(compliance-manager-fe/)

檔案 角色
src/views/survey-v2/SurveyDesigner.vue 主檢視(頂列 / 頁面樹 / 題目編輯 / 資訊 dialog)
src/views/survey-v2/components/PageTreeNode.vue 頁面樹遞迴節點(展開 / 選中 / 右鍵)
src/views/survey-v2/components/AddPageDialog.vue 新增 / 編輯頁面
src/views/survey-v2/components/AddQuestionDialog.vue 三步題目精靈(基本 / 選項 / 進階 + 流程規則)
src/views/survey-v2/composables/useSurveyApi.js API composable(page / question CRUD、儲存、版本)
src/views/survey-v2/utils/survey-mapper.js API ↔︎ FE 欄位轉換(pid↔︎parentId、option key↔︎id)
src/views/survey-v2/data/survey-mock-data.js 題型常數(questionTypes / Labels / Icons)
src/config/router/index.js:719-722 route survey-v2-designer/survey/designer/:id
src/config/api/api.js endpoint 常數(SURVEY_PAGE / SURVEY_PAGES_REORDER / SURVEY_QUESTION / SURVEY_QUESTION_MOVE …)

8. 後端檔案地圖(本頁核心鏈路)

鏈路 Route App Service 底層
載入 api/survey/routes/survey_route.py::SurveyRoute.get jedi_survey SurveyService domain / repo
頁面 CRUD api/survey/routes/survey_page_route.py jedi_survey/app/service/survey_page.py survey_page_domain_service(move 守門在此)
題目 CRUD api/survey/routes/survey_question_route.py jedi_survey/app/service/survey_question.py survey_question_domain_service
儲存 / 版本 survey_route.py::SurveyRoute.put / .post(as_new_version) jedi_survey/app/service/survey.py domain / repo

DDD 提醒:問卷 domain / repo 全在 jedi_survey 外部套件;主專案 route 只做 HTTP 邊界(解 uid、取 locale、呼叫套件 service)。所有寫入 route 僅 @jwt_required()未加角色守門(見 §3 / §12)——新增端點勿比照。

9. DB

9.1 資料表總清單(本頁讀寫的全部表)

讀/寫 說明 欄位詳述
survey.surveys 讀 / (儲存 / 版本 / 發布) 問卷主檔 manage §9.3
survey.survey_pages 讀 / 頁面(樹 pid);硬刪除、無 is_delete §9.3
survey.survey_questions 讀 / 題目(樹 pid、型別、選項 jsonb);硬刪除、無 is_delete §9.3
survey.survey_pages_trans / survey_questions_trans 翻譯表(含 locale 時) §9.3

9.2 ER 圖(本頁讀寫範圍)

svd_er 問卷設計器讀寫範圍(survey schema) surveys survey.surveys 讀 / 寫 儲存/另存新版/發布 pages survey.survey_pages 讀 / 寫 建立·更新·刪除·排序·移動 樹 pid · no · sort surveys->pages survey_id questions survey.survey_questions 讀 / 寫 建立·更新·刪除·排序·移動 type · options · weights · required pages->questions page_id ptrans survey.survey_pages_trans survey.survey_questions_trans 寫(含 locale 時) pages->ptrans 翻譯 questions->ptrans
問卷設計器讀寫範圍:頁面 / 題目樹(硬刪除)+ 翻譯表

9.3 核心表欄位(取自 DEV DB dump,含 DB comment)

survey.survey_pages — 頁面(樹,12 欄,無 is_delete)

欄位 型別 說明
uid varchar(36) 頁面 UUID
survey_id int 所屬問卷(→ surveys.id,ON DELETE CASCADE
pid int|null 父頁面(→ survey_pages.id 自參照,ON DELETE CASCADE
no varchar(30) 頁面編號
name / description varchar(255) / varchar(500) 名稱 / 描述
sort int|null 排序

survey.survey_questions — 題目(樹,19 欄,無 is_delete)

欄位 型別 說明
uid varchar(36) 題目 UUID
page_id int 所屬頁面(→ survey_pages.id,ON DELETE CASCADE
survey_id int|null 所屬問卷(冗餘,便於查詢)
pid int|null 父題目(子題用自參照)
no varchar(30) 題目編號
question text 題目內容
type varchar(30) 題型(text / textarea / radio / dropdown / checkbox / fileupload / link)
weights int 題目權重
required int|null 必填(1 / 0)
options jsonb|null 選項陣列
tags / references jsonb|null 標籤 / 參考資料
description text|null 題目說明(help text)
sort int|null 排序

翻譯表

survey_pages_transsurvey_page_id / name / description / language_codesurvey_questions_transsurvey_question_id / question / description / tags / references / options / language_code。寫入含翻譯欄位要傳 locale(見 _overview §6.3)。

10. 頁面邏輯與資料對應

載入時序:進頁 GET /survey/{uid}mapSurveyFromApi 建 pages / questions 樹 → 預設選第一頁 → 中欄渲染題目。

關鍵欄位對應(FE ↔︎ API):

概念 FE API
頁面 / 題目父參照 parentId(UID) pid(DB int id)
頁面編號 / 名稱 / 排序 code / name / sortOrder no / name / sort
題號 / 權重 / 必填 / 說明 questionNumber / weight / isRequired / helpText no / weights / required(0/1) / description
選項 id / 標籤 / 描述 id / label / description key / name / content
選項補充輸入 hasSupplementInput / supplementDescription ext_answer(bool) / ext_answer_desc

選項 id ↔︎ key 往返:survey-mapper.jskey 保存 FE id,避免以 label 當 key 造成碰撞。

儲存流程:題目 / 頁面的每個新增 / 編輯 / 排序 / 移動即時打對應 endpoint(非整批);頂列「儲存」= PUT /survey/{uid} 整包;「另存新版」= POST /survey as_new_version 後換 URL。

錯誤對應SURVEY_404003(頁面不存在)、SURVEY_404004(題目不存在)、SURVEY_409005(頁面移到自己底下)→ toast。

11. 背景行為與外部依賴

類型 內容
通知 本頁通知
Job 無背景 job
Socket 設計器 socket(useSurveySocket 只用於填寫頁協作);設計器儲存靠即時 REST
jedi-* 套件 jedi-survey(問卷 / 頁面 / 題目 domain / repo / 錯誤碼)、jedi-auth(JWT)
系統參數 無 feature flag

12. 邊界情況與已知坑

  1. 寫入無角色守門(安全缺口):頁面 / 題目 / 儲存 / 發布所有 route 只有 @jwt_required(),無 manager / 能力層強制(同問卷管理 §12)。任何登入者拿到 uid 就能改題目結構。
  2. 頁面 / 題目是硬刪除survey_pages / survey_questions is_deleteDELETE 為真刪除;刪頁經 FK CASCADE 連子頁 + 該頁全部題目一起消失、不可還原。與問卷 / 資料夾的軟刪除(is_delete)語意不同——刪頁前想清楚。
  3. SURVEY_409003(頁面有子頁)是死碼:error code 有定義但無 raise site;刪頁不會因有子頁被擋,而是直接 CASCADE 刪掉子頁。別在 spec / FE 假設「有子頁不能刪」。
  4. 移頁守門只有「自己底下」SURVEY_409005 只擋移到自身 / 子孫;跨問卷移動等其他非法情境未見額外守門。
  5. 儲存 vs 另存新版:「儲存」就地覆寫當前版本(不 bump);「另存新版」保留舊版 + 同 group_idversion_no,且前端 URL 換新 uid——編輯中誤按會分岔出新版本列。
  6. 流程規則存在 FE:選項→跳題的 flowRules 由 AddQuestionDialog 組成(option→target 映射),落地在題目的 jsonb(options / 相關欄位);BE 不驗證流程規則正確性——目標題被刪 / 改編號時規則可能懸空。
  7. 可翻譯欄位question / description / tags / references / options(題目)與 name / description(頁面)有 _trans 表;未傳 locale 只更新主表,讀取走 failover 優先翻譯表(見 docs/claude/translatable-fields.md)。
  8. 子題與型別:子題(pid)在同頁掛母題下;題型的選項步驟只對 radio / dropdown / checkbox 出現,其餘型別無 options。

13. 開發與驗證

  • 跑起來:BE python main_socketio.py(port 8000,log 在 log/app.log);FE 在 compliance-manager-fe/ 起 Vite dev server。BE 改 service code 後必須重啟(無 hot reload)
  • 測試帳號:dev 環境登入帳號密碼見 .env / 部署文件
  • 導航路徑:問卷管理頁點問卷「編輯」→ /survey/designer/:id
  • 前置資料:需先有一份問卷(可由問卷管理頁建立空白問卷後進入)
  • E2Ecompliance-manager-test/ repo(Cucumber + Playwright);以 問卷設計 / survey designer 搜尋 feature 檔
  • 相關文件:問卷 CRUD / 版本 / 發布見 問卷管理頁、填答 / 預覽見 問卷填寫 / 預覽;DB / API 全量見 GAI-SD-02/03