[CLAUDE] Domain+App+Infra+Admin: W1 KHKK — Mig 69 ContractSigningPlans 7 bang + policy KeHoachKyKet + seeder UPGRADE-if-exists + CodeGen KHKK + Designer type-10
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m40s

- Domain/ContractSigningPlans: 7 entity + 3 enum (Phase 1/2/3/98/99; DossierItem Kind/Status start=1); ApplicableType += ContractSigningPlan=10 (slot 10, append-only)
- Mig 69 AddContractSigningPlans: 7 CreateTable / 20 CreateIndex / 0 ALTER; UNIQUE filtered (PlanId,SupplierId) WHERE IsDeleted=0 (#57); FK 6 con Cascade 1-hop + 2 Restrict, 0 multiple-cascade-path; database-agent review PASS 8/8 + DB11
- MenuKeys.All += KeHoachKyKet (policy KeHoachKyKet.* x4 sinh runtime; menu-row prod KHONG doi — 142 giu); STATUS canonical 54->55 / 216->220
- DbInitializer.SeedKeHoachKyKetAccessAsync: UPGRADE-if-exists (F-S1 — khong insert-NO-OP) + vế CanDelete (Drafter/Admin), 13/13 role CanCreate+CanUpdate, chay SAU revoke; revoker khong phu Khkk_* (reviewer Truc-1 PASS)
- ContractSigningPlanCodeGenerator: KHKK/{YYYY}/{Seq:D3} (owner OK @S161) qua WorkflowAppCodeSequences dung chung, SERIALIZABLE
- AWV2AdminFeatures: 3 site count/retained/orphan + nhanh ContractSigningPlanLevelOpinions (chong no FK 500 khi xoa Level); +label VN type-10 (F-7); +ep false 2 co early-finalize server-side cho type-10 (F-8 — containment tang BE, FE da ep o levelFlagsPayload)
- fe-admin Designer: deep-link type-10 + an 2 checkbox early-finalize (anh phan "PHA VO" S155) — containment 2 lop render+payload
- tests: +4 (566 total, 0 fail) — schema-invariant 7 bang + codegen format (fault-inject 2 chieu chung co rang)

Reviewer: PASS_WITH_FLAGS 10 issue -> 8 fixed cung commit, 2 giu trang thai (F-1 acceptance đo-CO cho prod; F-4 ke thua y PE prod)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-07-29 20:04:39 +07:00
parent 909134c922
commit a8027c04fe
30 changed files with 8987 additions and 22 deletions

View File

@ -0,0 +1,52 @@
using System.Data;
using Microsoft.EntityFrameworkCore;
using SolutionErp.Application.Common.Interfaces;
using SolutionErp.Application.ContractSigningPlans.Services;
using SolutionErp.Domain.Office;
namespace SolutionErp.Infrastructure.Services;
// [W1 Mig 69 — S161 2026-07-29] Mã phiếu KHKK — format KHKK/{YYYY}/{Seq:D3} (anh OK @S161).
// Mirror PurchaseEvaluationCodeGenerator (SERIALIZABLE + LastSeq += 1), khác 1 điểm:
// sequence sống trong bảng WorkflowAppCodeSequences DÙNG CHUNG 4 module Office
// (per-prefix row "KHKK/{YYYY}" — KHÔNG bảng sequence riêng, spec W1 §②-9).
public class ContractSigningPlanCodeGenerator(IApplicationDbContext db, IDateTime dateTime)
: IContractSigningPlanCodeGenerator
{
public async Task<string> GenerateAsync(CancellationToken ct = default)
{
var year = dateTime.UtcNow.Year;
var prefix = $"KHKK/{year}";
// Transaction SERIALIZABLE chống race 2 người Submit cùng lúc (mirror PE codegen).
var context = (DbContext)db;
await using var tx = await context.Database
.BeginTransactionAsync(IsolationLevel.Serializable, ct);
try
{
var seq = await db.WorkflowAppCodeSequences
.FirstOrDefaultAsync(s => s.Prefix == prefix, ct);
if (seq is null)
{
seq = new WorkflowAppCodeSequence
{
Prefix = prefix, LastSeq = 1, UpdatedAt = dateTime.UtcNow,
};
db.WorkflowAppCodeSequences.Add(seq);
}
else
{
seq.LastSeq += 1;
seq.UpdatedAt = dateTime.UtcNow;
}
await db.SaveChangesAsync(ct);
await tx.CommitAsync(ct);
return $"{prefix}/{seq.LastSeq:D3}";
}
catch
{
await tx.RollbackAsync(ct);
throw;
}
}
}