Files
superport_v2/doc/approval_flow_alignment_review.md
JiWoong Sul d76f765814 feat(approvals): Approval Flow v2 프런트엔드 전면 개편
- 환경/라우터 모듈에 approval_flow_v2 토글을 추가하고 FeatureFlags 초기화를 연결 (.env*, lib/core/**)
- ApiClient 빌더·ApiRoutes 확장과 ApprovalRepositoryRemote 리팩터링으로 include·액션 시그니처를 정합화
- ApprovalFlow·ApprovalDraft 엔티티/레포/유즈케이스를 도입해 서버 초안과 단계 액션(승인·회수·재상신)을 지원
- Approval 컨트롤러·히스토리·템플릿 페이지와 공유 위젯을 재작성해 감사 로그·회수 UX·템플릿 CRUD를 반영
- Inbound/Outbound/Rental 컨트롤러·페이지에 결재 섹션을 삽입하고 대시보드 pending 카드 요약을 갱신
- SuperportDialog·FormField 등 공통 위젯을 보강하고 승인 위젯 가이드를 추가해 UI 가이드를 정리
- 결재/재고 테스트 픽스처와 단위·위젯·통합 테스트를 확장하고 flutter_test_config로 스테이징 호스트를 허용
- Approval Flow 레포트/플랜 문서를 업데이트하고 ApprovalFlow_System_Integration_and_ChangePlan.md를 추가
- 실행: flutter analyze, flutter test
2025-10-31 01:05:39 +09:00

9.2 KiB

Approval Flow 정합성 점검

개요

  • 점검 일시: 2025-10-31 (KST)
  • 대상 저장소: superport_v2(프런트엔드), superport_api_v2(백엔드)
  • 범위: Approval Flow v2 도입 이후 프런트·백엔드 계약 준수 여부

발견 사항 (2025-10-30)

1. 결재 상세 조회에 전표 동기화 정보 누락

  • 프런트의 결재 상세 API 호출이 include=transaction을 전달하지 않아 전표 updated_at 정보를 수신하지 못한다 (lib/features/approvals/data/repositories/approval_repository_remote.dart:68-81, lib/features/approvals/presentation/controllers/approval_controller.dart:344-348, lib/features/approvals/history/presentation/controllers/approval_history_controller.dart:200-235).
  • 회수·재상신 UI는 transactionUpdatedAt 값을 필수로 확인하며 없을 경우 즉시 토스트를 띄우고 작업을 중단한다 (lib/features/approvals/history/presentation/pages/approval_history_page.dart:1153-1238).
  • 백엔드는 회수/재상신 시 결재와 전표의 최종 수정 시각이 모두 일치해야 한다고 검증한다 (backend/src/app/services/approvals.rs:760-784) ; transaction_expected_updated_at이 빠지면 TRANSACTION_VERSION_MISMATCH가 발생한다.
  • 영향: 사용자는 실제로 최신 데이터를 보고 있어도 전표 타임스탬프를 확보할 방법이 없어 회수·재상신을 실행할 수 없다.
  • 권장 조치:
    • 상세 조회 기본 include에 transaction(및 필요 시 requested_by)을 추가하도록 ApprovalRepositoryRemote.fetchDetail을 수정하고, 동일 로직을 사용하는 컨트롤러들이 별도 옵션 없이 최신 값을 받도록 한다.
    • 회수/재상신 전 UI가 자동으로 재조회하면서 실패 시 재시도 안내를 제공하도록 낙관적 잠금 UX를 보완한다.

작업 항목

  • 프런트엔드
    • ApprovalRepositoryRemote.fetchDetail에서 includeParts 기본값에 transaction을 추가하고, 필요 시 requested_by까지 묶어서 전달한다 (lib/features/approvals/data/repositories/approval_repository_remote.dart).
    • ApprovalController.selectApprovalApprovalHistoryController.loadApprovalFlow가 옵션 없이 전표 정보를 수신하도록 fetch 호출부를 점검하고, ApprovalFlow.transactionUpdatedAt 캐시 로직을 재검증한다.
    • 회수/재상신 트리거 시 refreshFlow 재조회가 실패하면 재시도 문구를 안내하도록 토스트 메시지를 보완하고, 낙관적 잠금 시나리오 위젯 테스트를 추가한다 (lib/features/approvals/history/presentation/pages/approval_history_page.dart).
  • 백엔드
    • ApprovalDetailResponse 직렬화에 transaction.updated_at이 항상 포함되는지 통합 테스트로 보증하고(backend/tests/api/approvals_flow.rs), 누락 시 ApprovalRepository::find_by_id 결과 매핑을 점검한다.

2. 결재 목록 “전체 상태” 조회에서 include_pending 누락

  • 프런트 목록 API 호출은 상태 필터가 all일 때도 include_pending=true를 전달하지 않고 있다 (lib/features/approvals/data/repositories/approval_repository_remote.dart:36-53).
  • 스펙과 도메인 모델은 기본값이 승인·완료 상태만 반환하도록 정의하며, 대기/진행 중 건을 포함하려면 include_pending=true 또는 status=draft,submitted,in_progress를 명시해야 한다 (stock_approval_system_api_v4.md:1231-1236, backend/src/domain/approvals/models.rs:146-189).
  • 영향: 백엔드가 스펙대로 기본 필터를 적용하면 UI의 “전체 상태” 목록이 승인·완료 건만 노출되어 사용자 기대와 불일치가 발생한다.
  • 권장 조치:
    • 컨트롤러에서 상태 필터가 all일 때 include_pending=true를 전달하도록 쿼리 파라미터를 확장하고, 필요 시 status 문자열 필터로 명시적인 다중 상태 조회를 지원한다.
    • 목록 헤더/필터 라벨이 실제 반환 범위와 일치하도록 UX 문구도 함께 재검토한다.

작업 항목

  • 프런트엔드
    • ApprovalRepositoryRemote.list 호출 시 ApprovalStatusFilter.all이면 include_pending=true를 쿼리에 추가하고, 필터에 따라 status 문자열을 조립하도록 로직을 갱신한다.
    • ApprovalController 필터 상태(_statusIdFor, _statusCodeFor)가 새 쿼리 파라미터에 맞춰 동작하도록 단위 테스트를 추가하고, 목록/필터 위젯 테스트를 보완한다.
    • “전체 상태” UI 라벨과 도움말이 실제 반환 범위를 설명하도록 변경한다 (lib/features/approvals/presentation/pages 관련 위젯).
  • 백엔드
    • GET /approvals에서 include_pending 동작이 스펙과 일치하는지 e2e 테스트를 추가하고, 요청 파라미터가 누락될 경우 기본 필터가 승인·완료로 제한됨을 문서(stock_approval_system_api_v4.md)에 재확인한다. (저장소 상태 필터 적용 및 정규화 테스트 보강)

발견 사항 (2025-10-31)

3. 결재 목록 조회 시 상신자·전표 요약 누락

  • 프런트 목록 API는 기본 include에 steps/histories만 추가하고 있어 requester·transaction 정보를 요청하지 않는다 (lib/features/approvals/data/repositories/approval_repository_remote.dart:27-57). 이에 따라 DTO가 비어 있는 맵을 파싱하면서 상신자 ID가 0, 이름이 -로 대체되고 전표 번호도 누락된다 (lib/features/approvals/data/dtos/approval_dto.dart:85-143, lib/features/approvals/data/dtos/approval_dto.dart:195-204).
  • 백엔드는 include.requested_by / include.transaction 플래그가 켜졌을 때만 해당 요약을 조인하므로, 목록 응답에 최소 정보조차 제공되지 않는다 (backend/src/adapters/repositories/approvals.rs:162-210).
  • 영향: 결재 목록의 “상신자/전표번호” 열이 항상 -로 표시되고, 선택 항목에서 상신자 ID가 0으로 초기화되어 재상신·필터 유지 등 후속 동작에서 상신자 정보를 잃는다.
  • 권장 조치:
    • 목록 조회 기본 include에 requested_by, transaction을 추가해 UI가 필요한 요약 데이터를 항상 수신하도록 한다.
    • DTO 파싱 시에도 최악의 경우를 대비해 requested_by_id 등 기본 필드로 최소한의 ID 정보를 보존한다.

작업 항목

  • 프런트엔드
    • ApprovalRepositoryRemote.list 기본 include에 requested_by, transaction을 더하고 관련 위젯/단위 테스트를 갱신한다 (lib/features/approvals/data/repositories/approval_repository_remote.dart).
    • ApprovalDto.fromJsonrequester_id 등 단일 필드를 이용해 ID를 보강하도록 로직을 보완한다 (lib/features/approvals/data/dtos/approval_dto.dart).
  • 백엔드
    • (선택) 하위 호환을 위해 include 미지정 시 최소 requester 요약을 포함할지 검토한다 (backend/src/adapters/repositories/approvals.rs).

4. 서버 임시저장(Approval Draft) API 미연동

  • 백엔드는 /api/v1/approval-drafts에서 초안 목록/조회/저장/삭제 기능을 제공하지만 (backend/src/api/v1/approval_drafts.rs:12-99, backend/src/app/services/approvals.rs:1196-1286), 프런트에는 해당 엔드포인트를 호출하는 레포지토리나 use case가 없다.
  • 현재 프런트 컨트롤러는 메모리 내 _submissionDraft만 유지하며 세션이 끊기거나 다른 기기로 이동하면 초안을 복구할 방법이 없다 (lib/features/approvals/presentation/controllers/approval_controller.dart:398-415, lib/features/inventory/inbound/presentation/controllers/inbound_controller.dart:145-151).
  • 영향: 서버 기반 임시저장 기능을 활용하지 못해 다중 기기/장시간 작업 시 초안 복구 요구사항을 충족하지 못한다.
  • 권장 조치:
    • Approval Draft 전용 경로/DTO/레포지토리를 추가하고, 결재 작성 및 인벤토리 폼 컨트롤러가 서버 초안을 저장·복원할 수 있도록 통합한다.
    • 초안 저장/복원 흐름에 대한 위젯·통합 테스트와 문서화를 추가한다.

작업 항목

  • 프런트엔드
    • ApiRoutes/approval-drafts 경로를 추가하고 원격 레포지토리/DTO/유즈케이스를 구현한다 (신규 파일, lib/core/network/api_routes.dart).
    • ApprovalRequestController 및 인벤토리 컨트롤러에 서버 초안 저장·복구 흐름을 연결하고 의존성 주입을 갱신한다 (lib/features/approvals/request/presentation/controllers/approval_request_controller.dart 등).
    • 초안 관련 위젯/통합 테스트를 추가해 회귀를 방지한다 (test/features/approvals/**).
  • 백엔드
    • 초안 엔드포인트 사용 예시를 스펙 문서에 보강하고 프런트 연동용 샘플을 공유한다 (stock_approval_system_api_v4.md, doc/ApprovalFlow_System_Integration_and_ChangePlan.md).

권장 후속 절차

  • 위 항목 개선 후 flutter analyze, flutter test, cargo test를 실행해 회 regressions 여부를 확인한다.
  • 낙관적 잠금 관련 시나리오는 backend/tests/api/approvals_flow.rs 및 대응 위젯 테스트를 추가/보강해 재현 가능성을 확보한다.
  • 작업 완료 시 본 문서를 업데이트하고 관련 QA 체크리스트에 반영 상황을 기록한다.