合規框架 PDF 匯入兩階段化 — 實作計畫

文件版本:1.0 建立日期:2026-05-03 對應 SDdesign.md對應 SAapi-spec.md對應 FEfrontend-spec.md


§1

0. 執行原則

  • 單一執行者:本 plan 由 main agent 一氣呵成執行,phase 間有 dependency 不平行;每個 phase 結束 self-check(CLAUDE.md 規範清單)
  • Code review 粒度:所有 phase 完成後一次跑(依 memory feedback_review_granularity.md
  • Poetry 策略:開發期間用 path = "/Users/chouraymond/Projects/Jedicogy/module/jedi-python-package/jedi-oscal", develop = true;最終驗收前才進版到 0.0.16 pin(依使用者明示)
  • Reference PDFsdocs/features/FR-024-2605-compliance-framework-pdf-import-v2/referance/CMMC 2.0 Level 1 Assessment Guide.pdf + Level 2 Assessment Guide.pdf,兩者共用 ParserAdapterType.CMMC_2 adapter
  • DB 直接作業:使用者已備份;migration 完成後直接以 cmmgr 帳號執行(依 memory feedback_sql_migration_use_cmmgr.md
  • 遇 blocker:手機 push notification 通知使用者

§2

Phase A — DB Schema + Domain (BE)

依賴:無

A.1 Migration

  • 新增 scripts/sql/2026-05-03-oscal-framework-parse-jobs.sql
  • 內容:建表 + index(tenant_id+is_active+status / uid / created_at)+ RLS policy(仿 ssp_docx_parse_jobs)+ GRANT
  • 直接以 cmmgr 帳號執行

A.2 ORM Model + Mapper

  • infra/oscal/model/oscal_framework_parse_job.pyOscalFrameworkParseJob(schema=oscal
  • infra/oscal/mapper/oscal_framework_parse_job_mapper.py

A.3 Domain Entity + Query + Repo Interface

  • domain/oscal/entity/oscal_framework_parse_job_entity.py
  • domain/oscal/entity/oscal_framework_parse_job_query_entity.py
  • domain/oscal/repository/oscal_framework_parse_job_repo.py

A.4 Domain Service + Repo Impl

  • domain/oscal/service/oscal_framework_parse_job_domain_service.py
  • infra/oscal/repository/oscal_framework_parse_job_repo_impl.py(繼承 BaseRepositoryImpl,session lazy)

A.5 Error Codes

  • common/code/grc_error_code.py 新增 7 個 GRC error code(見 api-spec §3)

A.6 DI 串接

  • di_containers/oscal/oscal_containers.py:新增 repo / domain service / app service providers

Self-check


§3

Phase B — jedi-oscal 拆分(外部套件)

依賴:A 完成(不過 jedi-oscal 改動可平行;嚴格說 B 只在 Phase D BE parse endpoint 之前要好就行)

B.1 切到 develop path

  • BE pyproject.toml:jedi-oscal pin 改為註解,啟用 [tool.poetry.dev-dependencies] 區塊的 path 行
  • 提示使用者跑 poetry update

B.2 jedi-oscal 加 parse_pdf_to_dict

  • jedi_oscal/app/services/oscal_import_service.py
    • 新 method parse_pdf_to_dict(file_stream, parser_type) -> dict
    • 內部呼叫 oscal_parser_factory.get_oscal_parser_adapter(parser_type) 取 adapter,呼叫 pdf_parser() 拿 raw list[dict]
    • 再用 adapter 的 convert_to_oscal_catalog_entity() 轉 CatalogEntity,序列化成 OSCAL-shaped dict(含 catalog metadata + groups[] + controls[] + assessments[],每筆給 stable uid)
    • 不寫 DB、不開 session

B.3 jedi-oscal 加 import_from_dict

  • jedi_oscal/app/services/oscal_import_service.py
    • 新 method import_from_dict(oscal_dict, payload, curr_user, locale=None, version_uid=None) -> FrameworkVersionEntity
    • 從 dict 重建 CatalogEntity → 沿用既有「寫 DB」路徑(FrameworkVersion / Catalog / Profile)
    • 寫入需 @transaction,但本方法已假設 caller 在 transaction scope 內(不再加裝飾器)

B.4 重構 legacy method

  • import_or_update_oscal_from_pdf() 內部改成兩段呼叫(保留簽章不變)

B.5 新增 ImportFrameworkVersionPayload dataclass

  • jedi_oscal/app/dto/...:替代散裝 dict 參數

B.6 jedi-oscal 自我測試

  • 暫不 publish,由 BE develop path 引用即可
  • 對 reference PDFs 跑一次 parse_pdf_to_dict smoke test,確認 dict 結構符合預期

§4

Phase C — BE App Service + Routes

依賴:A、B

C.1 App Service

  • app/oscal/service/oscal_framework_parse_job_service.py
    • list_jobs(filter) — list with summary count
    • parse(file, payload, curr_user) — 建 parse_job + 同步呼叫 OscalImportService.parse_pdf_to_dict + 處理失敗 fallback to status=failed
    • get_detail(uid, curr_user) — 取單筆,jedi-oscal framework_uid → name 補欄位
    • confirm(uid, decisions, overrides, curr_user) — 套用 → 呼叫 import_from_dict
    • discard(uid) — 軟刪
    • 全部 @transaction

C.2 Marshmallow Schemas

  • api/oscal/serializers/framework_parse_job/
    • request:FrameworkParseRequestSchemaFrameworkParseJobConfirmRequestSchema
    • response:FrameworkParseJobListResponseSchemaFrameworkParseJobDetailResponseSchemaFrameworkParseJobConfirmResponseSchemaFrameworkParseResponseSchema

C.3 Route 層

  • api/oscal/routes/framework/oscal_framework_parse_job_route.py
    • 5 個 Resource classes(依 api-spec §1)
  • api/oscal/__init__.py 註冊 4 個 url(api.add_resource

C.4 RBAC 資源註冊

  • ui_routes migration 加新前端路由(依 SOP reference_permission_system_sop
  • route_capabilities 對應 BE 4 個 endpoint

Self-check


§5

Phase D — 排程清理(BE)

依賴:A

  • core/scheduler.py:新 cron job framework_parse_job_cleanup,每天 01:00 跑
    • 軟刪 is_active=true AND created_at < now() - interval '7 days'
    • is_active=falsestatus='expired'updated_user='system'
  • 仿既有 ssp_docx_parse_job_cleanup(若有);無則沿用 scheduler 模式

§6

Phase E — FE 主流程

依賴:A/B/C 完成(FE 需要實際端點才能 e2e)

E.1 路由 + service + composable

  • src/router/index.ts:兩條動態路由
  • src/config/api/api.jsOSCAL_FRAMEWORK_PARSE_JOBS 常數
  • src/service/FrameworkImportService.js:5 個方法
  • src/composables/useFrameworkImportDraft.js

E.2 Page 元件

  • src/views/compliance-framework/FrameworkImportPage.vue(page wrapper + step 狀態機)
  • src/components/compliance-framework/import/
    • DraftBanner.vue
    • FrameworkImportUploadStep.vue
    • FrameworkImportPreviewStep.vue
    • GroupTreeEditor.vue
    • ControlListEditor.vue
    • AssessmentListEditor.vue
    • ErrorPanel.vue

E.3 i18n

  • src/config/locales/i18n/zh-tw/compliance-framework-version-import.json
  • src/config/locales/i18n/en/compliance-framework-version-import.json

E.4 入口替換

  • ComplianceFrameworkVersionManage.vue
    • 「匯入版本」按鈕 click → router.push
    • 移除 importVersionDialog 整段(template + script + handlers)
    • 移除 createDocByImportFile / updateDocByImportFile 兩個 handler

E.5 PDF 預覽

  • 上傳檔案保 URL.createObjectURL(file),預覽用 <iframe :src="blobUrl">
  • 重整 / blob 失效時顯示 placeholder

§7

Phase F — Changelog + 文件

依賴:A–E 完成後

  • docs/changelog/2026-05-XX-feat-framework-pdf-import-v2-be.md
  • docs/changelog/2026-05-XX-feat-framework-pdf-import-v2-fe.md
  • docs/changelog/2026-05-XX-feat-jedi-oscal-import-service-split.md(jedi-oscal 改動)
  • docs/api/oscal/api-spec.md / design.md 補 framework_parse_job 端點段落
  • compliance-manager-fe/docs/features/compliance-framework-pdf-import/release-notes.md
  • 對話歷史最後一輪封存到 docs/conversation-history/2026-05-03-compliance-framework-pdf-import/

§8

Phase G — 最終 code review

依賴:A–F 完成

  • 對 BE 改動跑 pr-review-toolkit:code-reviewer
  • 對 FE 改動跑 pr-review-toolkit:code-reviewer
  • 對 jedi-oscal 改動單獨跑一輪(外部套件 quality gate)
  • 修補回饋;spec compliance + code quality 雙審
  • 確認後再決定是否 jedi-oscal 進版到 0.0.16 + BE pin(依使用者明示,不自動進)

§9

開放追蹤項

項目 說明
audit_file_type 路徑舊端點處置 暫保留,待新流程穩定後再評估 deprecate
Excel 匯入兩階段化 本 spec 不做(明確 out of scope)
Adapter L1/L2 區分 共用 CMMC_2 adapter 即可,PDF 結構規律相同
jedi-oscal 0.0.16 publish 開發期 develop path,release 前再進版