# 프런트엔드/백엔드 정합성 점검 리포트 (2025-10-23)

## 개요
- 기준 문서: 갱신된 `backend_change_requests.md`(B8-2 완료)와 `stock_approval_system_api_v4.md`(Approval Flow v2 전면 개편 반영)를 토대로 Flutter 프런트(`superport_v2`)와 Rust 백엔드(`superport_api_v2`)의 계약을 재검증했다.
- 로그인 → 대시보드 → 재고/결재 → 보고서/권한까지 전 흐름을 재검증하고, 기본 목록 비노출 정책(B5-5) 적용 여부를 코드·테스트로 확인했다.

## 주요 정합성 결과
| 구분 | 내용 | 상태 | 후속 조치 |
| --- | --- | --- | --- |
| 1 | Approval Flow v2 API 문서 (`expected_updated_at`, drafts, 이력·지표) | ✅ 해결 | `tool/sync_stock_docs.sh`로 프런트 문서/DTO 재생성 |
| 2 | 결재/재고 응답 스키마(상태·메타데이터·중첩 객체) | ✅ 해결 | 프런트 DTO/위젯에 새 필드 반영 및 테스트 추가 |
| 3 | 전표 기본 목록 비노출 정책(B5-5) | ✅ 해결 | 기본 목록=승인·완료, 대기 영역은 `status=draft,submitted` 또는 `include_pending`으로 조회 |
| 4 | 보고서 Export(PDF/XLSX) 스트리밍·메타데이터 | ✅ 해결 | 감사 로그 확인 및 다운로드 UI 메타 필드 적용 |
| 5 | 그룹-메뉴 권한 `route_path`·`is_deleted`·`include_deleted` | ✅ 해결 | 편집 화면에 삭제 항목/경로 노출 및 회귀 테스트 |
| 6 | Prometheus 지표(`approval_flow_action_*`) 및 감사 로그 | ✅ 해결 | Ops 대시보드/알림 구성안 수립 |
| 7 | 재고 현황 API (`/inventory/summary`) 계약 및 RBAC | 🟡 진행중 | 백엔드 구현 완료 → 프런트 DTO/화면/권한 플로우 동기화 (`doc/inventory_management_feature_plan.md`) |

아래 섹션에서 영역별 관찰 내용과 프런트엔드 후속 작업을 정리했다.

## 로그인 & 세션
- `backend/src/api/v1/auth.rs`가 `data.access_token`, `data.refresh_token`, `data.expires_at`, `data.user`, `data.permissions`를 반환하며 오류 메시지는 문서 규격과 일치한다.
- 프런트 `AuthSessionDto` 매핑은 유지되지만, 알림 메시지가 영어 키(`invalid credentials`, `token expired` 등)에 맞춰 노출되는지 QA에서 다시 확인한다.
- 세션 만료 재로그인 UX는 기존대로 유지하되, 만료/재사용 토큰 구분 안내를 사용자에게 명확히 보여주는지 체크한다.

## 대시보드
- `GET /api/v1/dashboard/summary`가 `kpis[]`, `recent_transactions[]`, `pending_approvals[]`를 제공하고 `delta`·`trend_label`이 문서와 코드에 맞춰 채워진다(`backend/src/api/v1/dashboard.rs`).
- KPI 카드 구성이 입고/출고/대여/결재 대기로 확정되면서 백엔드는 `kpi.key=rental` 값을 추가했고 프런트는 이를 상단 카드 프리셋에 반영했다.
- 프런트 KPI 카드에서 `delta`가 소수(0.125) → 백분율(12.5%)로 변환되는 로직과 `step_summary` 포맷(`"2단계 · 승인자"`)이 정상 노출되는지 UI 스냅샷 테스트를 업데이트한다.

## 재고·대여 트랜잭션
- 응답 본문이 거래/창고/라인/고객/결재 요약을 중첩 객체로 반환하고 `quantity`·`unit_price`의 null도 유지한다(`backend/src/api/v1/stock_transactions.rs`).
- 결재 전이 API가 `expected_updated_at`, `transaction_expected_updated_at`을 요구하며 최신 `data.transaction`/`data.approval`을 반환한다. 프런트는 낙관적 잠금 실패 시 메시지를 문서에 맞춰 노출해야 한다.
- 기본 목록은 승인·완료 상태만 반환하고, 초안·상신 전표는 `status=draft,submitted` 또는 `include_pending=true`로 별도 조회한다. (`backend/src/domain/stock_transactions.rs:74`, `backend/src/adapters/repositories/stock_transactions.rs:45`)

## 재고 현황 API
- 백엔드가 `inventory_balance_events_view`/`inventory_balance_snapshots` 마테뷰와 `/api/v1/inventory/summary` 목록/단건 API를 구현했다. 응답 스키마는 `stock_approval_system_api_v4.md` §4.8~4.9 및 `doc/API_CLIENT_SPEC.md`(백엔드, 프런트 모두)에 정리되어 있다.
- 응답 필드: 목록/단건 모두 `product_id`, `product_code`, `product_name`, `vendor_name`, `total_quantity`, `warehouse_balances[] { warehouse_id, warehouse_code, warehouse_name, quantity }`, `recent_event_*`(kind, delta, counterparty, warehouse_id/name, transaction_id/no, event_at), `updated_at`, `refreshed_at`을 반환한다. UI는 리스트에서 총계·주요 창고·최근 변동 요약을, 상세에서 전체 `warehouse_balances`와 최근 이벤트 타임라인을 노출해야 한다. (출처: `stock_approval_system_spec_v4.md` §§3.24~3.25)
- 데이터 해석: `inventory_balance_events_view`는 5분 주기로 리프레시되는 마테뷰이며 `delta_quantity`는 입고/반납=양수·출고/대여=음수 규칙을 따른다. `event_kind`(receipt, issue, rental_out, rental_return 등)는 뱃지/아이콘으로 구분하고, `counterparty_name`/`recent_event_warehouse_name`은 현지화된 라벨 텍스트와 함께 표기해야 한다.
- 권한: 메뉴 권한(`menu_code=inventory`) + 스코프 `inventory.view`. 프런트 라우트 가드/사이드 메뉴 노출은 `permissions` 배열의 `scope:inventory.view` 보유 여부를 기준으로 삼는다.
- 캐시/리프레시: 서버 2초 TTL 캐시 + 마테뷰 리프레시 스크립트(`script/refresh_inventory_mv.sh`). UI에서 `last_refreshed_at`을 노출해 사용자에게 데이터 신선도를 알려야 한다.
- 감사 로그: `inventory.summary.viewed` 이벤트가 `{ actor_id, filters, result_count, request_id }`를 포함한다. 프런트는 필터/정렬 상태를 명시적으로 노출해 감사 이유를 이해할 수 있도록 UX를 준비한다.

## 결재 단계 & 행위
- `GET /api/v1/approval-steps`가 `approver_id`, `approval_id`, `status_id`, `q` 필터와 `include=approval,approver,status` 확장을 지원한다. 프런트 컨트롤러가 새 파라미터를 모두 전달하는지 점검한다.
- `/approval/**` 행위가 `expected_updated_at`을 요구하고 `data.approval`을 반환하며, Prometheus 지표(`approval_flow_action_total`, `approval_flow_action_duration_seconds`)가 발행된다.
- 열람 권한 정책이 상신자·기결재자에게만 상세 접근을 허용하므로, 프런트 `MyApprovals`·`ApprovalDetailPage`에서 403 시나리오 UX를 재확인한다.

## 결재 플로우 문서 & 모니터링
- `stock_approval_system_api_v4.md`가 `/approval`, `/approval-drafts`, 회수/재상신, 이력, 권한 정책, 예상 업데이트 시각(`expected_updated_at`)을 모두 포함한다.
- Prometheus 지표/Slack 알림 정책은 `doc/approval_flow_alert_policy.md`에 정리돼 있으니 Ops와 함께 대시보드 구성을 착수한다.
- 프런트 문서 동기화(`tool/sync_stock_docs.sh`)와 DTO 리프레시 후 회귀 테스트(`flutter analyze`, `flutter test`) 일정을 맞춘다.

## 보고서 (PDF/XLSX)
- `GET /api/v1/reports/transactions|approvals/export`가 스트리밍과 메타데이터 모드를 모두 지원하고, `download_url`, `filename`, `mime_type`, `expires_at`을 반환한다.
- 프런트 다운로드 UI는 새 메타 필드를 표시하고, 감사 로그(Download 요청 시 이벤트 남는지) 결과를 스테이징에서 확인한 뒤 UX 안내문구를 보강한다.
- 대용량 PDF/XLSX에 대한 합동 테스트를 QA 시나리오에 추가한다.

## 권한/문서
- `GET /api/v1/group-menu-permissions`가 `include_deleted`를 허용하고 `route_path`, `path`, `is_deleted`를 응답에 포함한다. 프런트 DTO와 편집 화면이 삭제 항목을 구분 표시하는지 확인한다.
- 백엔드/프런트 문서가 모두 최신 스펙을 참조하도록, `backend_change_requests.md`와 프런트 대응 문서를 동시에 업데이트한 후 공유한다.

## 일정 & 의존성
| 구분 | 작업 내용 | 담당 | 상태 | 목표일(제안) | 비고 |
| --- | --- | --- | --- | --- | --- |
| 결재 | 전표 기본 목록 비노출 정책 구현(B5-5) | 백엔드 | ✅ 완료 | 2025-10-24 | 기본 필터/테스트 반영 완료, 대기 목록은 상태 필터로 조회 |
| 결재 | 목록 비노출 UI/필터 적용 및 QA 시나리오 | 프런트 | 🗓️ 예정 | 2025-10-25 | 백엔드 배포 직후 테스트 연동 |
| 문서 | `tool/sync_stock_docs.sh` 실행 및 DTO 재생성 | 프런트 | 🗓️ 예정 | 2025-10-23 | 문서/코드 차이 검출 후 PR 공유 |
| QA | Approval Flow 통합 테스트 재실행 (`cargo test`) | 백엔드 | 🗓️ 예정 | 2025-10-24 | 보고서/결재 전이 회귀 포함 |
| QA | `flutter analyze`, `flutter test --coverage` | 프런트 | 🗓️ 예정 | 2025-10-26 | 새 DTO·UI 반영 후 보고 |
| Ops | Prometheus 지표 대시보드 구성 | 백엔드/Ops | 🗓️ 예정 | 2025-10-28 | `approval_flow_action_*` 메트릭 시각화 |

## 테스트 & 다음 단계
- 백엔드는 기본 필터 동작 검증 후 `cargo fmt`, `cargo check`, `cargo test` 결과를 공유한다.
- 프런트는 문서/DTO 동기화 이후 Approval Flow UI·보고서 다운로드·권한 편집 시나리오를 회귀 테스트로 보강한다.
- 양측 모두 QA 완료 시 `notify.py` 워크플로로 완료 알림을 발송하고, 남은 일정(B8-4, B8-5, B9-x)을 공유 캘린더에 업데이트한다.
