wal: flush 20260717T1446
This commit is contained in:
@ -0,0 +1,79 @@
|
||||
# sub-cicd-monitor-0 — S133 pe-budget-freeze deploy verify (commit d4fbced)
|
||||
|
||||
> Read-only CI/CD verifier. Evidence dồn dần (anti-#53). VERDICT ở cuối khi đủ 5 mục.
|
||||
> Target commit: `d4fbced02f6a24df7177c33adc21b8ca89140a0c`
|
||||
> Subject: `[CLAUDE] PurchaseEvaluation: freeze ngân sách phiếu DaDuyet — Mig 67 snapshot 11 cột + display-gate budgetFrozen + 2 terminal-guard (UAT anh Kiệt 07-16)`
|
||||
|
||||
## Stage 1 — Push + path-filter (DONE)
|
||||
- `git rev-parse origin/main` = `d4fbced02f6a24df7177c33adc21b8ca89140a0c` → d4fbced IS on origin/main. PASS.
|
||||
- `git branch -r --contains d4fbced` → `origin/main`. PASS.
|
||||
- Local HEAD = `bf79842 wal: flush 20260717T1116` (1 commit ahead, unpushed docs/WAL — NOT the target, irrelevant).
|
||||
- Files changed `9e874ca..d4fbced` (28 files): FULL-STACK
|
||||
- BE: PeBudgetAccumulator.cs, PeWorkItemBudgetFeatures.cs, PurchaseEvaluationFeatures.cs, PurchaseEvaluationDtos.cs, Domain/PurchaseEvaluation.cs, PurchaseEvaluationConfiguration.cs, DbInitializer.cs, PurchaseEvaluationWorkflowService.cs
|
||||
- Mig 67: `20260717032812_AddPeApprovedBudgetSnapshot.cs` + .Designer.cs + ApplicationDbContextModelSnapshot.cs
|
||||
- FE: fe-admin/{PeDetailTabs.tsx, types/purchaseEvaluation.ts}, fe-user/{PeDetailTabs.tsx, types/purchaseEvaluation.ts} → 4 real fe-src files → bundle MUST rotate ×2
|
||||
- Tests: PeBudgetFreezeTests.cs
|
||||
- Governance/memory/run-trace: .claude/WAL.md, agent-memory×4, run.md, spec + 4 sub-*.md
|
||||
- Non-docs code present → CI MUST trigger (NOT docs-skip). CONFIRMED triggered (run #398 exists).
|
||||
|
||||
## Stage 1b — Migration file review (Mig 67, DONE)
|
||||
- `20260717032812_AddPeApprovedBudgetSnapshot.cs`: 11 AddColumn on PurchaseEvaluations, 0 CreateTable:
|
||||
1. ApprovedBudgetProInitialAmount decimal(18,2) null
|
||||
2. ApprovedBudgetProAdjustmentAmount decimal(18,2) null
|
||||
3. ApprovedBudgetProNote nvarchar(1000) null
|
||||
4. ApprovedBudgetCcmInitialAmount decimal(18,2) null
|
||||
5. ApprovedBudgetCcmAdjustmentAmount decimal(18,2) null
|
||||
6. ApprovedBudgetCcmNote nvarchar(1000) null
|
||||
7. ApprovedBudgetPrevSubmittedTotal decimal(18,2) null
|
||||
8. ApprovedBudgetPrevSubmittedCount int null
|
||||
9. ApprovedBudgetPrevSelectedTotal decimal(18,2) null
|
||||
10. ApprovedBudgetPrevSelectedCount int null
|
||||
11. ApprovedBudgetSnapshotAt datetime2 null
|
||||
- Backfill `Sql()`: `UPDATE ... SET ... SnapshotAt=SYSUTCDATETIME() WHERE pe.Phase=7 AND pe.ApprovedBudgetSnapshotAt IS NULL AND pe.IsDeleted=0`. Idempotent. → post-apply ALL Phase=7 rows have SnapshotAt NOT NULL → expected chua=0.
|
||||
- NO CreateTable → sys.tables invariant 89 should hold.
|
||||
|
||||
## Stage 2 — Gitea CI poll (IN PROGRESS)
|
||||
- API: `/api/v1/repos/vietreport-admin/solution-erp/actions/tasks?limit=8` (anon, GITEA_TOKEN empty — public repo OK). NOT /runs (404, gotcha #46).
|
||||
- Run #398 | head_sha d4fbced02f | status=running | conclusion=None (prev #397 72f68d1 success — matches SPEC baseline).
|
||||
- Polling until terminal status... (conclusion stays None even on success per memory — trust `status`).
|
||||
|
||||
### Stage 2 RESULT — CI PASS
|
||||
- Run #398 (d4fbced02f) → `status=success` @ updated_at `2026-07-17T11:20:02+07:00` (conclusion=None = Gitea tasks-API norm, trust status). Prev #397 success — baseline OK.
|
||||
- Poll note: python subprocess `capture_output=True` (text) crashed cp1252 on Vietnamese titles ×14 iters; re-fetch with `text=False`(bytes)+`json.loads(bytes)` → clean. Elapsed ~6min covered the run.
|
||||
- Test gate (web-UI log `runs/398/jobs/0/logs`, 17936 bytes, NO /api/v1):
|
||||
- `Passed! - Failed: 0, Passed: 45, Skipped: 0, Total: 45` — SolutionErp.Domain.Tests
|
||||
- `Passed! - Failed: 0, Passed: 475, Skipped: 0, Total: 475` — SolutionErp.Infrastructure.Tests
|
||||
- 45 + 475 = **520**, 0 fail/skip → matches SPEC baseline. **PASS.**
|
||||
|
||||
## Item 2 — Mig prod (ssh vietreport-vps sqlcmd, DONE)
|
||||
- `__EFMigrationsHistory` TOP3: `20260717032812_AddPeApprovedBudgetSnapshot` (top) · `20260714035636_AddPeApprovedPriceRange` · `20260712142652_Backfill...` → top == SPEC target. **PASS.**
|
||||
- sys.columns ApprovedBudget* on PurchaseEvaluations = **11** (all 11 names present, exact match to Mig 67 file). **PASS.**
|
||||
- Backfill `WHERE Phase=7 AND IsDeleted=0`: total=**18**, chua(SnapshotAt IS NULL)=**0** → all 18 DaDuyet phiếu snapshotted. **PASS.**
|
||||
- sys.tables is_ms_shipped=0 = **89** (no new table — AddColumn-only). **PASS.**
|
||||
|
||||
## Item 3 — Bundle FE rotate + byte-verify #77 (DONE)
|
||||
- ADMIN index.html: js `/assets/index-3NCdyODe.js` css `/assets/index-B--dUHcm.css` (was S129 js `yCkX-2Bp` css `CXD7q9xH`) → JS+CSS ROTATED.
|
||||
- EOFFICE index.html: js `/assets/index-CKsoiNCI.js` css `/assets/index-BuntB63r.css` (was S129 js `DKSD4p9k` css `CjwZwYJo`) → JS+CSS ROTATED.
|
||||
- Real-size + LM: admin.js 1,657,025 B, LM `Fri 17 Jul 2026 04:18:42 GMT` (11:18:42 +07) · eoffice.js 1,563,373 B, LM `04:19:36 GMT` (11:19:36 +07) — both application/javascript, LM in CI window (run done 11:20:02 +07). NOT SPA-trap.
|
||||
- Byte-verify markers (python bytes-search): admin.js `budgetFrozen`=1, `Ngân sách chốt tại thời điểm duyệt`=1 · eoffice.js both=1.
|
||||
- CONTROL old admin `yCkX-2Bp` → 900 B text/html (SPA-fallback trap), markers=0 → confirms markers are NEW not fallback. **PASS.**
|
||||
|
||||
## Item 4 — Smoke (DONE)
|
||||
- api/health/live=200 · api/health/ready=200 (body "Healthy") · admin=200 · eoffice=200 · GET /api/purchase-evaluations no-token=**401** (secured). **PASS.**
|
||||
|
||||
## Item 5 — Traps handled
|
||||
- S116: polled CI to `success` BEFORE bundle snapshot ✓ · #69: rotate benign (4 real fe-src changed → rotate expected) ✓ · #77: curl byte-level + old-hash control (900b SPA-trap) not browser ✓.
|
||||
|
||||
---
|
||||
|
||||
## VERDICT | GO (5/5 PASS)
|
||||
| # | Item | Verdict | Key evidence |
|
||||
|---|------|---------|--------------|
|
||||
| 1 | CI run #398 + gate 520 | PASS | status=success; Domain 45/45 + Infra 475/475, 0 fail |
|
||||
| 2 | Mig 67 prod applied | PASS | history top=AddPeApprovedBudgetSnapshot; 11 cols; backfill 18/18 chua=0; 89 tables |
|
||||
| 3 | Bundle rotate ×2 + byte-verify | PASS | admin js 3NCdyODe / eoffice js CKsoiNCI; markers present; old-control 0; real-size+LM-in-window |
|
||||
| 4 | Smoke 5-probe | PASS | live/ready 200, admin/eoffice 200, PE no-token 401 |
|
||||
| 5 | Traps (S116/#69/#77) | PASS | poll-then-snapshot; benign rotate; byte-level+control |
|
||||
|
||||
Run URL: https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp/actions/runs/398
|
||||
Token cost: ~90K. No production file modified (only this run-trace sub-file).
|
||||
@ -60,3 +60,60 @@ Failed! - Failed: 1, Passed: 0, Skipped: 0, Total: 1, Duration:
|
||||
|
||||
**Verdict:** T0 RED PASS-as-designed. KHÔNG PREMISE-FAIL (không GREEN bất ngờ). KHÔNG chạm production. Sẽ GREEN sau khi implementer thêm snapshot ngân sách tại 4 site DaDuyet + display-gate đọc cột snapshot.
|
||||
**Baseline:** 509 → 510 test (test này RED tới khi fix land — test-before đúng quy trình bug-fix docs/rules.md §7).
|
||||
|
||||
---
|
||||
|
||||
# STAGE C — INV-C T1-T9 (BE ĐÃ LAND, T0 ĐÃ GREEN → phủ nhánh/guard/edge còn lại)
|
||||
|
||||
Role: test-specialist. KHÔNG đụng src/ · KHÔNG sửa T0/test cũ. Thêm T1-T9 vào cùng file `PeBudgetFreezeTests.cs`.
|
||||
|
||||
## Anchors verified (đọc code truth — BE post-fix)
|
||||
- Domain `PurchaseEvaluation.cs:122-132` — 11 cột snapshot: ApprovedBudgetProInitialAmount/ProAdjustmentAmount/ProNote · CcmInitialAmount/CcmAdjustmentAmount/CcmNote · PrevSubmittedTotal/Count · PrevSelectedTotal/Count · SnapshotAt.
|
||||
- Service helper `ApplyBudgetSnapshotOnFinalizeAsync` def :994; gọi 4 site: :861 (level-finalize AllowApproverFinalize) · :900 (CCM-threshold delegation) · :933 (all-steps-done) · :1108 (V1 legacy — CHỈ snapshot, KHÔNG ApplyApprovedPrice). Helper: WorkItemId null → 10 cột null + SnapshotAt set; pair thiếu → 6 pair cols null; 4 lũy kế qua PeBudgetAccumulator; LUÔN overwrite + LUÔN SnapshotAt=dateTime.UtcNow.
|
||||
- Helper NAMING: pair.InitialAmount/AdjustmentAmount = CCM; pair.ProInitialAmount/ProAdjustmentAmount = PRO.
|
||||
- Display-gate `PurchaseEvaluationFeatures.cs:928` `frozen = Phase==DaDuyet && ApprovedBudgetSnapshotAt!=null`. Frozen branch :929-954 → CanEditPro/Ccm HARDCODE false,false (KỂ CẢ Admin) + BudgetFrozen=true + lũy kế từ snapshot + CurrentProposalTotal VẪN live-own-quotes. Live branch :956-984 → accumulator + canEditPro/Ccm theo role + BudgetFrozen=false.
|
||||
- Guard 7a `SetPeCcmBudgetPeriodCommandHandler` PeWorkItemBudgetFeatures.cs:235 — `Phase is DaDuyet or TuChoi` → Conflict TRƯỚC role-gate (chặn CẢ Admin lẫn CCM).
|
||||
- Guard 7b `AdjustPurchaseEvaluationBudgetCommandHandler` PurchaseEvaluationFeatures.cs:365 — cùng message, TRƯỚC isAdmin block.
|
||||
- Accumulator: peers cùng (ProjectId,WorkItemId), Id!=this, CreatedAt<this. ⚠️ TestApplicationDbContext KHÔNG wire audit interceptor → set CreatedAt thủ công (peers earlier, current later).
|
||||
- V1 legacy: PurchaseEvaluationWorkflowDefinition + Steps + Approvers(Kind=User AssignmentValue=userId). Match qua userManager.FindByIdAsync → cần user THẬT (fix.CreateUserAsync).
|
||||
|
||||
## T1-T9 danh sách (tên test = scenario_expected)
|
||||
- T1 `LevelFinalize_SnapshotsAll11Columns_FromPairAndAccumulator` (:861) — 6 pair cột + notes + 2 peer (PrevSubmitted 150tr/2, PrevSelected 90tr/1) + SnapshotAt.
|
||||
- T2 `CcmThresholdFinalize_SetsBudgetSnapshot` (:900) — CCM delegation below-threshold → snapshot pair cols + SnapshotAt.
|
||||
- T3 `AllStepsDoneFinalize_SetsBudgetSnapshot` (:933) — 1 Bước 1 Cấp no-finalize-flag, approve last slot → snapshot + DaDuyet.
|
||||
- T4 `V1LegacyFinalize_SetsBudgetSnapshot_WithoutApprovedPrice` (:1108) — def+step+user-approver → snapshot set + ApprovedPriceAmount==null.
|
||||
- T5 `SetCcmBudgetPeriodGuard_BlocksDaDuyet_ForCcmAndAdmin_AllowsChoDuyet`.
|
||||
- T6 `AdjustBudgetGuard_BlocksDaDuyetAndTuChoi_ForAdmin`.
|
||||
- T7 `BudgetSummary_LiveVsFrozen_FlagsAndEditability`.
|
||||
- T8 `Finalize_NullSafe_NoWorkItemAndNoPairRecord`.
|
||||
- T9 `ReFinalize_AlwaysOverwritesStaleSnapshot_RefreshesSnapshotAt`.
|
||||
|
||||
## Kết quả chạy — ✅ ALL GREEN (T1-T9 phủ đủ, 0 RED phase vì BE đã land)
|
||||
|
||||
**Filtered:** `dotnet test SolutionErp.slnx --filter "FullyQualifiedName~PeBudgetFreeze" --nologo -p:BuildInParallel=false -maxcpucount:1`
|
||||
→ `Passed! - Failed: 0, Passed: 10, Skipped: 0, Total: 10` (T0 + T1-T9).
|
||||
|
||||
**FULL:** `dotnet test SolutionErp.slnx --nologo --verbosity minimal -p:BuildInParallel=false -maxcpucount:1`
|
||||
→ Domain `Passed! - Failed: 0, Passed: 45, Skipped: 0, Total: 45`
|
||||
→ Infra `Passed! - Failed: 0, Passed: 474, Skipped: 0, Total: 474`
|
||||
→ **Tổng 519 PASS / 0 fail / 0 skip** = baseline 510 (509 + T0) + 9 (T1-T9).
|
||||
|
||||
## Bảng T1-T9 (verdict)
|
||||
| Test | Nhánh/guard/edge | Verdict |
|
||||
|---|---|---|
|
||||
| T1 `LevelFinalize_SnapshotsAll11Columns_FromPairAndAccumulator` | :861 level-finalize → 11 cột | PASS |
|
||||
| T2 `CcmThresholdFinalize_SetsBudgetSnapshot` | :900 CCM-delegation | PASS |
|
||||
| T3 `AllStepsDoneFinalize_SetsBudgetSnapshot` | :933 all-steps | PASS |
|
||||
| T4 `V1LegacyFinalize_SetsBudgetSnapshot_WithoutApprovedPrice` | :1108 V1 + giá null | PASS |
|
||||
| T5 `SetCcmBudgetPeriodGuard_BlocksDaDuyet_ForCcmAndAdmin_AllowsChoDuyet` | guard 7a | PASS |
|
||||
| T6 `AdjustBudgetGuard_BlocksDaDuyetAndTuChoi_ForAdmin` | guard 7b | PASS |
|
||||
| T7 `BudgetSummary_LiveVsFrozen_FlagsAndEditability` | display live/frozen | PASS |
|
||||
| T8 `Finalize_NullSafe_NoWorkItemAndNoPairRecord` | null-safe (a)+(b) | PASS |
|
||||
| T9 `ReFinalize_AlwaysOverwritesStaleSnapshot_RefreshesSnapshotAt` | overwrite semantics | PASS |
|
||||
|
||||
## Surprise / bẫy đã xử
|
||||
- **UNIQUE(ApprovalWorkflows.Code, Version)**: T8 gọi `SeedAndFinalizeAsync` 2 lần/1 db → helper `SeedFinalizeWorkflowAsync` Code cố định "QT-BF-V2" v1 → SQLite Error 19 (RED lần 1). Fix: thêm param optional `code="QT-BF-V2"` (T0 call-site 2-arg GIỮ NGUYÊN, hành-vi T0 bất biến) + `SeedAndFinalizeAsync` truyền `$"QT-BF-V2-{suffix}"`. Không đụng T0-logic.
|
||||
- KHÔNG chạm src/ production. KHÔNG sửa T0. Test cũ CŨ 0 regression (509 baseline vẫn xanh). KHÔNG REGRESSION-FOUND.
|
||||
|
||||
**Verdict:** INV-C COMPLETE — 9 test mới GREEN, phủ 4 nhánh snapshot + 2 guard + 2 edge + display live/frozen. Tổng 519/519.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user