{}}
+ />,
+ );
+ const notes = screen.getAllByTestId('decision-note');
+ expect(notes.some((note) => note.textContent.includes('체인'))).toBe(true);
+ const rootNote = notes.find((note) => note.textContent.includes('분류'));
+ expect(rootNote.textContent.includes('체인')).toBe(false);
+});
diff --git a/workflow/src/components/DecisionSheet.jsx b/workflow/src/components/DecisionSheet.jsx
index 8971367..1427ed4 100644
--- a/workflow/src/components/DecisionSheet.jsx
+++ b/workflow/src/components/DecisionSheet.jsx
@@ -9,7 +9,7 @@ const SECONDARY_ACTIONS = [
];
// 결정 시트: 상세 표시 + 승인/반려. 반려는 사유 칩 + 자유 입력 (본체 터치 반려 시트 패턴 계승).
-export default function DecisionSheet({ request, onDecide, onClose }) {
+export default function DecisionSheet({ request, onDecide, onClose, chain = null }) {
const [rejecting, setRejecting] = useState(false);
const [reason, setReason] = useState('');
const highlight = formatPresetHighlight(request.subjectType, request.subject.payload);
@@ -42,7 +42,19 @@ export default function DecisionSheet({ request, onDecide, onClose }) {
{JSON.stringify(request.subject.payload, null, 2)}
요청자: {request.actorId}
- {request.parentRequestId ? (
+ {chain && chain.length > 1 ? (
+
+ {chain.map((item) => {
+ const isCurrent = item.requestId === request.requestId;
+ return (
+ -
+ {item.subjectType} · {item.subject?.title} · {item.status === 'pending_decision' ? '대기' : '결정됨'}
+ {isCurrent ? ' ← 현재' : ''}
+
+ );
+ })}
+
+ ) : request.parentRequestId ? (
체인 이전 요청: {request.parentRequestId}
) : null}
diff --git a/workflow/src/components/DecisionSheet.test.jsx b/workflow/src/components/DecisionSheet.test.jsx
index 6a0eb92..a10c1f2 100644
--- a/workflow/src/components/DecisionSheet.test.jsx
+++ b/workflow/src/components/DecisionSheet.test.jsx
@@ -52,6 +52,31 @@ describe('DecisionSheet', () => {
expect(onDecide).toHaveBeenCalledWith('revise', '');
});
+ it('chain prop이 있으면 타임라인을 렌더하고 현재 요청을 강조한다', () => {
+ render(
+ {}}
+ onClose={() => {}}
+ />,
+ );
+ const timeline = screen.getByLabelText('결정 체인');
+ expect(timeline.textContent).toContain('메일 분류');
+ expect(timeline.textContent).toContain('결정됨');
+ expect(timeline.textContent).toContain('대기');
+ expect(timeline.textContent).toContain('← 현재');
+ });
+
it('parentRequestId가 있으면 체인 이전 요청을 표시한다', () => {
render(