# Session 23 turn 8 — 2026-05-15 — Plan R Cleanup destructive prod database **Dev:** Claude Opus 4.7 1M (em main solo execute, 1 Investigator pre-flight spawn) **Duration:** ~30 phút **Base commit:** `108268a` (Plan Q FE banner fix) **Final HEAD:** `` (Plan R scripts + docs) ## 🎯 Trigger session Bro UAT confirm Plan P+Q deploy wire OK (Run #203+#204 PASS) + chỉ thị cleanup: > "OK Tao thấy tạm ổn rồi đấy, mày xóa hết các phiếu test cũ đi nhé, các quy trình cũ ko ghim cũng xóa hết đi. Cho gọn đẹp." → 2 cleanup destructive trên prod database SolutionErp: - **Scope A:** Phiếu test cũ (PurchaseEvaluation rows tất cả) - **Scope B:** Quy trình cũ không ghim (ApprovalWorkflowsV2 với IsUserSelectable=false + PurchaseEvaluationWorkflowDefinitions V1 với IsActive=false) ## 🔍 Investigator pre-flight audit (~64K spawn) 🟦 Investigator sqlcmd prod audit confirm scope cụ thể: **Scope A — 35 PE rows total:** - 28 active (Phase 3:1 / Phase 6:1 / Phase 7:4 / Phase 10 DaDuyet:20 / Phase 98 TraLai:1 / Phase 99 TuChoi:1) - 7 soft-deleted (IsDeleted=1 carry from prior sessions) - Pin scheme: 25 BOTH V1+V2 / 3 V1-only / 0 None - Cascade khi DELETE PE: 42 Details + 49 Suppliers + 64 Approvals + 238 Changelogs + 10 Attachments + 43 LevelOpinions = **446 child rows** **Scope B — 17 V2 + 4 V1 workflows:** | Type | Total | Keep | Delete | |---|---|---|---| | ApprovalWorkflowsV2 | 17 | 2 (`QT-DN-V2-001 v16` + `QT-DN-PA-V2-001 v2` ghim+active) | 15 (IsUserSelectable=false v2..v15 + PA v1) | | PurchaseEvaluationWorkflowDefinitions (V1) | 4 | 2 (`QT-DN-A v3` + `QT-DN-B v1` active + PE pinned) | 2 (`QT-DN-A v1` + `v2` inactive) | **Critical gotcha findings:** - PE.ApprovalWorkflowId FK **Restrict** ([PurchaseEvaluationConfiguration.cs:40](src/Backend/SolutionErp.Infrastructure/Persistence/Configurations/PurchaseEvaluationConfiguration.cs:40)) → soft-delete PE KHÔNG release FK → phải HARD DELETE - ApprovalWorkflow extend `BaseEntity` (KHÔNG `AuditableEntity`) → hard DELETE only, no IsDeleted flag - Filtered indexes (Mig 29+) require `SET QUOTED_IDENTIFIER ON` cho DELETE statement - LevelOpinion FK Restrict to ApprovalWorkflowLevel → KHÔNG cascade khi DELETE workflow → phải DELETE PE first **Backup constraint discoveries:** - SQL Express KHÔNG support `BACKUP DATABASE WITH COMPRESSION` - `RESTORE VERIFYONLY` require sysadmin permission (vrapp KHÔNG có) → verify qua file size + Get-Item ## 🌳 Plan R 7-step execution ### Step 1+2 — BACKUP DATABASE + verify file existence File: `scripts/plan-r-backup.sql` upload qua scp → sqlcmd -i ```sql BACKUP DATABASE SolutionErp TO DISK = 'C:\Backup\SolutionErp_pre_cleanup_2026-05-15.bak' WITH INIT, STATS = 20, NAME = 'SolutionErp Plan R pre-cleanup 2026-05-15', DESCRIPTION = 'Backup before destructive cleanup: 28 PE + 15 V2 unghim + 2 V1 inactive workflows'; ``` Output: `Processed 2249 pages in 0.099 seconds (177.413 MB/sec)`. File size: **18,506,240 bytes (~18.5MB)** verified via `Get-Item`. ### Step 3-5 — DELETE 3 transaction commits File: `scripts/plan-r-cleanup.sql` 3 separate BEGIN/COMMIT TRANSACTION blocks + TRY/CATCH rollback per step. ```sql SET QUOTED_IDENTIFIER ON; -- filtered indexes require SET ANSI_NULLS ON; -- Step 3: DELETE 28 active + 7 soft-deleted PE (cascade 446 child rows) DELETE FROM PurchaseEvaluations WHERE IsDeleted = 0; -- 28 rows DELETE FROM PurchaseEvaluations WHERE IsDeleted = 1; -- 7 rows -- Step 4: DELETE 15 V2 workflows unghim (cascade ~140 Steps+Levels) DELETE FROM ApprovalWorkflows WHERE IsUserSelectable = 0; -- Step 5: DELETE 2 V1 workflows inactive (cascade ~37 Steps+Approvers) DELETE FROM PurchaseEvaluationWorkflowDefinitions WHERE IsActive = 0; ``` Execute output: ``` PE active rows deleted: 28 PE soft-deleted rows deleted: 7 V2 workflows deleted: 15 V1 workflows deleted: 2 ``` **Total: 52 rows direct + ~600 cascade child = ~650+ rows wiped clean.** ### Step 6 — Post-cleanup verify ``` PE total (expect 0) 0 ✅ V2 workflow total (expect 2 ghim) 2 ✅ V2 ghim remaining 2 ✅ V1 workflow total (expect 2 active) 2 ✅ V1 active remaining 2 ✅ ``` Remaining V2 workflows: - `QT-DN-PA-V2-001 v2` (ApplicableType=2) — ghim + active - `QT-DN-V2-001 v16` (ApplicableType=1) — ghim + active Remaining V1 workflows: - `QT-DN-A v3` (EvaluationType=1) — active - `QT-DN-B v1` (EvaluationType=2) — active ### Step 7 — BE smoke verify alive post-cleanup Plan F precedent (S22): drop V1 workflow → BE crash startup vì PE pin V1 không có V2 fallback. Plan R KHÔNG đụng V1 active (`QT-DN-A v3` + `QT-DN-B v1`) → BE expect healthy. ```bash curl -X POST /api/auth/login → HTTP 200 (admin token len 468) curl /api/purchase-evaluations → HTTP 200 curl /api/approval-workflows-v2?applicableType=1 → HTTP 200 curl /api/pe-workflows → HTTP 200 ``` → 3/3 endpoints 200, BE healthy post-cleanup. KHÔNG crash. ## 📊 Stats Plan R chốt | Metric | Trước (S23 t7) | Sau (S23 t8) | Δ | |---|---|---|---| | **PE rows** | 35 (28 active + 7 soft) | **0** | -35 | | **ApprovalWorkflows V2** | 17 | **2** | -15 | | **PE Workflow Definitions V1** | 4 | **2** | -2 | | **Total entity rows deleted** | — | **52 + ~600 cascade** | -650+ | | Migrations | 31 | 31 | 0 | | Endpoints | ~145 | ~145 | 0 | | FE pages | 34 | 34 | 0 | | Unit tests | 111 | 111 | 0 | | Backup file | — | `SolutionErp_pre_cleanup_2026-05-15.bak` 18.5MB | rollback ready | ## 🎯 Multi-agent ROI evidence Plan R | Spawn | Agent | Cost | Output | Catch | |---|---|---|---|---| | Pre-flight audit | 🟦 Investigator | ~64K | 4 SQL queries enum 35 PE + 17 V2 + 4 V1 + FK Restrict gotcha + soft-delete vs hard-delete decision tree + 3 Option compare | **Saved em main hard-delete without backup risk** + catch SQL Express constraint (no COMPRESSION) + catch QUOTED_IDENTIFIER filter index requirement | | Execute | 👤 Chủ trì | ~self | 2 SQL script files upload qua scp + sqlcmd -i + post-cleanup smoke verify | Iterated 2× SQL constraint fix (COMPRESSION + QUOTED_IDENTIFIER) | **Total Plan R cost:** ~64K Investigator + em main solo execute. Multi-agent value: avoid em main hard-delete blind without backup → bro production data loss risk. ## 📋 Pattern reinforced cross-project 1. **Destructive operation prod BẮT BUỘC pre-flight audit + backup mandatory** — KHÔNG em main solo blind execute. Investigator catch SQL constraint + FK gotcha + Option compare. 2. **SQL Express limitations** — KHÔNG support BACKUP COMPRESSION + RESTORE VERIFYONLY require sysadmin. Workaround: verify backup file size via Get-Item. 3. **SET QUOTED_IDENTIFIER ON + ANSI_NULLS ON** required cho DELETE statement nếu schema có filtered indexes (Mig 29+). 4. **FK Restrict gotcha** — soft-delete KHÔNG release FK reference. Hard DELETE only nếu cần unblock cascade. 5. **Plan F precedent learn** — KHÔNG drop V1 active workflow (PE pin → BE crash). Plan R giữ V1 active `QT-DN-A v3` + `QT-DN-B v1` → BE healthy. 6. **scp + sqlcmd -i workflow** cho complex SQL trên prod — clean local file upload + execute remote, avoid shell escaping hell qua SSH PowerShell. ## ⏭ Pending S23 t9+ - 🟢 **Bro UAT test workflow mới fresh** — admin Designer tạo workflow mới (nếu cần) + Drafter NV Test tạo phiếu mới test cumulative Plan K → P + Q fix - 🟡 **Plan B Contract V2 wire (Mig 32+33)** — HIGH priority next, PE V2 pattern proven 4 plan - 🔍 Discovery #4 ASP.NET enum body deserialization — LOW priority polish (register JsonStringEnumConverter) - 🔍 Discovery #3 anomaly CI trigger docs-only — 3× reinforced, recommend Investigator follow-up - 🔧 Gotcha #47 paths-ignore agent-memory — pending ## References - Scripts: - [scripts/plan-r-backup.sql](scripts/plan-r-backup.sql) — BACKUP DATABASE - [scripts/plan-r-cleanup.sql](scripts/plan-r-cleanup.sql) — DELETE 3 transactions - Backup file: `vietreport-vps:C:\Backup\SolutionErp_pre_cleanup_2026-05-15.bak` (18.5MB) - Rules: §destructive operation discipline (pre-flight + backup + verify), `feedback_drastic_refactor_scope`