- 환경/라우터 모듈에 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
9.2 KiB
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를 보완한다.
- 상세 조회 기본 include에
작업 항목
- 프런트엔드
ApprovalRepositoryRemote.fetchDetail에서includeParts기본값에transaction을 추가하고, 필요 시requested_by까지 묶어서 전달한다 (lib/features/approvals/data/repositories/approval_repository_remote.dart).ApprovalController.selectApproval및ApprovalHistoryController.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 정보를 보존한다.
- 목록 조회 기본 include에
작업 항목
- 프런트엔드
ApprovalRepositoryRemote.list기본 include에requested_by,transaction을 더하고 관련 위젯/단위 테스트를 갱신한다 (lib/features/approvals/data/repositories/approval_repository_remote.dart).ApprovalDto.fromJson이requester_id등 단일 필드를 이용해 ID를 보강하도록 로직을 보완한다 (lib/features/approvals/data/dtos/approval_dto.dart).
- 백엔드
- (선택) 하위 호환을 위해 include 미지정 시 최소
requester요약을 포함할지 검토한다 (backend/src/adapters/repositories/approvals.rs).
- (선택) 하위 호환을 위해 include 미지정 시 최소
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 체크리스트에 반영 상황을 기록한다.