對應 spec:
../design.md對應 plan:../implementation-plan.md緣由:user 睡前說「持續作業下去」,目標把 S1–S4 全做完,user 早上 review
| 項目 | 值 |
|---|---|
| BE branch | fearure/ai-evidence-classify |
| FE branch | fearure/ai-evidence-classify |
| BE commits(新) | b1936c35 Docker container · 410f3f46 S2 BE module |
| FE commits(新) | 7519b5f S3 review page · 2f71eb9 S4 trigger panel |
| Push 狀態 | 未 push,等你早上 review 後決定 |
| Docker image | cmmc-classifier:latest build 完成(196MB content) |
| 預估 review 時間 | 30-45 分鐘 |
按順序看比較好理解全貌:
docs/features/FR-030-2605-auto-evidence-classification/design.md — 整體規格(Phase 0)docs/features/FR-030-2605-auto-evidence-classification/implementation-plan.md — S1-S4 切分docs/api/evidence-classification/api-spec.md — 3 endpoints API 規格新建 scripts/evidence/classify/docker/:
Dockerfile — python:3.11-slim base,~200MBrequirements.txt — anthropic / google-api / docx / sqlalchemy / cryptographycontainer_entrypoint.py — self-contained,subcommand service-classifyjedi_helpers/ — 內聯 FernetCrypto + GoogleOAuthClient(不 import infra/)README.md + .dockerignore驗證:docker run --rm cmmc-classifier:latest service-classify --limit 3 ... 跑 3 檔 16.8s,輸出 _state.json + _report-original.json 結構正確。
新模組 api/evidence_classification/ + app/... + infra/... + di_containers/...
3 個 endpoints(auto-registered via Blueprint):
POST /api/1.0/project/<project_uid>/classify-evidence — 觸發GET /api/1.0/project/<project_uid>/classify-evidence/jobs[/<job_uid>] — job 狀態 pollingGET /api/1.0/classification-run/<run_folder_id>/state — 讀 _state.jsonPUT /api/1.0/classification-run/<run_folder_id>/state — 寫 + diff + Drive ops關鍵實作:
ClassifierContainerRunner — subprocess.Popen(['docker', 'run', ...]) block 等結果EvidenceDriveOps — Drive copy/trash/upload-json/list-children helperJobRegistry — in-memory thread-safe dict(無 DB,restart 後消失,可接受)自動分類_YYYY-MM-DD_HH-MMfiles.copy 每筆 placement 進對應 AO 資料夾_state.json + _report-original.json 到 run folderDDD 規範遵守:
@transaction 在 app service public methodsGoogleDriveTokenManager 拿 access_tokenEC_* (common/code/evidence_classification_error_code.py)新 Vue route: /project/projects/:id/ap/:apUid/classify-evidence/run/:runFolderId
元件結構(全 PrimeVue + Ultima theme + FE CLAUDE.md 規範):
src/views/evidence-classification/
├── EvidenceClassificationReview.vue 頁面 entry
├── aoLookup.js flatten catalog helper
└── components/
├── ClassificationStatsRow.vue 5 stat cards
├── ClassificationFilterBar.vue search/domain/status/conf + inbox
├── ClassificationFileList.vue DataTable virtual scroll
├── ClassificationFileDetail.vue right panel
├── PlacementCard.vue breadcrumb + reasoning + remove
├── CandidateCard.vue for unclassified files
└── AOPickerDialog.vue searchable AO picker
支援功能:
build 驗證:npm run build:DEV 通過,EvidenceClassificationReview-09cca9de.js 43 KB / gzip 11 KB
新元件 src/components/grc/project/AIEvidenceClassificationPanel.vue:
/jobs 每 5s嵌入到 ProjectPlanningView.vue 的 Cloud Integrations TabPanel 內,跟既有 ProjectCloudIntegrationsPanel 並列。
⚠ 你昨晚說 BE 對 project AP → Drive 連結有問題。我已經把 trigger endpoint 設計成從 request body 收
evidence_folder_id(不從 DB derive),FE panel 也是要 user 手動貼 URL/ID。這樣繞過 AP-Drive 連結問題,可以直接用你給的測試資料夾1fTAAUXpo66PUkfyHhTpMf4xjUJexCZ8v。
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
# 你自己用既有方式起 BE(main_socketio.py 或 main_app.py)觀察 startup log:應該看到 Evidence Classification module registered。
cd ~/Projects/Billows/Audit-Manager/compliance-manager-fe
npm run dev
# http://localhost:518040c3f612-00a4-4574-868b-276a82d30ef0 → AP eaa521f1-... → 專案規劃 頁https://drive.google.com/drive/folders/1fTAAUXpo66PUkfyHhTpMf4xjUJexCZ8v 或直接貼 ID# 觸發
curl -X POST http://localhost:8000/api/1.0/project/40c3f612-00a4-4574-868b-276a82d30ef0/classify-evidence \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{"evidence_folder_id": "1fTAAUXpo66PUkfyHhTpMf4xjUJexCZ8v", "framework_id": "cmmc-l1", "confidence_threshold": 0.80}'
# Poll
curl -H "Authorization: Bearer <jwt>" \
http://localhost:8000/api/1.0/project/40c3f612-00a4-4574-868b-276a82d30ef0/classify-evidence/jobs
# 完成後讀 state
curl -H "Authorization: Bearer <jwt>" \
http://localhost:8000/api/1.0/classification-run/<run_folder_id>/statemkdir -p /tmp/cm-jobs/manual
cp "docs/reference/CMMC-Level 1-Evidences/cmmc_l1_aos.json" /tmp/cm-jobs/manual/catalog.json
docker run --rm \
-v /tmp/cm-jobs/manual:/job \
--env-file .env \
cmmc-classifier:latest service-classify \
--tenant-id 102 \
--evidence-folder-id 1fTAAUXpo66PUkfyHhTpMf4xjUJexCZ8v \
--catalog-file /job/catalog.json \
--output-dir /job \
--min-confidence 0.80 \
--limit 3
ls /tmp/cm-jobs/manual/ # 看到 _state.json + _report-original.json| 問題 | 影響 | Workaround |
|---|---|---|
| AP → Drive 資料夾連結 BE 有 bug(你昨晚提的) | 無法從 DB 自動 derive evidence_folder_id | FE panel 要 user 手動貼 URL/ID。已實作。等 BE 修好後 panel 可改自動 |
| BE restart 後 in-memory job state 消失 | 跑中的 container 不受影響(subprocess 獨立),但 job 狀態 UI 看不到 | 等 v1.0 改 DB tables |
_state.json 讀取必須有 in-memory job 才知道 tenant |
restart 後不能 GET state | 等 v1.0 改用 project_uid 路徑(會把 project 找 tenant) |
| 兩人同時 PUT state 後改的覆蓋前改的 | 並發編輯衝突 | 實驗階段先這樣,v1.1 加 ETag |
| Drive folder 內若有大量已存在的 run folder(重跑多次)會看起來雜亂 | 視覺上 | 手動刪舊 run folder 或 v1 加 cleanup policy |
| 項 | 說明 |
|---|---|
| E2E 實測 | 我沒辦法起 BE 跑 curl,所有 BE 程式碼透過 syntax + import + AST parse 通過,但 actual HTTP request 要你早上測 |
| AP-Drive 自動連結 | 等你 BE bug 修好後,把 AIEvidenceClassificationPanel 的「user 輸入 folder URL」改為從 BE 取自動帶 |
| 正式版 DB schema | design.md §「v1.0 之後的 DB schema」三表,目前實驗階段不做 |
| 多框架支援 | 目前 hardcoded cmmc-l1,catalog from cmmc_l1_aos.json;BE 加 OSCAL API + FE 加 framework 選擇器後可支援 NIST 800-171 / ISO 27001 等 |
| E2E 測試(compliance-manager-test repo) | 等 UI 穩定後在 test repo 加 Cucumber feature |
| Drive 重新整理 | 每次跑完 BE 把 _state.json upload 到 run folder,但 Drive web UI 偶爾要 manual refresh 才看到 |
fearure/ai-evidence-classify)v-tooltip.toptext-2xl / text-sm 等@transaction / domain service via DI)EC_<HTTP-status><序號># === BE side ===
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
git log --oneline -5 # 看新 commits
docker images | grep cmmc-classifier # 確認 image 在
# 起 BE(用你的方式)
# === FE side ===
cd ~/Projects/Billows/Audit-Manager/compliance-manager-fe
git log --oneline -3
npm run dev # 啟動 dev server
# === Quick container sanity ===
mkdir -p /tmp/cm-jobs/quick && \
cp "docs/reference/CMMC-Level 1-Evidences/cmmc_l1_aos.json" /tmp/cm-jobs/quick/catalog.json && \
docker run --rm -v /tmp/cm-jobs/quick:/job --env-file .env \
cmmc-classifier:latest service-classify \
--tenant-id 102 --evidence-folder-id 1fTAAUXpo66PUkfyHhTpMf4xjUJexCZ8v \
--catalog-file /job/catalog.json --output-dir /job --limit 3
cat /tmp/cm-jobs/quick/_state.json | head -50log/app.log),搜 evidence_classification 看是否註冊config/app_modules.py 有 evidence_classificationdocker(user 是不是有 docker group 權限)[classifier] job=... drive op ..._resolve_tenant_for_run_folder 找不到 in-memory job(BE restart 後就會這樣)自動分類_<datetime> 資料夾結構正確