本卡屬 FR-145(母卡見子卡清單回填),卡 4:報告包。等卡 3(報告 Word/PDF)。
按「下載報告包」拿一個 zip,裡面有:完整報告 Word 與 PDF、一張證據對照表 Excel(一列一筆佐證,告訴你每個控制項的證據在包裡哪個資料夾)、每個稽核次一個資料夾放稽核計畫、稽核報告、工作表、還有一個「證據」資料夾依控制族群/控制項/評估目標分層放證據原檔。證據用稽核次結案時凍結的那個版本,不是現在的;問卷類佐證轉成一份 PDF(題目加答案)放進去;連結類打不包只記在對照表;沒被採用的佐證對照表留一列但不收檔。定稿時把 zip 存一份,歷史頁可重新下載那一版。
app/flow_control/service/ar_close_service.py _freeze :54——每條評估目標的採用項經 ar_objective_app_service.save_adopted_items :235 → _observations.upsert_adopted 寫 assessment_observations;每項 props 帶 content-hash(evidence_hashes :238:檔案=upload_files sha256/checksum,其餘=job_evidences.content_hash)與 frozen-at。ar_objective_view.py to_relevant_evidence——檔案 /files/<uid>、問卷 urn:guidant:task-survey:<survey_uid>(:77)、連結=網址。pkg/jedi-survey/app/service/question_answer_service.py:95 get_answer_list_by_task_survey_uid(task_survey_uid);歷史在 question_answer_histories/_details。app/flow_control/service/ap_report_export_service.py、ap_workbook_export_service.py;稽核報告與工作表:卡 1 選檔端點的 app service 方法。ar_workbook_export_service.py _zip :70(zipfile.ZipFile(buf,'w',ZIP_DEFLATED) + writestr)。render_pdf(WeasyPrint,project_summary_report_route.py:171)。儲存後端:既有 storage 設定(FR-039 系列,config/config.py grep STORAGE)。app/closing_report/service/closing_report_bundle_service.py 新:build(report) → BytesIO;資料夾與檔名規則
app/closing_report/service/evidence_index_workbook.py 新:證據對照表 xlsx
app/closing_report/service/survey_answer_pdf.py 新:問卷填答 → PDF
app/closing_report/service/closing_report_app_service.py issue() 接 bundle 存檔;加 bundle 端點
api/closing_report/routes/closing_report_route.py GET …/bundle、GET …/history/<uid>/bundle
compliance-manager-fe …ClosingReportView.vue 下載下拉「報告包 zip」「報告包內容」接上
<專案>_<第N輪>_結案報告[_v<N>]/:00-完整報告.docx、00-完整報告.pdf(卡 3 export)、01-證據對照表.xlsx、每 pass 第<seq>次<內部|外部>稽核/(稽核計畫.docx、稽核報告.docx、改善計畫工作表.xlsx 或稽核結果工作表.xlsx)、證據/<族群代碼 族群名>/<控制項>/<評估目標>/(原檔名;問卷 問卷填答_<問卷名>.pdf)。檔名含非法字元(/\:*?"<>|)替換底線。_observations.list_adopted(ar_result_id),CM-2826 已有),每項依 href scheme 分類:/files/→檔案(以 content-hash 對 upload_files.sha256 取對應版本,取不到在對照表備註「檔案已不存在」不中斷)、urn:guidant:task-survey:→問卷、其他→連結。未採用項(同 observation adopted=false)留對照表一列不收檔。ap_workbook_writer 的樣式 helper 可複用)。survey_answer_pdf.render(task_survey_uid) -> bytes——get_answer_list_by_task_survey_uid 取題目與答案,HTML 表(問卷名、填答人、填答時間、題號/題目/答案)經 render_pdf。中文字型主機要有 Noto Sans CJK TC(host-dependencies.md)。issue() 接上——build 一次存儲存後端,歷史定稿筆 bundle_ref 記路徑;GET …/history/<uid>/bundle 重下載。draft 下載即時 build 不存;draft zip 內 PDF 帶浮水印、檔名無版號。CLOSING_REPORT_BUNDLE_MAX_BYTES(預設 1 GB)回 413 並列出大小;背景產檔列後續不做。先查既有 env var 沒有同義的再新增,.env sample 與 deployment-env.md 同步補一行。round-closing-report.html 的 bundle-manifest:zip 樹(GET …/bundle?manifest=1 回結構不產檔)+對照表前 N 列。