§1
一句話摘要
Track B(SSP 匯出 B1~B6)全部 shipped,含 6 種格式匯出(docx/pdf/odt/json/yaml/xml)、CMMC 正式 DOCX 格式、LibreOffice 跨平台支援、中文檔名修正。
§2
Commits 清單
BE(compliance-manager-be)
FE(compliance-manager-fe)
§3
功能說明(改動範圍)
B1~B4:核心匯出 pipeline(062782d)
SspDocxGenerator:docxtpl + python-docx 混合渲染
MfSspContentLoader / SspVersionContentLoader:從 MF 或 SSP 版本組裝 SspExportDataModel
SspLibreOfficeConverter:subprocess 呼叫 LibreOffice 產 PDF/ODT
- API routes:
/module-frame/<uid>/ssp-export + /ssp/<uid>/export
B5:OSCAL 格式(25909f2)
/ssp/<uid>/export?format=json|yaml|xml
- 同一 route,透過
SystemSecurityPlanYamlMapper 序列化 jedi-oscal entity
B6 DOCX 格式升級(8df2525)
- 封面:標題居中、系統名稱、metadata 表(Version/Date/Prepared by)
- System Information:動態 loop,只顯示有值的列
- Responsible Organization:動態 kv rows
- Participants:合併人員表(Name / Role / Email),過濾 organization 類型
- Assessment Objectives:bullet list(去掉 statement_id 前綴重複問題)
- 標題、欄位名稱:全純英文,移除中英夾雜
- 修正
docxtpl.get_docx() 回傳未渲染原件的 bug(改用 save → Document)
LibreOffice 跨平台(8ee55f5)
- 新增
_resolve_libreoffice_cmd() 自動偵測:env var → PATH libreoffice → PATH soffice → macOS app bundle
- 解決開發機 macOS 只有
soffice 而非 libreoffice 導致 PDF/ODT 500
中文檔名(43a9389 BE + c21372c FE)
- BE:
_UNSAFE_FILENAME_RE 取代原 ASCII-only 過濾;Route 加 RFC 5987 filename*=UTF-8''
- FE:3 處
.replace(/[^a-zA-Z0-9-_]/g, '_') 改為 .replace(/[\\/:*?"<>|\x00-\x1f]/g, '_')
- 結果:
SSP_亞O航空專案_2026-05-22.docx(不再是 SSP__O____2026-05-22.docx)
§6
Working Tree 狀態
pyproject.toml M dev-only jedi-oscal path dep — 不 commit
其餘工作樹乾淨。
§7
部署 Handover
- BE 需要 LibreOffice 安裝(PDF/ODT)。macOS 開發機用
soffice(Homebrew),Linux production 用 libreoffice,均自動偵測。若 binary 在非標準路徑,設 LIBREOFFICE_CMD env var。
- FE 不需重新 build(Vite dev server hot reload),production 需 re-build。
pyproject.toml 有 jedi-oscal path dep 待恢復 Nexus pin(待 jedi-oscal 正式發版後執行)。