[CLAUDE] App+Infra+Api+FE-User+FE-Admin+Tests: W3 KHKK — duyet 3 tram OR-of-N + finalize chot gia (test-before 6 RED->GREEN)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m54s

- ContractSigningPlanWorkflowService: copy khuon ApproveV2Async (con-tro doi StepIndex+LevelOrder, GroupBy Order, OR-of-N, LevelOpinions UPSERT "(duyet — khong y kien)") — CAM Proposal-flatten; KHONG port 2 duong ket-thuc-som (owner phan PHA VO S155)
- Choke-point finalize ApplyApprovedValuesOnFinalize (Line.ApprovedAmount ??= Proposed) 1-SITE-BY-DESIGN: hop-dong transitions khong co targetPhase => admin cung xuyen choke-point (triet lop #81 tu goc); RULE-comment khuon :356-360
- Transitions endpoint: submit/approve/return/reject (hop-dong LEAD-dinh-nghia literal — reviewer Truc-4 KHOP 5/5, truc W2 tung dut 6 diem); guard trinh CreatedBy|Drafter|DeptManager-cung-phong|Admin; changelog/approvals bang KHKK rieng (CAM IChangelogService — FK-547 rao bang vang-mat-dep); notify Cap-ke dich danh + exclusion actor/drafter (S86)
- Save-diem: 1 SaveChanges cuoi = 1 transition 1 unit-of-work (service la diem vao, khac nguon :537)
- FE KhkkWorkflowPanel x2 app SHA-pair: so-do Buoc/Cap + banner den-luot + Gui/Duyet/Tra/Tu-choi + y kien; panel GATE nut theo actor (khong de an 403)
- Test-before: 6 test san PIN RED-evidence 6/6 (5 NotImplemented + 1 assert) -> GREEN 6/6; sua-test dung 1 seed FAULT-INJECT sot (0 assert doi); suite 574 -> 580/0
- Reviewer 7/7 truc DAT 0 chan (4 truc vai + 3 truc lead on-behalf; Q1-Q6 duyet)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-07-29 22:33:11 +07:00
parent d7bdb45312
commit df52fa0cd0
11 changed files with 2370 additions and 6 deletions

View File

@ -6,7 +6,8 @@
// per-NCC trúng thầu (READ-ONLY ở W2 — `PeReferenceAmount` là SNAPSHOT lúc lập kế
// hoạch) · (3) Căn cứ hồ sơ b.8-9 (CRUD chỉ mở ở DangSoanThao|TraLai) · (4) File
// đính kèm (mở MỌI phase — triết lý PE S147).
// 🔴 CỐ Ý KHÔNG có panel trình/duyệt + banner cấp duyệt: transitions = W3.
// [W3 S161] +panel duyệt `KhkkWorkflowPanel` NGAY DƯỚI header (trên "Thông tin kế hoạch"):
// sơ đồ Bước→Cấp + banner đến-lượt + Gửi duyệt / Duyệt / Trả lại / Từ chối.
import { useState, type ReactNode } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useNavigate, useParams } from 'react-router-dom'
@ -31,6 +32,7 @@ import {
type KhkkDetailDto, type KhkkDossierItemDto, type KhkkPhaseValue,
type UpsertKhkkDossierItemInput,
} from '@/types/khkk'
import { KhkkWorkflowPanel } from './KhkkWorkflowPanel'
function formatVnd(n: number | null): string {
if (n === null || n === undefined) return '—'
@ -316,6 +318,11 @@ export function KhkkDetailPage() {
}
/>
{/* [W3 S161] Panel duyệt — đặt NGAY dưới header để người duyệt thấy việc-phải-làm
trước nội dung phiếu (mirror thứ tự PE: workflow panel là thứ đầu tiên trong
màn Duyệt). `onChanged` dùng `invalidate` của trang để refetch theo id URL. */}
<KhkkWorkflowPanel plan={k} onChanged={invalidate} />
{/* Section 1: Thông tin */}
<SectionCard
title="Thông tin kế hoạch"