4.4 KiB
sub-test-specialist-0 — W1 KHKK Mig 69: schema-invariant test + codegen format test
Ghi TỪNG MỤC trong lúc làm (chống #53). Run:
2026-07-29-S161-khkk-w1-schema. Vai: test-specialist (WRITE độc quyềntests/**). KHÔNG sửa production, KHÔNG commit.
§0 — Tiền đề đọc từ ĐĨA (trước khi viết 1 dòng test)
Spec đọc: .claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/spec-wave-w1-schema-designer-29-07-2026.md
- §③-B dòng 35: test PIN tên
ContractSigningPlanSchemaTests.BayBang_MoiBang_CoAuditFields_VaQueryFilter, sànN ≥ 2, số-sau ≥ số-trước + 2. - §③-B dòng 36: test PIN tên
SigningPlanCodeGenerator_Format_KhkkYearSeqD3— regex^KHKK/\d{4}/\d{3}$+ 2 lần gọi seq tăng.
7 entity — base class ĐO THẬT trên đĩa (KHÔNG đoán)
| # | Entity | File | Base | Query filter (config) |
|---|---|---|---|---|
| 1 | ContractSigningPlan |
Domain/ContractSigningPlans/ContractSigningPlan.cs:16 |
AuditableEntity |
✅ ContractSigningPlanConfiguration.cs:47 |
| 2 | ContractSigningPlanLine |
ContractSigningPlanLine.cs:14 |
AuditableEntity |
✅ ContractSigningPlanLineConfiguration.cs:36 |
| 3 | ContractSigningPlanDossierItem |
ContractSigningPlanDossierItem.cs:31 |
AuditableEntity |
✅ ...DossierItemConfiguration.cs:29 |
| 4 | ContractSigningPlanAttachment |
ContractSigningPlanAttachment.cs:24 |
AuditableEntity |
✅ ...AttachmentConfiguration.cs:39 |
| 5 | ContractSigningPlanLevelOpinion |
ContractSigningPlanLevelOpinion.cs:24 |
AuditableEntity |
❌ CỐ Ý KHÔNG có |
| 6 | ContractSigningPlanChangelog |
ContractSigningPlanChangelog.cs:26 |
BaseEntity |
❌ (đúng — no IsDeleted) |
| 7 | ContractSigningPlanApproval |
ContractSigningPlanApproval.cs:19 |
BaseEntity |
❌ (đúng — no IsDeleted) |
🔴 LỆCH so mô-tả trong TASK-prompt (prompt liệt LevelOpinion = AuditableEntity có IsDeleted ⇒ ngụ ý phải có query filter). ĐĨA nói khác: ContractSigningPlanLevelOpinion LÀ AuditableEntity nhưng CỐ Ý KHÔNG HasQueryFilter, có lý do viết sẵn 2 chỗ:
- entity
ContractSigningPlanLevelOpinion.cs:20-23: "CỐ Ý KHÔNG có HasQueryFilter (parity 7 twin còn lại): site 'dọn chữ ký MỒ CÔI' (ApprovalWorkflowV2AdminFeatures ExecuteDeleteAsync) phải THẤY được row đã soft-delete, nếu bị filter che thì row mồ côi sống sót và FK Restrict lại nổ 500." - config
ContractSigningPlanLevelOpinionConfiguration.cs:12-16: cùng nội dung.
⇒ Áp luật MEMORY "spec drift detection BEFORE write (S34)": test theo CODE, không theo prompt. Nhưng KHÔNG bỏ qua — assert LevelOpinion KHÔNG có filter như một invariant CÓ CHỦ Ý (nếu ai đó thêm filter sau này ⇒ test ĐỎ ⇒ buộc đọc lại lý do). Đây là assert có RĂNG, không phải né.
Codegen
src/Backend/SolutionErp.Infrastructure/Services/ContractSigningPlanCodeGenerator.cs
- ctor
(IApplicationDbContext db, IDateTime dateTime)—:12 GenerateAsync(CancellationToken ct = default)— KHÔNG nhận entity (khác PE nhậnPurchaseEvaluation)- prefix
$"KHKK/{year}", return$"{prefix}/{seq.LastSeq:D3}"—:20,:45 BeginTransactionAsync(IsolationLevel.Serializable, ct)—:24-25- sequence sống ở
db.WorkflowAppCodeSequences(bảng DÙNG CHUNG Office), PKPrefix
Tiền lệ SQLite + Serializable — ĐÃ CÓ, không cần chế mới
tests/SolutionErp.Infrastructure.Tests/Common/SqliteDbFixture.cs:36-42 ghi rõ:
"SQLite hỗ trợ transactions thật (BEGIN/COMMIT/ROLLBACK), tuy nhiên IsolationLevel enum value bị provider mapping gracefully (no exception, just default behavior)"
Và PurchaseEvaluationCodeGeneratorTests.cs:17 gọi thẳng new PurchaseEvaluationCodeGenerator(fix.Db, dt) — generator PE cũng Serializable, test cũ chạy XANH nhiều session ⇒ dùng y khuôn, KHÔNG đụng production.
FixedDateTime stub: SqliteDbFixture.cs:71.
§1 — Test đã viết
File MỚI: tests/SolutionErp.Infrastructure.Tests/Application/ContractSigningPlanSchemaTests.cs
(đặt cạnh EmployeeSatelliteTests.cs — cùng lớp "EF-model assertion", khuôn EmployeeSatelliteTests.cs:248-261 db.Model.FindEntityType(...)).
(chi tiết điền sau khi chạy — xem §2/§3)
§2 — Số đo
(điền sau)
§3 — Verdict
(điền sau)