手冊首頁 / 溝通協作 / 問卷功能群總覽

問卷功能群總覽(Survey V2 Overview)

本檔放「本功能群多個頁面共用的知識」:頁面地圖、問卷 v2 資料模型、作者端發布與消費端填答雙生命週期、快照機制、角色基調。

各頁面 spec 引用本檔,只寫自己頁面的差異——改共用邏輯時改這裡一份

事實基準:2026-07-05 從 FE(views/survey-v2/config/router/index.js)/ BE(api/surveyapi/task_survey)code 與 db_schema.jsonsurvey schema)掃出。

1. 頁面地圖

問卷群分兩半:作者端(設計可重用問卷範本)與消費端(稽核任務執行者對問卷快照填答)。

頁面 FE route 用途一句話 端|spec
問卷管理 /survey/manage 資料夾樹 + 問卷清單 CRUD、複製、發布、版本、匯入 作者|問卷管理
問卷設計器 /survey/designer/:id 單一問卷的頁面樹 + 題目編輯(題型 / 選項 / 權重) 作者|問卷設計器
問卷預覽 /survey/preview/:id 作者唯讀預覽(不落資料);與填寫頁同一個 view 作者|併入 問卷預覽
問卷填寫 /survey/fill 稽核任務執行者對問卷快照填答、送審 消費|問卷填寫

previewfill 兩條 route 共用同一個 SurveyPreview.vue(作者預覽 vs 任務填答由 route / 參數分流,見 fill 頁 spec §10)。

上游 / 下游關係:問卷範本在此群設計、發布;被專案規劃頁的稽核任務(job_type=survey)綁定消費——綁定當下 BE 對問卷取快照,任務執行者填的是凍結快照而非 live 範本(見 §4)。

2. 核心資料模型(本群最重要)

sv_core_data_model 問卷 v2 資料模型:作者端(樹狀範本)— snapshot 橋接 — 消費端(任務填答) cluster_author 作者端 authoring(survey schema · api.survey) cluster_consume 消費端 consume(survey schema · api.task_survey) folders survey_folders 資料夾(樹 pid) surveys surveys 問卷主檔 group_id/version_no 版本 release 發布・is_sample 範本 folders->surveys folder_id pages survey_pages 頁面(樹 pid・no・sort) surveys->pages survey_id discuss survey_discussions 問卷討論串 surveys->discuss survey_id snap surveys(快照列) is_snapshot=1 source_survey_id→原問卷 surveys->snap launch/任務綁定時 clone 成 snapshot questions survey_questions 題目(樹 pid・type・weights options/tags/references jsonb) pages->questions page_id tasksv task_surveys 任務×問卷×設備 status 填答狀態機 snap->tasksv survey_id answers question_answers 每題答案 answer/feedback jsonb・score tasksv->answers task_survey_id hist question_answer_histories (+_details) 版本快照/還原 tasksv->hist task_survey_id job 規劃頁任務(GRC job) job_type=survey job_execution_surveys job->tasksv survey×device 笛卡爾積 reconcile
問卷 v2 資料模型:作者端樹狀範本 — snapshot 橋接 — 消費端任務填答

全部表都在 survey schema(不是 compliance / oscal)。兩條線:

  1. 作者端(範本樹)survey.survey_folders(資料夾,pid 樹)→ survey.surveys(問卷主檔)→ survey.survey_pages(頁面,pid 樹 + no + sort)→ survey.survey_questions(題目,pid 樹 + type + weights + options/tags/references jsonb)。另有 survey.survey_discussions(問卷討論串)。四張主表各有 _trans 翻譯表(見 §6.3)。
  2. 消費端(任務填答)survey.task_surveys(任務×問卷×設備的執行期追蹤,status 填答狀態機、main_project_id/task_idapproval_requiredjob_evidence_id soft-ref)→ survey.question_answers(每題答案,answer/feedback jsonb + score);填答異動快照進 survey.question_answer_histories(+ _details)供還原。

兩個 BE 模組對應兩端:作者端 = api.survey/survey/survey-folder/survey-page/survey-question/survey-discussion);消費端 = api.task_survey/task-survey*/project-survey/*)。

3. 作者端發布生命週期(surveys.release)

sv_lifecycle 問卷雙生命週期:作者端發布 vs 消費端填答狀態機 cluster_release 作者端發布(surveys.release) cluster_fill 消費端填答(task_surveys.status · TaskSurveyStatusCode) draft 草稿 release=0 published 已發布 release=1 release_at/release_target draft->published PUT /survey/{uid}/release published->draft DELETE /survey/{uid}/release (取消發布) s0 待填寫 UNFILLED=0 s1 編輯中 EDITING=1 s0->s1 開始填答 s1->s1 checkpoint/patch 暫存 s2 待審核 UNDER_REVIEW=2 s1->s2 送審 (approval_required) s9 完成 COMPLETED=9 s1->s9 提交 (免審核) s3 待補充說明 ADD_NOTES=3 s2->s3 退回補充 (審核人送回饋) s2->s9 審核通過 s3->s2 補充後重送審
問卷雙生命週期:作者端發布 vs 消費端填答狀態機
  • 草稿 → 已發布surveys.release0 草稿 / 1 已發布)+ release_at + release_target(發布對象)。PUT /survey/{uid}/release 發布、DELETE /survey/{uid}/release 取消發布。
  • 版本group_id 群組同一問卷的多版本、version_no 版本號;問卷管理「另存新版」= POST /surveyas_new_version=true + group_id),保留舊版、產生新版列。
  • 範本旗標is_sample1 為系統範本,可被複製起手)。
  • 軟刪除is_delete1 已刪,查詢預設 is_delete=0)。

4. 快照機制(作者範本 → 消費快照,本群關鍵)

問卷被稽核任務綁定消費時不直接引用 live 範本,而是 clone 一份快照:

  • 快照是 survey.surveys 內的另一列,is_snapshot=1 + source_survey_id 指回原範本;快照連同其 pages / questions 一起複製,與原範本脫鉤——之後改範本不影響已綁定任務。
  • 綁定發生在專案規劃頁:任務(GRC job)job_type=survey 設定問卷後,job_service.update_job 對問卷取 snapshot、job_execution_surveys 記 job→snapshot 關聯,並把 survey × device 笛卡爾積 reconcile 進 survey.task_surveys(多問卷 × 多設備 → 列數乘開)。
  • 消費端填答頁只認 task_surveys / 快照,看不到作者端資料夾樹。

(任務綁定的完整欄位語意、full-replace 陷阱見 project-task-edit.md §6.2 / §12。)

5. 角色基調

角色是誰

  • 問卷作者(capability 控管,非專案角色)——設計問卷頁面與題目、發布版本,供稽核專案挑選使用。「身為問卷作者,我要設計一份問卷範本、加好題目與選項,發布後讓專案可以在任務裡指派。」

  • 任務執行者(受稽方)——對指派給自己的問卷快照作答。「身為受稽方,我要完成被指派的問卷、填完後送出等待審核。」

  • 審核人task_assignees.is_approver)——審核送出的問卷答案。「身為審核人,我要檢查受稽方填的問卷答案是否需要退回修改。」

  • 作者端(管理 / 設計 / 預覽):問卷範本作者,以選單能力(capability)/ RBAC 控管(ui_routes + RBAC 三層,見 docs/claude/ 權限系統 SOP),非專案層 manager/auditor 角色。route meta.requiresAuthconfig/router/index.js:710)——目前 beforeEach 僅硬性擋 requiresAdminrequiresAuth 的 token gate 待 auth/session 重構接上(見各頁 §3)。

  • 消費端(填寫):稽核任務執行者(受稽方),對指派給自己的 task_surveys 填答;審核由任務指派時標記的審核人(task_assignees.is_approver)處理(approval_required 決定是否需送審)。各頁實際 endpoint 守門以該頁 §3 為準。

6. 本群共用的已知坑

  1. 表都在 survey schemasurvey.surveys / survey_pages / survey_questions / task_surveys / question_answers 等——別寫成 compliance.*public.*
  2. 作者端 survey ≠ 消費端 task_survey:兩個 BE 模組、兩套 route、兩種角色;survey.surveys 同一張表同時放範本列(is_snapshot=0)與快照列(is_snapshot=1),靠 is_snapshot / source_survey_id 區分。
  3. 可翻譯欄位surveys(name/description/release_target)、survey_pages(name/description)、survey_questions(question/description/tags/references/options)、survey_folders(name/description)各有 _trans 表;寫入含翻譯欄位要傳 locale,否則只更新主表(見 docs/claude/translatable-fields.md)。
  4. 快照脫鉤:改已發布範本不回溯已綁定任務的快照;要讓既有任務吃到新版得重綁。
  5. 樹狀結構:資料夾 / 頁面 / 題目都用 pid 自參照成樹;刪父層多為 ON DELETE CASCADE(見各表 FK)。
  6. 已發布仍可被填答的是快照:作者端 release 只影響「可否被規劃頁選用」;填答走的是綁定當下的快照狀態,與範本後續發布狀態無關。