[CLAUDE] Contract: K2 SP-002 phieu KHKK mang hang-muc + nhom duyet N1-8 (Mig 71) + FE x2 app + 11 test
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 6m12s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 6m12s
Mig 71 AddKhkkApprovalGroupCatalogAndFinalizeRuntime: +ApprovalGroup (backfill=1)
+EndedByLevelFinalize (K2 de, K3 tieu - ghost-window khai) + Line +CatalogEntryId/
TenHangMuc + unique (Plan,Supplier,CatalogEntry) filtered IsDeleted=0. Rao
1-PE-1-phieu doi (PeId,ApprovalGroup) 2 site + picker OG-7 ExistingGroups + nut
'Tao them cho nhom khac'. Submit-guard va-5 (CHAN null, thang nen cho-qua-legacy;
ghost-window K2->K4b khai) + dem-so-khop (gate F-1: bit duong hang-muc xoa-mem).
List ?group= end-to-end + Tong-Approved list (va-8). FE: select nhom default 1 +
badge N{g} + cot Hang-muc + cot Tong-duyet, SHA-pair 5/5. Gate K2 PASS-WITH-FLAGS
10f: F-1 guard fix + 2 test bit (xoa-mem chan + reflection ?group=); F-2/F-5/F-7/
F-8/F-9 comment-honest; F-3/F-4 docs-delta. Suite 609/0 (45D+564I). Wave co #53 x5,
artifact + relaunch-cat-got cuu 100% (0 mat cong).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@ -193,11 +193,17 @@ public class ContractSigningPlanSchemaTests
|
||||
db.ContractSigningPlans.Add(plan);
|
||||
|
||||
var supplierId = Guid.NewGuid();
|
||||
// [K2 Mig 71] UNIQUE nay 3 cột (PlanId, SupplierId, CatalogEntryId). CẢ HAI vế của test
|
||||
// dùng CatalogEntryId NON-NULL GIỐNG NHAU để phép đo độc lập provider: SQLite coi
|
||||
// NULL ≠ NULL trong unique (cặp NULL không nổ) còn SQL Server coi bằng nhau — cặp NULL
|
||||
// do SUBMIT-GUARD (WorkflowService) chặn ở tầng nghiệp vụ, không đo ở đây.
|
||||
var catalogId = Guid.NewGuid(); // loose-Guid — index test không cần row danh mục thật
|
||||
db.ContractSigningPlanLines.Add(new ContractSigningPlanLine
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
ContractSigningPlanId = plan.Id,
|
||||
SupplierId = supplierId,
|
||||
CatalogEntryId = catalogId,
|
||||
PeReferenceAmount = 100_000_000m,
|
||||
ProposedAmount = 95_000_000m,
|
||||
});
|
||||
@ -217,13 +223,14 @@ public class ContractSigningPlanSchemaTests
|
||||
Id = Guid.NewGuid(),
|
||||
ContractSigningPlanId = plan.Id,
|
||||
SupplierId = supplierId,
|
||||
CatalogEntryId = catalogId, // trùng cả 3 cột với dòng đã XOÁ MỀM
|
||||
PeReferenceAmount = 100_000_000m,
|
||||
ProposedAmount = 90_000_000m,
|
||||
});
|
||||
|
||||
var act = async () => await db.SaveChangesAsync();
|
||||
await act.Should().NotThrowAsync(
|
||||
"UNIQUE (PlanId, SupplierId) phải là filtered `WHERE [IsDeleted] = 0` — gotcha #57");
|
||||
"UNIQUE (PlanId, SupplierId, CatalogEntryId) phải là filtered `WHERE [IsDeleted] = 0` — gotcha #57");
|
||||
|
||||
db.ContractSigningPlanLines.AsNoTracking()
|
||||
.Count(x => x.ContractSigningPlanId == plan.Id)
|
||||
@ -246,23 +253,48 @@ public class ContractSigningPlanSchemaTests
|
||||
};
|
||||
db.ContractSigningPlans.Add(plan2);
|
||||
var dupSupplierId = Guid.NewGuid();
|
||||
foreach (var _ in new[] { 1, 2 })
|
||||
var dupCatalogId = Guid.NewGuid();
|
||||
db.ContractSigningPlanLines.Add(new ContractSigningPlanLine
|
||||
{
|
||||
db.ContractSigningPlanLines.Add(new ContractSigningPlanLine
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
ContractSigningPlanId = plan2.Id,
|
||||
SupplierId = dupSupplierId,
|
||||
PeReferenceAmount = 1m,
|
||||
ProposedAmount = 1m,
|
||||
});
|
||||
}
|
||||
Id = Guid.NewGuid(),
|
||||
ContractSigningPlanId = plan2.Id,
|
||||
SupplierId = dupSupplierId,
|
||||
CatalogEntryId = dupCatalogId,
|
||||
PeReferenceAmount = 1m,
|
||||
ProposedAmount = 1m,
|
||||
});
|
||||
await db.SaveChangesAsync(); // dòng 1 sống — mốc đối chứng
|
||||
|
||||
db.ContractSigningPlanLines.Add(new ContractSigningPlanLine
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
ContractSigningPlanId = plan2.Id,
|
||||
SupplierId = dupSupplierId,
|
||||
CatalogEntryId = dupCatalogId, // TRÙNG cả 3 cột, cả 2 còn SỐNG
|
||||
PeReferenceAmount = 1m,
|
||||
ProposedAmount = 1m,
|
||||
});
|
||||
var actDup = async () => await db.SaveChangesAsync();
|
||||
await actDup.Should().ThrowAsync<DbUpdateException>(
|
||||
"2 dòng SỐNG cùng (PlanId, SupplierId) phải bị UNIQUE chặn — vế này chứng "
|
||||
"2 dòng SỐNG cùng (PlanId, SupplierId, CatalogEntryId) phải bị UNIQUE chặn — vế này chứng "
|
||||
+ "index thật sự tồn tại, nên vế 'xoá mềm rồi thêm lại KHÔNG nổ' ở trên "
|
||||
+ "là do FILTER chứ không phải do thiếu index");
|
||||
db.ChangeTracker.Clear();
|
||||
|
||||
// [K2 Mig 71] Vế MỞ — chính tính năng K2: CÙNG (Plan, NCC) nhưng KHÁC hạng mục = 2 dòng
|
||||
// hợp lệ (tách 1 NCC theo nhiều hạng mục). Unique 2 cột cũ CẤM ca này — nay phải QUA.
|
||||
db.ContractSigningPlanLines.Add(new ContractSigningPlanLine
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
ContractSigningPlanId = plan2.Id,
|
||||
SupplierId = dupSupplierId,
|
||||
CatalogEntryId = Guid.NewGuid(), // hạng mục KHÁC ⇒ được phép
|
||||
PeReferenceAmount = 1m,
|
||||
ProposedAmount = 1m,
|
||||
});
|
||||
var actSplit = async () => await db.SaveChangesAsync();
|
||||
await actSplit.Should().NotThrowAsync(
|
||||
"unique 3 cột phải CHO PHÉP cùng (Plan, NCC) khác CatalogEntryId — mục đích của Mig 71");
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
Reference in New Issue
Block a user