feat(approvals): 결재 접근 차단 대응과 전표 전이 메모 전달 강화

- approvals 모듈에서 APPROVAL_ACCESS_DENIED 응답을 포착하여 ApprovalAccessDeniedException으로 변환하고 접근 거부 시 토스트·대시보드 리다이렉트를 처리

- approval history 조회가 서버 action id에 맞춰 필터링되도록 repository·controller·테스트를 보강

- 재고 트랜잭션 상태 전이 API 호출에 note를 전달하도록 repository·컨트롤러·통합/단위 테스트를 업데이트

- 승인 플로우 QA 체크리스트 및 연동 문서를 최신 계약과 테스트 흐름으로 업데이트
This commit is contained in:
JiWoong Sul
2025-10-31 16:43:14 +09:00
parent d76f765814
commit 3e83408aa7
35 changed files with 1056 additions and 470 deletions

View File

@@ -1542,7 +1542,7 @@
- `POST /approvals/5001/restore`
### 5.9 결재 이력 조회
`GET /approval-histories?approval_id=5001&include=approval,step,approver`
`GET /approval-histories?approval_id=5001`
```json
{
"items": [
@@ -1607,6 +1607,8 @@
}
```
기본 응답에는 `approval`, `step`, `approval_action`, `approver`, `from_status`, `to_status` 서브 오브젝트가 포함되며, 추가 정보가 필요하지 않은 경우 `include` 파라미터를 생략해도 동일한 페이로드를 수신한다. `approval_action_id` 필터는 정수 ID 기준으로 동작하므로, 클라이언트는 사전에 제공된 행위 메타데이터로 코드 → ID 매핑을 수행한 뒤 요청해야 한다.
### 5.10 단계 개별 CRUD
- `GET /approval-steps?approval_id=5001&include=approval,approver,status``{ items: [], page, page_size, total }` 형태로 반환하며, 각 항목은 `approval`, `approver`, `status` 서브 오브젝트를 선택적으로 포함한다.
- `GET /approval-steps/7001?include=approval,approver,status``{ data: { ... } }`.
@@ -1618,10 +1620,11 @@
주요 필터 및 확장 파라미터:
- `approval_id`, `approval_step_id`, `approver_id`, `approval_action_id`(정수 ID), `status_id`
- `q`(결재번호·승인자 검색), `action_from`, `action_to` (ISO8601 UTC)
- `action_from`, `action_to` (ISO8601 UTC). 문자열 검색 파라미터 `q`는 2025-11-01 기준 제공되지 않으며, 도입 시 본 문서를 갱신한다.
- `sort=action_at|created_at|updated_at`, `order=asc|desc`
- `include` 기본값은 `approver,approval_action,from_status,to_status`; `approval`, `step`, `status` 토큰으로 확장
- `include` 기본값은 `approval,step,approval_action,approver,from_status,to_status`이며, `status` 토큰으로 응답을 확장할 수 있다.
- 응답은 `action` 오브젝트에 `name`/`code`를, 루트 레벨에 `action_code`를 포함하여 감사 행위 식별자를 일관되게 노출한다.
- 프런트엔드는 `approval_action_id` 정수 필터를 사용해야 하며, `approval_action.code`만으로는 필터링이 되지 않는다.
`GET /approval-histories/91001?include=approval,step`
```json
@@ -1680,6 +1683,78 @@
}
```
### 5.11 결재 초안 API (`/approval-drafts`)
- 상신자가 작성 중이던 결재 구성을 서버에 저장하고, 다른 세션에서 복구할 수 있도록 지원한다.
- 초안은 `requester_id`(상신자) 기준으로 구분되며 기본 목록은 유효(`status=active`) 초안만 반환한다. 만료된 초안을 함께 조회하려면 `include_expired=true`를 전달한다.
`GET /approval-drafts?requester_id=7`
```json
{
"items": [
{
"id": 88001,
"request_id": null,
"transaction_id": 91005,
"requester_id": 7,
"template_id": 1201,
"title": "입고 결재 초안",
"summary": "서류 미완료",
"status": "active",
"saved_at": "2025-01-04T05:10:00Z",
"expires_at": "2025-01-06T05:10:00Z",
"session_key": "draft-session-123",
"step_count": 2
}
],
"page": 1,
"page_size": 50,
"total": 1
}
```
`POST /approval-drafts`
```json
{
"requester_id": 7,
"transaction_id": 91005,
"template_id": 1201,
"title": "입고 결재 초안",
"summary": "서류 미완료",
"note": "재고 파악 필요",
"session_key": "draft-session-123",
"steps": [
{ "step_order": 1, "approver_id": 21, "is_optional": false },
{ "step_order": 2, "approver_id": 34, "is_optional": false }
]
}
```
`POST /approval-drafts/88001/restore`
```json
{
"data": {
"id": 88001,
"requester_id": 7,
"transaction_id": 91005,
"template_id": 1201,
"payload": {
"title": "입고 결재 초안",
"summary": "서류 미완료",
"note": "재고 파악 필요",
"status": "draft",
"steps": [
{ "step_order": 1, "approver_id": 21, "is_optional": false },
{ "step_order": 2, "approver_id": 34, "is_optional": false, "note": "재무 확인" }
]
},
"saved_at": "2025-01-04T05:10:00Z",
"expires_at": "2025-01-06T05:10:00Z",
"session_key": "draft-session-123"
}
}
```
- 초안 삭제는 `DELETE /approval-drafts/{id}?requester_id=<상신자 ID>`를 호출하며 `204 No Content`가 응답된다.
---
## 6. 결재 템플릿 API