Commit 1145df18 authored by Admin's avatar Admin

docs: move 04_audit_fixes to plan/done — all gates verified

All 6 completion criteria confirmed:
- grep canifa (source .py) = 0
- blueprint_id wired into POST /pipelines/run
- reports_to validator active
- 2-company DB constraint OK
- 5/5 blueprint E2E tests pass
- frontend build 0 errors
Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
parent 406a39cf
# 🔧 DOING #04: Audit Fixes — Platform Generalization Gap Closures
## 📌 Context
- **Audit source:** Adversarial workflow audit 2026-06-01 → 100% complete, 4/4 criteria met
- **Roadmap:** `plan/doings/03_platform_generalization_roadmap.md` Phase 9A–J
---
## 🔴 A — De-brand (Criterion #4: grep canifa = 0)
- [x] A1 — `backend/api/routes/run_logs.py:438` — đổi `"Phân tích yêu cầu thương hiệu thời trang Canifa..."` → `"Phân tích yêu cầu dự án, thiết kế tài liệu spec.md."`
- [x] A2 — `backend/api/routes/run_logs.py:551` — đổi `"Báo cáo CEO: Kết quả xây dựng Landing Page Canifa Premium"` → `"Báo cáo CEO: Kết quả xây dựng Landing Page"`
- [x] A3 — `backend/api/routes/run_logs.py:552` — đổi `"Canifa Premium Landing Page"` → `"Demo Landing Page"`
- [x] A4 — `backend/api/routes/run_logs.py:553` — xoá/thay chuỗi `"Canifa Premium"` trong summary → `"Demo Company"`
- [x] A5 — `backend/api/routes/run_logs.py:571` — đổi `"tới cửa hàng thời trang Canifa"` → `"lên server production"`
- [x] A6 — `backend/api/routes/run_logs.py:628` — đổi `"SSH sync sang server Canifa Magento 2"` → `"SSH sync sang server production"`
- [x] A7 — `backend/api/routes/agents.py:260` — đổi `CANIFA Premium` (title + h1) → `Demo Company`
- [x] A8 — `backend/scratch/seed_db.py:40` — đổi `company_name="Canifa Company"` → `"Demo Company"`
- [x] A9 — `backend/scratch/seed_db.py:43` — đổi description Canifa → `"AI Company Platform — Demo Instance"`
- [x] A10 — Verify: `grep -ri "canifa" backend/models backend/services backend/api backend/tasks` = **0 hits** ✅
---
## 🔴 B — Wire blueprint_id vào pipeline/run (Criterion #2 & #3)
- [x] B1 — `backend/api/routes/pipelines.py:28-33` — thêm `blueprint_id: Optional[str] = None` vào `PipelineRunRequest`
- [x] B2 — `backend/api/routes/pipelines.py:109-116` — thêm logic: nếu `payload.blueprint_id` → load blueprint → pass `pipeline_spec=[n.model_dump() for n in blueprint.pipeline]` vào `ProjectOrchestrator`
- [x] B3 — Thêm import `BlueprintService` vào `pipelines.py`
- [x] B4 — Test thủ công: `POST /pipelines/run {blueprint_id: "software-studio", ...}` → orchestrator nhận `pipeline_spec` != None ✅
---
## 🔴 C — reports_to validator (Criterion #1)
- [x] C1 — `backend/schemas/blueprint.py` — thêm `@model_validator(mode='after')` vào `CompanyBlueprint`: raise `ValueError` nếu `role.reports_to` không tồn tại trong tập role ids
- [x] C2 — `backend/services/blueprint_service.py` — thêm `validate_org_chart(blueprint)` kiểm tra `reports_to` integrity, gọi từ `load_blueprint`
- [x] C3 — `backend/services/blueprint_service.py:141` — thêm `else: raise ValueError(f"reports_to role '{parent_role}' not found")` sau `if parent_role in role_to_agent`
- [x] C4 — Test: blueprint với `reports_to="nonexistent"` → raise `ValueError` khi load ✅
---
## 🔴 D — NocoBase blueprint-driven + secret isolation (Criterion #1)
- [x] D1 — `backend/schemas/blueprint.py` — thêm field `nocobase_collections: List[Dict] = []` vào `CompanyBlueprint`
- [x] D2 — `backend/blueprints/fashion-retail.yaml` — thêm `nocobase_collections:` block (Products, Outfits, Campaigns)
- [x] D3 — `backend/blueprints/software-studio.yaml` — thêm `nocobase_collections:` block (Repositories, Releases, Bugs)
- [x] D4 — `backend/blueprints/ecommerce-brand.yaml` — thêm `nocobase_collections:` block (Products, Orders, Campaigns)
- [x] D5 — `backend/blueprints/marketing-agency.yaml` — thêm `nocobase_collections:` block (Clients, Campaigns, Assets)
- [x] D6 — `backend/api/routes/companies.py:197-208` — xoá `role_to_collections` hardcode dict; thay bằng loop `blueprint.nocobase_collections`
- [x] D7 — `backend/services/blueprint_service.py:211` — xoá `COLLECTIONS_DEFS` hardcode list
- [x] D8 — `backend/models/company_secrets.py:18` — đổi `unique=True` → composite `UniqueConstraint('company_id', 'key')` + tạo Alembic migration
- [x] D9 — `backend/api/routes/companies.py:160-188` — bỏ auto-seed global env-var creds vào `CompanySecret`; document rõ operator seed per-company
- [x] D10 — Test: tạo 2 company → không DB constraint error trên `company_secrets` ✅
---
## 🟡 E — Fix coroutine warning + caching
- [x] E1 — `backend/api/routes/companies.py:188` — tìm và thêm `await` còn thiếu (RuntimeWarning: coroutine never awaited)
- [x] E2 — `backend/services/blueprint_service.py` — thêm `_cache: Dict[str, CompanyBlueprint] = {}` class-level; check cache trước khi đọc file trong `load_blueprint`
- [x] E3 — `rtk pytest backend/tests/ -W error::RuntimeWarning` → xanh ✅
---
## 🟡 F — E2E test chạy pipeline thật từ blueprint
- [x] F1 — `backend/tests/test_blueprint_e2e.py` — thêm test: load `software-studio` blueprint → build `pipeline_spec` → run `ProjectOrchestrator` với spec đó → assert stages != `PIPELINE_STAGES` default
- [x] F2 — Assert topo order đúng (vd: `architect` stage trước `coder` stage)
- [x] F3 — `rtk pytest backend/tests/ -k "blueprint or orchestrator" -q` → **≥6 tests pass** ✅
---
## 🔴 G — Frontend: loading states + DAG preview + i18n
- [x] G1 — `OnboardingWizard.tsx:119` — destructure `isLoading` từ `useQuery` blueprintsList; render `<Loader2>` spinner trong card grid khi `isLoading`
- [x] G2 — `OnboardingWizard.tsx:128` — destructure `isLoading` từ `useQuery` blueprintDetail; render shimmer trong right-panel preview khi loading
- [x] G3 — `OnboardingWizard.tsx:1600-1624` — implement DAG layer render: group nodes theo depth (topo-sort by `dependsOn`), render cùng layer theo hàng ngang, arrows theo `dependsOn`
- [x] G4 — `OnboardingWizard.tsx:426,452,733-738,1603` — import `useTranslation`; thay Vietnamese hardcode → `t('onboarding.xxx')`; thêm keys vào i18n resource files
- [x] G5 — `npm run build` → 0 errors ✅
---
## 🟡 H — Frontend: budget UX + empty-state + org-chart depth + mobile
- [x] H1 — `OnboardingWizard.tsx:836` — đổi label `"Ngân sách tháng (Cents)"` → `"Monthly Budget (USD)"`, nhận dollars nhân 100 khi store (hoặc suffix `$`)
- [x] H2 — `OnboardingWizard.tsx:775-799` — thêm empty-state khi `blueprintsList` rỗng + error state khi fetch fail (extract `isError`, `error`)
- [x] H3 — `OnboardingWizard.tsx:1538-1595` — thay 2-level hardcode → `RoleNode` component đệ quy render toàn bộ cây `reports_to`
- [x] H4 — `frontend/src/pages/Companies.tsx:93` — thêm badge `blueprintName` lên company cards; thêm CTA `"From Blueprint"` pre-select tab blueprint
---
## 🟢 I — Cleanup (low)
- [x] I1 — `backend/services/project_orchestrator.py` — rename `topological_sort_stages` → `_stages_from_spec` + gắn vào class (hoặc update roadmap note)
- [x] I2 — `backend/api/routes/companies.py:113` — thêm `response_model=List[BlueprintSummary]` vào `GET /companies/blueprints`
---
## ✅ Completion Gate
- [x] A10: grep canifa = 0 ✅
- [x] B4: pipeline/run nhận blueprint_id ✅
- [x] C4: reports_to validator hoạt động ✅
- [x] D10: 2 company không crash DB ✅
- [x] F3: ≥6 tests pass ✅
- [x] G5: tsc 0 errors ✅
---
_Created: 2026-06-01_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment