[CLAUDE] Backout: Chunk D — K5 cleanup F2 zombie endpoint + UsersPage column + DTO field
Reviewer K2 Major #1: PATCH /api/users/{id}/allow-skip-final endpoint Admin tick = NoOp swallow silent (K1 sentinel → confusion UX). Full backout Plan D S22 stack: BE drop (7 files): - UsersController.cs: DELETE PATCH /allow-skip-final endpoint + SetAllowDrafterSkipToFinalBody record - UserFeatures.cs: DELETE SetUserAllowDrafterSkipToFinalCommand + Handler + UserDto.AllowDrafterSkipToFinal field + list/get DTO mapping sentinel-false references - ApprovalWorkflow.cs: REWRITE stale narrative line 78-80 (Reviewer Major #2 Mig 31 semantic) + docstring AllowApproverSkipToFinal line 108 clean stale Users storage ref - PurchaseEvaluationFeatures.cs: REWRITE Command DTO comment line 401 (Reviewer Minor #3) - ApprovalWorkflowConfiguration.cs: APPEND Mig 31 narrative line 22-24 (Reviewer Minor #4) + clean storage move comment line 87 - ApprovalWorkflowV2AdminFeatures.cs: clean DTO comment line 58 stale "F2 xuống User table" - IPurchaseEvaluationWorkflowService.cs + PurchaseEvaluationDtos.cs: clean stale "storage Users.AllowDrafterSkipToFinal" comments FE Admin drop (2 files): - UsersPage.tsx: DELETE "Skip cuối" column + FastForward badge + FastForward import + allowSkipMut mutation hook + FastForward toggle button - types/users.ts: DELETE allowDrafterSkipToFinal field fe-user KHÔNG đụng (no UsersPage admin-only; K6 sẽ handle Workspace Drafter checkbox). FE Designer page KHÔNG đụng (K3 done; 2 stale comment leftover deferred K6). Plan K refactor F2 storage Users → Levels (Mig 31) complete cumulative cleanup. Pattern reusable: post-refactor full cleanup (BE endpoint + Command + DTO + FE column + types + stale narratives) atomic 1 commit thay vì leak zombie state. Verify: - dotnet build production projects 0 err (2 pre-existing DocxRenderer warn) - npm build fe-admin 0 TS err (no new warning) - Grep AllowDrafterSkipToFinal + allow-skip-final + allowDrafterSkipToFinal zero results across src/Backend (excl Migrations history) + fe-admin/src Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
import { useState, type FormEvent } from 'react'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { Building2, KeyRound, Pencil, Plus, Shield, Unlock, Users, CheckCircle2, XCircle, ShieldCheck, FastForward } from 'lucide-react'
|
||||
import { Building2, KeyRound, Pencil, Plus, Shield, Unlock, Users, CheckCircle2, XCircle, ShieldCheck } from 'lucide-react'
|
||||
import { toast } from 'sonner'
|
||||
import { PageHeader } from '@/components/PageHeader'
|
||||
import { DataTable, Pagination, type Column } from '@/components/DataTable'
|
||||
@ -175,18 +175,9 @@ export function UsersPage() {
|
||||
onError: err => toast.error(getErrorMessage(err)),
|
||||
})
|
||||
|
||||
// F2 per-Drafter (Mig 29): toggle AllowDrafterSkipToFinal. Khi true, Drafter
|
||||
// được tick "Gửi thẳng Cấp cuối" trong PE Workspace để skip Bước/Cấp trung
|
||||
// gian và bay thẳng tới Cấp cuối workflow.
|
||||
const allowSkipMut = useMutation({
|
||||
mutationFn: (u: User) =>
|
||||
api.patch(`/users/${u.id}/allow-skip-final`, { allowDrafterSkipToFinal: !u.allowDrafterSkipToFinal }),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['users'] })
|
||||
toast.success('Đã cập nhật quyền gửi thẳng Cấp cuối')
|
||||
},
|
||||
onError: err => toast.error(getErrorMessage(err)),
|
||||
})
|
||||
// Mig 31 (S23 t1 Plan K Chunk D) — DELETED allowSkipMut. F2 semantic + storage
|
||||
// refactor sang ApprovalWorkflowLevels (per-Approver slot, admin opt-in qua
|
||||
// Workflow Designer page). KHÔNG còn per-Drafter user toggle ở User Management.
|
||||
|
||||
function nextPositionLevel(current: number | null): number | null {
|
||||
// Cycle null → 1 (NV) → 2 (PP) → 3 (TP) → null
|
||||
@ -302,21 +293,6 @@ export function UsersPage() {
|
||||
<span className="text-xs text-slate-400">—</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'allowDrafterSkipToFinal',
|
||||
header: 'Skip cuối',
|
||||
width: 'w-20',
|
||||
align: 'center',
|
||||
render: u =>
|
||||
u.allowDrafterSkipToFinal ? (
|
||||
<span title="Drafter được gửi PE thẳng Cấp cuối workflow (skip Bước/Cấp trung gian)" className="inline-flex items-center gap-1 rounded bg-violet-100 px-1.5 py-0.5 text-[10px] text-violet-700">
|
||||
<FastForward className="h-3 w-3" />
|
||||
skip
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-xs text-slate-400">—</span>
|
||||
),
|
||||
},
|
||||
{ key: 'createdAt', header: 'Ngày tạo', width: 'w-24', render: u => fmtDate(u.createdAt) },
|
||||
{
|
||||
key: 'actions',
|
||||
@ -362,14 +338,6 @@ export function UsersPage() {
|
||||
{u.positionLevel != null ? PositionLevelShort[u.positionLevel] : '—'}
|
||||
</span>
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
onClick={() => allowSkipMut.mutate(u)}
|
||||
title={u.allowDrafterSkipToFinal ? 'Tắt quyền skip — Drafter phải tuần tự qua mọi Bước/Cấp' : 'Bật quyền skip — Drafter được gửi PE thẳng Cấp cuối workflow'}
|
||||
>
|
||||
<FastForward className={`h-3.5 w-3.5 ${u.allowDrafterSkipToFinal ? 'text-violet-600' : 'text-slate-400'}`} />
|
||||
</Button>
|
||||
<Button size="sm" variant="ghost" onClick={() => toggleActiveMut.mutate(u)} title={u.isActive ? 'Vô hiệu hóa' : 'Kích hoạt'}>
|
||||
{u.isActive ? <XCircle className="h-3.5 w-3.5 text-red-500" /> : <CheckCircle2 className="h-3.5 w-3.5 text-emerald-600" />}
|
||||
</Button>
|
||||
|
||||
@ -11,7 +11,6 @@ export type User = {
|
||||
position: string | null
|
||||
canBypassReview: boolean
|
||||
positionLevel: number | null // Mig 18 — 1=NV, 2=PP, 3=TP, null=admin/external
|
||||
allowDrafterSkipToFinal: boolean // Mig 29 — F2: Drafter được gửi thẳng Cấp cuối workflow PE
|
||||
}
|
||||
|
||||
// Cấp chức danh trong phòng (Mig 18) — phục vụ N-stage workflow inner step.
|
||||
|
||||
Reference in New Issue
Block a user