# 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:** `<pending>` (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`
