# Superport v2 입·출고 + 결재 시스템 PRD (Draft v1)

본 문서는 `doc/입출고 대여 폼 정리.md`, `doc/stock_approval_system_spec_v4.md`, `doc/stock_approval_system_api_v4.md`를 근거로 Flutter 웹 프론트엔드 구현을 위한 상세 요구사항을 정리한다. 스타일은 `/Users/maximilian.j.sul/Documents/flutter/superport`의 UI/UX 패턴을 준수한다.

## 1. 범위 및 목표
- 범위: 로그인/대시보드/입고/출고/대여/마스터(벤더, 제품, 창고, 고객사, 사용자, 그룹, 메뉴, 권한)/결재(결재, 단계, 이력, 템플릿)/보고서.
- 목표: 백엔드 API와 연동하여 화면/네비게이션/상호작용(폼 검증, 필터, 페이징, 모달)을 완성. DTO/리포지토리 인터페이스를 분리해 유지보수를 용이하게 함.
- 기술: Flutter + shadcn_ui + go_router + two_dimensional_scrollables. 반응형 웹 최적화.
- 제약: 입력·수정 폼은 팝업 모달(ShadDialog 기반)로 노출. 테이블은 ShadTable 계열 사용.

## 2. 전역 UX/스타일 가이드
- 레이아웃(AppLayout): 좌측 사이드바 내비게이션 + 상단 헤더(타이틀, 브레드크럼, 액션) + 콘텐츠.
- 컴포넌트(슈퍼포트 준수):
  - 테이블: `ShadTable.list`(고정 헤더, 필요 시 첫 컬럼 고정, 가로 스크롤 허용).
  - 버튼: `ShadButton.(primary|outline|ghost)`, 행 액션은 `ghost` 아이콘 버튼.
  - 입력: `ShadInput`, `ShadSelect`, `SuperportShadDatePicker/DateRangePicker`, `ShadSwitch`, `ShadBadge`, `ShadTooltip`.
  - 모달: `SuperportShadDialog`(헤더/본문/푸터 구분, ESC/배경 클릭 닫기 옵션).
  - 페이징: 테이블 하단 우측 `page / perPage / total` 표시 + 페이지네이션.
- 필터/검색 바: 테이블 상단. 기본 `검색(q)` + 주요 조건(기간/상태/창고 등). `Reset` 버튼 제공.
- 정렬: 테이블 헤더 클릭 1열 정렬(추후 멀티 정렬 확장 가능).
- 반응형: 
  - Breakpoints: `>=1280` 데스크톱 3열, `>=1024` 2열, `>=768` 2열(compact), `<768` 1열 카드형 목록 대체 및 모달 전면(full-screen) 전환.
  - 테이블은 작은 화면에서 핵심 컬럼만 우선 노출(열 가시성 프리셋), 나머지는 가로 스크롤.
- 접근성: 포커스 트랩, 키보드 내비게이션(Tab/Enter/Esc), 명확한 에러 메시지.
- 로딩/빈 상태: Skeleton과 Empty 상태 메시지(“조건을 변경해 보세요”). 오류는 Toaster로 노출.

## 3. 권한/메뉴 정책(뷰 관점)
- 그룹 기반 메뉴 권한(`group_menu_permissions`)은 서버 응답을 기반으로 적용: `can_create/read/update/delete`에 따라 버튼/액션 노출 제어.
- 메뉴 트리: 대시보드, 입고, 출고, 대여, 마스터(벤더, 제품, 창고, 고객사, 사용자, 그룹, 메뉴, 권한), 결재(결재, 단계, 이력, 템플릿), 보고서.

## 4. 공통 데이터 소스 매핑(드롭다운/자동입력)
- 공통 룩업: 
  - 단위: `/uoms` → `uom_name` 표시
  - 트랜잭션 유형: `/transaction-types` (입고/출고/대여/반납) — 화면 진입 시 자동 지정 또는 대여구분에 따라 자동 매핑
  - 트랜잭션 상태: `/transaction-statuses`(대기/진행/보류/승인/반려 등)
  - 결재 상태: `/approval-statuses`(blocking/terminal 속성 포함)
  - 결재 행위: `/approval-actions`(approve/reject/comment)
- 마스터: 
  - 창고: `/warehouses`(우편번호/주소 포함)
  - 벤더: `/vendors`
  - 제품: `/products?include=vendor,uom`(제품 선택 시 제조사/단위 자동 세팅, RO)
  - 고객사: `/customers`(유형 플래그: 파트너/일반)
  - 사원: `/employees`
- 공통 자동입력/읽기전용 규칙:
  - `작성자`: 로그인 사용자로 자동 세팅(RO).
  - `트랜잭션번호/결재번호`: 생성 시 자동 발번(RO)·수정 불가.
  - `생성일시/변경일시`: RO.
  - 제품 선택 시 `제조사/단위` 자동 세팅(RO). 수량/단가 변경 시 `합계` 자동 계산(표시용).
  - 고객사 유형(파트너/일반) 선택은 내부적으로 `is_partner`/`is_general` 불린 필드로 매핑하여 저장.

## 5. 화면별 상세 사양

### 5.0 로그인/로그아웃
- 라우트: `/login`
- 목적: 세션 시작/종료(로컬 상태). 성공 시 대시보드로 이동.
- 입력(모달 아님): 아이디[TXT], 비밀번호[PWD].
- 검증: 아이디/비밀번호 필수. 실제 인증 성공 후 사용자/그룹/권한/메뉴를 서버에서 로딩.

### 5.1 대시보드
- 라우트: `/`
- 목적: 당일 입고/출고/대기 결재 위젯, 최근 트랜잭션, 내 결재 대기 요약.
- 위젯:
  - KPI 배지: 오늘 입고/출고 건수, 대기 결재 수.
  - 최근 트랜잭션: 번호, 일자, 유형, 상태, 작성자.
  - 내 결재 대기: 결재번호, 현재 단계, 요청일시.

### 5.2 입고(Stock Inbound)
- 라우트: `/inbounds`
- 역할: 구매/반입 처리. 라인에 제품/수량/단가 입력.
- 테이블 컬럼: 번호(id), 처리일자(processed_at), 창고(warehouse_name), 트랜잭션번호(transaction_no), 상태(status_name), 작성자(employee_name), 품목수(line_count), 총수량(total_qty), 비고(note).
- 기본 정렬: `processed_at desc`.
- 필터: 기간, 창고, 상태, 검색(q: 번호/비고 등).
- 행 액션: 상세(모달), 수정(모달), 삭제(소프트), 복구.
- 신규(모달: “입고 등록”):
  - 헤더 섹션: 처리일자[DT, 필수], 창고[DD, 필수], 상태[DD, 기본=대기], 작성자[자동, RO], 비고[TXT].
  - 시스템 필드: 입출고유형[RO/숨김, `transaction_type_id`=입고] — 라우트 진입 시 고정 설정.
  - 라인 섹션(ShadTable): 
    - 제품[DD/자동완성, 필수] → 선택 시 제조사[RO], 단위[RO] 자동 표시
    - 수량[NUM, >=1, 필수], 단가[NUM, >=0], 비고[TXT]
    - (+)행 추가, (−)행 삭제, 최소 1행 필수
  - 검증: 전역 에러 바인딩(상단), 행 단위 인라인 에러.
- 수정(모달: “입고 수정”):
  - 읽기전용: 작성자, 트랜잭션번호.
  - 상태는 일부 제한(승인/반려 등 종결 상태는 수정 불가).

### 5.3 출고(Stock Outbound)
- 라우트: `/outbounds`
- 역할: 출하/반출 처리. 고객사 연결 필수.
- 테이블 컬럼: 번호, 처리일자, 창고, 트랜잭션번호, 상태, 작성자, 고객수, 품목수, 총수량, 비고.
- 필터: 기간, 창고, 상태, 고객사, 검색.
- 신규/수정 모달:
  - 헤더: 처리일자[DT], 창고[DD], 상태[DD], 작성자[RO], 비고[TXT].
  - 시스템 필드: 입출고유형[RO/숨김, `transaction_type_id`=출고] — 라우트 진입 시 고정 설정.
  - 고객 연결: 고객사[DD-멀티|자동완성, 최소 1건], 비고[TXT].
  - 라인: 제품[DD/자동완성], 제조사[RO], 단위[RO], 수량[NUM], 단가[NUM], 비고.
  - 규칙: 고객 최소 1건 없으면 저장 불가.

### 5.4 대여(Rental)
- 라우트: `/rentals`
- 역할: 대여/반납 트랜잭션 관리.
- 테이블 컬럼: 번호, 처리일자, 창고, 대여/반납(유형), 트랜잭션번호, 상태, 반납예정일, 고객수, 품목수, 비고.
- 필터: 기간, 창고, 상태, 대여구분, 반납예정일 범위, 검색.
- 신규/수정 모달:
  - 헤더: 처리일자[DT], 창고[DD], 상태[DD], 작성자[RO], 대여구분[DD: 대여/반납], 반납예정일[DT], 비고[TXT].
  - 시스템 필드: 입출고유형[RO/숨김, `transaction_type_id`=대여/반납(대여구분에 따라 자동 매핑)].
  - 고객 연결: 고객사[DD-멀티], 비고.
  - 라인: 제품[DD/자동완성], 제조사[RO], 단위[RO], 수량[NUM], 단가[NUM], 비고.
  - 규칙: 대여구분은 진행 중 제약(종결 후 변경 불가), 반납예정일은 수정 가능.

### 5.5 제조사 관리(벤더)
- 라우트: `/masters/vendors`
- 테이블: 번호, 벤더코드, 벤더명, 사용여부, 비고, 변경일시.
- 필터: 검색(q), 사용여부, 삭제 포함(고급) 토글.
- 신규(모달): 벤더코드[TXT, 고유], 벤더명[TXT], 사용여부[SW], 비고[TXT].
- 수정(모달): 벤더코드[RO], 생성/변경일시[RO].

### 5.6 장비 모델 관리(제품)
- 라우트: `/masters/products`
- 테이블: 번호, 제품코드, 제품명, 제조사, 단위, 사용여부, 비고, 변경일시.
- 필터: 검색(q), 제조사, 단위, 사용여부, 삭제 포함(고급) 토글.
- 신규: 제품코드[TXT], 제품명[TXT], 제조사[DD], 단위[DD], 사용여부[SW], 비고.
- 수정: 제품코드[RO], 생성일시[RO].

### 5.7 입고지 관리(창고)
- 라우트: `/masters/warehouses`
- 테이블: 번호, 창고코드, 창고명, 우편번호, 상세주소, 사용여부, 비고, 변경일시.
- 필터: 검색(q), 사용여부, 삭제 포함(고급) 토글.
- 신규/수정: 창고코드[TXT], 창고명[TXT], 우편번호[검색 모달], 상세주소[TXT], 사용여부[SW], 비고. 코드/일시는 RO.
- 우편번호 검색: 전용 모달(입력: 검색어 → 결과 리스트에서 선택 시 필드 채움).

### 5.8 회사 관리(고객사)
- 라우트: `/masters/customers`
- 테이블: 번호, 고객사코드, 고객사명, 유형, 이메일, 연락처, 우편번호, 상세주소, 사용여부, 비고.
- 필터: 검색(q), 유형, 사용여부, 삭제 포함(고급) 토글.
- 신규: 고객사코드[TXT], 고객사명[TXT], 유형(파트너/일반)[DD(복수 선택 가능)], 이메일[TXT], 연락처[TXT], 우편번호[검색], 상세주소[TXT], 사용여부[SW], 비고.
- 수정: 고객사코드/생성일시 RO.

### 5.9 사용자 관리(사원)
- 라우트: `/masters/employees`
- 테이블: 번호, 사번, 성명, 이메일, 연락처, 그룹, 사용여부, 비고, 변경일시.
- 필터: 검색(q), 그룹, 사용여부, 삭제 포함(고급) 토글.
- 신규: 사번[TXT], 성명[TXT], 이메일[TXT], 연락처[TXT], 그룹[DD], 사용여부[SW], 비고.
- 수정: 사번/생성일시 RO.

### 5.10 그룹 관리
- 라우트: `/masters/groups`
- 테이블: 번호, 그룹명, 설명, 기본여부, 사용여부, 비고, 변경일시.
- 필터: 검색(q), 기본여부, 사용여부, 삭제 포함(고급) 토글.
- 신규: 그룹명[TXT], 설명[TXT], 기본여부[SW], 사용여부[SW], 비고.
- 수정: 그룹명/생성일시 RO.

### 5.11 메뉴 관리
- 라우트: `/masters/menus`
- 테이블: 번호, 메뉴코드, 메뉴명, 상위메뉴, 경로, 사용여부, 비고, 변경일시.
- 필터: 검색(q), 상위메뉴, 사용여부, 삭제 포함(고급) 토글.
- 신규: 메뉴코드[TXT], 메뉴명[TXT], 상위메뉴[DD], 경로[TXT], 표시순서[NUM], 사용여부[SW], 비고.
- 수정: 메뉴코드/생성일시 RO.

### 5.12 그룹 메뉴 권한 관리
- 라우트: `/masters/group-permissions`
- 테이블: 번호, 그룹명, 메뉴명, 생성, 조회, 수정, 삭제, 사용여부, 변경일시.
- 필터: 그룹, 메뉴, 사용여부.
- 신규: 그룹[DD], 메뉴[DD], 생성/조회/수정/삭제[CHK], 사용여부[SW].
- 수정: 그룹/메뉴 RO.

### 5.13 결재 관리(Approvals)
- 라우트: `/approvals`
- 테이블: 번호, 결재번호, 트랜잭션번호, 상태, 상신자, 요청일시, 최종결정일시, 비고.
- 신규: 트랜잭션번호[DD], 결재번호[자동], 결재상태[DD(기본=대기)], 상신자[자동], 비고.
- 상세(우측 패널 또는 모달 탭): 
  - 개요: 현재 상태/현재 단계/상신자/요청일시/결정일시
  - 단계 탭: 단계 리스트(step_order, 승인자, 상태, 배정/결정 일시) + [템플릿 불러오기] 버튼 → 템플릿 선택 후 단계 일괄 생성(`POST /approvals/{id}/steps`)
  - 이력 탭: 행위/변경 전/후 상태/일시/비고
- 단계 행위(행 액션): 승인/반려/코멘트(결재 상태 규칙에 따라 전이 가능 여부 표시).

### 5.14 결재 단계 관리(Approval Steps)
- 라우트: `/approval-steps`
- 테이블: 번호, 결재ID, 단계순서, 승인자, 상태, 배정일시, 결정일시, 비고.
- 신규/수정: 결재ID[DD], 단계순서[NUM], 승인자[DD], 단계상태[DD], 비고. (결재ID/단계순서 RO 규칙 준수)

### 5.15 결재 이력 조회(Logs)
- 라우트: `/approval-histories`
- 테이블 전용: 번호, 결재ID, 단계ID, 승인자, 행위, 변경전상태, 변경후상태, 작업일시, 비고.

### 5.16 결재 템플릿 관리
- 라우트: `/approval/templates`
- 테이블: 번호, 템플릿코드, 템플릿명, 설명, 작성자, 사용여부, 변경일시.
- 신규/수정:
  - 헤더: 템플릿코드[TXT], 템플릿명[TXT], 설명[TXT], 작성자[RO], 사용여부[SW], 비고[TXT].
  - 단계 섹션(반복): (+추가) 순서[NUM], 승인자[DD].

### 5.17 우편번호 검색(모달)
- 트리거: 창고/고객사 폼의 우편번호 필드의 “검색”.
- 입력: 검색어[TXT]. 결과 테이블: 우편번호 | 시도 | 시군구 | 도로명 | 건물번호. 선택 시 부모 폼에 채움.

### 5.18 보고서
- 라우트: `/reports`
- 조건: 기간[DT-기간], 유형[DD], 창고[DD], 상태[DD].
- 액션: XLSX/PDF 다운로드(백엔드 제공 엔드포인트 연동, 미제공 시 버튼 비활성 처리).

## 6. 입력/수정 폼 규칙(공통)
- 모달 구조: 헤더(타이틀) / 본문(스크롤) / 푸터(취소, 저장). 모바일에서 풀스크린 모달.
- 검증: 필수값 표기(*), 저장 시 필수/형식/업무 규칙 검사. 에러는 필드 하단 및 상단 요약으로 노출.
- 자동입력: 작성자/번호/일시 RO. 제품 선택 시 제조사/단위 자동 표시. 합계/라인수는 표시만.
- 멀티 선택: 고객사 다건은 토큰/칩 형태로 표시 및 제거 지원.
- 라인 편집: 테이블 내 인라인 편집, 행 추가/삭제. 최소 1행.

## 7. API 연동 청사진(후속 단계)
- 목록: `{ items, page, page_size, total }` 포맷 사용. 쿼리: `page, page_size, q, sort, order, updated_since, include, active, deleted`.
- 단건: `{ data: { ... } }` 포맷. 생성 시 PK 미포함, 응답에 PK 포함. 수정 시 `id` 포함.
- 소프트 삭제/복구: `DELETE /{res}/{id}`, `POST /{res}/{id}/restore`.
- 엔드포인트 매핑 예:
  - 입고/출고/대여: `GET /stock-transactions?include=lines,customers,approval` | `POST /stock-transactions`(헤더+라인+고객 일괄) | `PATCH /stock-transactions/{id}` | `DELETE /stock-transactions/{id}` | `POST /stock-transactions/{id}/restore`
  - 결재: `GET /approvals?include=steps,histories` | `GET /approvals/{id}?include=steps,histories` | `POST /approvals/{id}/steps` | `PATCH /approvals/{id}/steps` | `POST /approval-steps/{id}/actions` | `GET /approvals/{id}/can-proceed`
  - 마스터: `/vendors`, `/products`, `/warehouses`, `/customers`, `/employees`, `/menus`, `/groups`, `/group-permissions`
  - 권한 일괄 갱신: `POST /groups/{id}/permissions` (체크박스 매트릭스 일괄 저장)
  - 룩업: `/uoms`, `/transaction-types`, `/transaction-statuses`, `/approval-statuses`, `/approval-actions`
  - 우편번호: `GET /zipcodes?zipcode=06000&road_name=세종대로` (검색 모달에서 복합 쿼리 지원)

## 8. 와이어프레임(텍스트)
- 공통 리스트 스크린
  - 헤더: [타이틀] [우측: +신규, 기타액션]
  - 필터바: [검색] [기간] [상태] [창고/유형 등] [Reset]
  - 본문: ShadTable.list(컬럼들…) [좌측 체크박스(옵션)] [우측 행 액션]
  - 하단: 페이지네이션(좌: 건수, 우: 페이지 컨트롤)
- 공통 폼 모달
  - 헤더: [타이틀]
  - 본문: [필드 그리드(2~3열)] [라인 테이블(필요 시)] [고객/단계 섹션]
  - 푸터: [취소] [저장(primary)]
- 예시) 출고 리스트
  - 필터바: 검색 | 기간 | 창고 | 상태 | 고객사 | Reset
  - 테이블: 번호 | 처리일자 | 창고 | 트랜잭션번호 | 상태 | 작성자 | 고객수 | 품목수 | 총수량 | 비고 | (행액션)
- 예시) 출고 등록 모달
  - 헤더 필드: 처리일자 | 창고 | 상태 | 작성자(RO) | 비고
  - 고객사(멀티) 섹션: 고객사(+추가/자동완성) | 비고
  - 라인 섹션: 제품(자동완성) | 제조사(RO) | 단위(RO) | 수량 | 단가 | 비고 | (+행)

## 9. 비기능 요구사항
- 성능: 가상 스크롤 또는 배치 렌더링 고려, 페이지 당 기본 20~50행.
- 국제화: 한국어 우선. 날짜/숫자 포맷 `intl` 사용.
- 코드 구조: `lib/features/<domain>/presentation` 중심, 위젯 재사용은 `lib/widgets/`에 공통화. DI는 `lib/injection_container.dart`.
- 정적 분석: `flutter analyze` 경고 0 유지. 포맷팅 `dart format .`.

## 10. 테스트(프론트)
- 위젯 테스트: 
  - 테이블 렌더링(컬럼/행 수), 필터 적용, 페이징 이동, 모달 열기/검증 에러 표시.
  - 위젯 테스트는 네트워크 의존 없는 UI 로직 검증에 한정(실제 API는 통합 테스트에서 검증).
- 통합 테스트(선택): 주요 내비게이션(대시보드 → 입/출/대여 → 결재 → 마스터) 흐름 확인.

---
참고 문서: `doc/입출고 대여 폼 정리.md`, `doc/stock_approval_system_spec_v4.md`, `doc/stock_approval_system_api_v4.md`

## 11. 화면별 필드 매트릭스(유형/검증/자동/소스)

표기 규칙: 유형(TXT/NUM/DT/CHK/SW/RO/DD/AA=자동완성), 소스(API/룩업/없음), 기본값, 검증(필수/형식/업무), 비고.

### 11.1 입고(신규/수정 모달)
헤더 필드
| key | 라벨 | 유형 | 소스 | 기본값 | 검증 | 비고 |
|---|---|---|---|---|---|---|
| processed_at | 처리일자 | DT | 없음 | 오늘 | 필수 | SuperportShadDatePicker |
| warehouse_id | 창고 | DD | `/warehouses` | 없음 | 필수 | 라벨=창고명 |
| status_id | 상태 | DD | `/transaction-statuses` | 대기 | 필수 | 진행/승인/반려 등 |
| created_by_id | 작성자 | RO | 로그인 | 로그인 사용자 | - | 자동 세팅 |
| note | 비고 | TXT | 없음 | - | - | 다중라인 허용 |
| transaction_type_id | 입출고유형 | RO/숨김 | `/transaction-types` | 입고 | - | 라우트로 자동 설정 |

라인 필드(반복)
| key | 라벨 | 유형 | 소스 | 기본값 | 검증 | 비고 |
|---|---|---|---|---|---|---|
| product_id | 제품 | AA | `/products?q=` | - | 필수 | 선택 시 제조사/단위 자동 |
| vendor_name | 제조사 | RO | products.vendor | - | - | 제품 선택 시 자동 |
| uom_name | 단위 | RO | products.uom | - | - | 제품 선택 시 자동 |
| quantity | 수량 | NUM | 없음 | 1 | 필수, >=1 | 우측 정렬 |
| unit_price | 단가 | NUM | 없음 | 0 | >=0 | 우측 정렬 |
| line_note | 비고 | TXT | 없음 | - | - |  |

자동 표시(요약): 품목수(line_count), 총수량(total_qty), 총금액(total_amount) — 읽기전용.

### 11.2 출고(신규/수정 모달)
헤더 필드: 입고와 동일 + 고객 연결 섹션
| key | 라벨 | 유형 | 소스 | 기본값 | 검증 | 비고 |
|---|---|---|---|---|---|---|
| processed_at | 처리일자 | DT | - | 오늘 | 필수 |  |
| warehouse_id | 창고 | DD | `/warehouses` | - | 필수 |  |
| status_id | 상태 | DD | `/transaction-statuses` | 대기 | 필수 |  |
| created_by_id | 작성자 | RO | 로그인 | 로그인 사용자 | - |  |
| note | 비고 | TXT | - | - | - |  |
| transaction_type_id | 입출고유형 | RO/숨김 | `/transaction-types` | 출고 | - | 라우트로 자동 설정 |

고객 연결(반복 가능)
| key | 라벨 | 유형 | 소스 | 기본값 | 검증 | 비고 |
|---|---|---|---|---|---|---|
| customer_id | 고객사 | AA | `/customers?q=` | - | 최소 1건 | 토큰/칩 UI |
| customer_note | 비고 | TXT | - | - | - |  |

라인 필드: 입고와 동일(제품/제조사/단위/수량/단가/비고).

업무 규칙: 고객사 최소 1건 필수, 없으면 저장 불가(422 메시지 노출).

### 11.3 대여(신규/수정 모달)
헤더 필드
| key | 라벨 | 유형 | 소스 | 기본값 | 검증 | 비고 |
|---|---|---|---|---|---|---|
| processed_at | 처리일자 | DT | - | 오늘 | 필수 |  |
| warehouse_id | 창고 | DD | `/warehouses` | - | 필수 |  |
| status_id | 상태 | DD | `/transaction-statuses` | 대기 | 필수 |  |
| rental_type | 대여구분 | DD | 로컬(대여/반납) | 대여 | 필수 | 종결 후 변경 불가 |
| due_date | 반납예정일 | DT | - | +7일 | 선택 | 진행 중 수정 가능 |
| created_by_id | 작성자 | RO | 로그인 | 로그인 사용자 | - |  |
| note | 비고 | TXT | - | - | - |  |
| transaction_type_id | 입출고유형 | RO/숨김 | `/transaction-types` | 대여/반납 | - | 대여구분에 따른 자동 매핑 |

고객 연결/라인 필드: 출고와 동일.

### 11.4 마스터: 벤더/제품/창고/고객/사용자/그룹/메뉴/권한
벤더
| key | 라벨 | 유형 | 검증 | 비고 |
|---|---|---|---|---|
| vendor_code | 벤더코드 | TXT | 필수, 고유 | 수정 RO |
| vendor_name | 벤더명 | TXT | 필수 |  |
| is_active | 사용여부 | SW | - |  |
| note | 비고 | TXT | - |  |

제품
| key | 라벨 | 유형 | 검증 | 비고 |
|---|---|---|---|---|
| product_code | 제품코드 | TXT | 필수, 고유 | 수정 RO |
| product_name | 제품명 | TXT | 필수 |  |
| vendor_id | 제조사 | DD | 필수 | `/vendors` |
| uom_id | 단위 | DD | 필수 | `/uoms` |
| is_active | 사용여부 | SW | - |  |
| note | 비고 | TXT | - |  |

창고
| key | 라벨 | 유형 | 검증 | 비고 |
|---|---|---|---|---|
| warehouse_code | 창고코드 | TXT | 필수, 고유 | 수정 RO |
| warehouse_name | 창고명 | TXT | 필수 |  |
| zipcode | 우편번호 | TXT | 필수 | 검색 모달로 채움 |
| address_detail | 상세주소 | TXT | 필수 |  |
| is_active | 사용여부 | SW | - |  |
| note | 비고 | TXT | - |  |

고객사
| key | 라벨 | 유형 | 검증 | 비고 |
|---|---|---|---|---|
| customer_code | 고객사코드 | TXT | 필수, 고유 | 수정 RO |
| customer_name | 고객사명 | TXT | 필수 |  |
| types | 유형 | DD(멀티) | 최소 1 | 파트너/일반 |
| email | 이메일 | TXT | 이메일형식 |  |
| phone | 연락처 | TXT | - |  |
| zipcode | 우편번호 | TXT | - | 검색 모달 |
| address_detail | 상세주소 | TXT | - |  |
| is_active | 사용여부 | SW | - |  |
| note | 비고 | TXT | - |  |

사용자(사원)
| key | 라벨 | 유형 | 검증 | 비고 |
|---|---|---|---|---|
| employee_no | 사번 | TXT | 필수, 고유 | 수정 RO |
| employee_name | 성명 | TXT | 필수 |  |
| email | 이메일 | TXT | 이메일형식 |  |
| phone | 연락처 | TXT | - |  |
| group_id | 그룹 | DD | 필수 | `/groups` |
| is_active | 사용여부 | SW | - |  |
| note | 비고 | TXT | - |  |

그룹
| key | 라벨 | 유형 | 검증 | 비고 |
|---|---|---|---|---|
| group_name | 그룹명 | TXT | 필수, 고유 | 수정 RO |
| description | 설명 | TXT | - |  |
| is_default | 기본여부 | SW | - |  |
| is_active | 사용여부 | SW | - |  |
| note | 비고 | TXT | - |  |

메뉴
| key | 라벨 | 유형 | 검증 | 비고 |
|---|---|---|---|---|
| menu_code | 메뉴코드 | TXT | 필수, 고유 | 수정 RO |
| menu_name | 메뉴명 | TXT | 필수 |  |
| parent_id | 상위메뉴 | DD | - | `/menus` |
| route_path | 경로 | TXT | 필수 |  |
| display_order | 표시순서 | NUM | >=0 |  |
| is_active | 사용여부 | SW | - |  |
| note | 비고 | TXT | - |  |

그룹 메뉴 권한
| key | 라벨 | 유형 | 검증 | 비고 |
|---|---|---|---|---|
| group_id | 그룹 | DD | 필수 | RO(수정) |
| menu_id | 메뉴 | DD | 필수 | RO(수정) |
| can_create | 생성 | CHK | - |  |
| can_read | 조회 | CHK | - |  |
| can_update | 수정 | CHK | - |  |
| can_delete | 삭제 | CHK | - |  |
| is_active | 사용여부 | SW | - |  |

결재
| key | 라벨 | 유형 | 검증 | 비고 |
|---|---|---|---|---|
| transaction_id | 트랜잭션번호 | DD | 필수 |  |
| approval_no | 결재번호 | RO | - | 자동 부여 |
| approval_status_id | 상태 | DD | 필수 | 기본=대기 |
| requested_by_id | 상신자 | RO | - | 로그인 사용자 |
| requested_at | 요청일시 | RO | - | 자동 |
| note | 비고 | TXT | - |  |

결재 단계
| key | 라벨 | 유형 | 검증 | 비고 |
|---|---|---|---|---|
| approval_id | 결재ID | DD | 필수 | 수정 RO |
| step_order | 순서 | NUM | 필수, >=1 | 수정 RO |
| approver_id | 승인자 | DD | 필수 | `/employees` |
| step_status_id | 상태 | DD | 필수 | `/approval-statuses` |
| assigned_at | 배정일시 | RO | - | 자동 |
| decided_at | 결정일시 | RO | - | 자동 |
| note | 비고 | TXT | - |  |

결재 이력: 조회 전용(테이블 컬럼 정의만, 입력/수정 없음).

결재 템플릿: 헤더(코드/명/설명/작성자/사용여부/비고) + 단계(순서/승인자 반복).

우편번호 검색: 입력(검색어) → 결과 테이블에서 선택 시 부모의 `zipcode`/주소 구성요소 세팅.

## 12. 테이블 스펙(열/정렬/반응형)

공통: 정렬은 기본 `updated_at desc` 또는 업무상 자연스러운 키, 헤더 클릭으로 1열 정렬 전환. 폭(px)은 힌트 값이며 브레이크포인트에 따라 가변.

입고 목록
- 컬럼: 번호(80, center, sortable=id) | 처리일자(140, center, sortable) | 창고(160) | 트랜잭션번호(180) | 상태(120, center) | 작성자(140) | 품목수(100, right) | 총수량(120, right) | 비고(1fr)
- 모바일(<768): 번호, 처리일자, 상태, 품목수만 노출. 확장 시 나머지 표시.

출고 목록
- 컬럼: 번호 | 처리일자 | 창고 | 트랜잭션번호 | 상태 | 작성자 | 고객수(100, right) | 품목수(100, right) | 총수량(120, right) | 비고(1fr)
- 모바일: 번호/처리일자/상태/고객수.

대여 목록
- 컬럼: 번호 | 처리일자 | 창고 | 대여/반납(120, center) | 트랜잭션번호 | 상태 | 반납예정일(160, center) | 고객수 | 품목수 | 비고
- 모바일: 번호/대여구분/반납예정일/상태.

마스터 테이블(벤더/제품/창고/고객/사용자/그룹/메뉴/권한)과 결재/단계/이력/템플릿은 `doc/입출고 대여 폼 정리.md`의 1행 예시를 기준으로 동일한 컬럼 구성, 모바일에서는 코드/이름/상태 위주 노출.

열 가시성 프리셋(예시)
- 데스크톱(≥1280): 모든 열 표시. 비고는 1fr로 확장.
- 태블릿(≥1024): 우선순위 낮은 열(비고/표시순서 등) 일부 숨김, 총합/상태/핵심 식별자 유지.
- 모바일(<768): 핵심 3~4열만 표시(예: 번호/상태/일자/구분). 나머지는 행 확장 또는 상세에서 제공.

## 13. 폼 레이아웃 & 와이어프레임(텍스트)

공통 모달(데스크톱)
```
[모달 헤더: 타이틀]
────────────────────────────────────────────
[필드 그리드 2~3열]
  [라벨] [입력]   [라벨] [입력]   [라벨] [입력]
  ...

[섹션 타이틀] (예: 라인 품목)
[라인 테이블: 제품 | 제조사 | 단위 | 수량 | 단가 | 비고 | (+행)]

[하단 합계/요약 배지]

[푸터: 취소][저장]
```

모바일(풀스크린)
```
[<] 제목                                [저장]
────────────────────────────────────────
[필드 1열 스택]
[섹션]
[라인: 카드형 반복]
[합계]
```

입고 등록 예시(데스크톱, 3열)
```
처리일자 [DT]   창고 [DD]         상태 [DD]
작성자 [RO]     비고 [TXT···(colspan=2)]

라인 섹션:
┌제품 [AA]┬제조사[RO]┬단위[RO]┬수량[NUM]┬단가[NUM]┬비고[TXT]┬(+)
└────────┴─────────┴──────┴───────┴───────┴───────┴────

[품목수: n][총수량: x][총금액: ₩y]
```

출고 등록: 상단 동일 + [고객사(멀티) 토큰 리스트 + (+추가) 자동완성]

## 14. 상호작용/플로우
- 리스트 → +신규 클릭 → 모달 → 저장 → 성공 토스트 → 리스트 리프레시/최상단 스크롤.
- 행 클릭 → 상세 모달(또는 우측 패널) → 수정 가능 상태면 “수정” 노출.
- 라인 편집: 수량/단가 변경 시 합계 즉시 반영. Enter/Tab으로 다음 셀 이동. (+)는 마지막 행 뒤에 포커스.
- 출고/대여 고객 토큰: 입력 자동완성 → Enter로 선택 → 토큰 생성. 토큰 X 클릭으로 제거.
- 삭제: 소프트 삭제 확인 모달 → 성공 시 상태 배지/행 스타일로 삭제 표시(필터로 숨김 기본).

## 15. 검증/오류 메시지(예시)
- 필수 누락: “처리일자를 입력해 주세요.”
- 수량 음수: “수량은 1 이상이어야 합니다.”
- 고객 미선택(출고/대여): “고객사는 최소 1건 선택해야 합니다.”
- 결재 상태 전이 금지: “현재 단계 상태에서는 다음 단계로 이동할 수 없습니다.”
- 네트워크 오류 시: 오류 토스트/다시 시도 버튼/오류 상세 제공(더미 데이터 사용 금지).

## 16. 키보드/접근성
- 단축키: Cmd/Ctrl+S 저장, Esc 닫기, Enter 다음 필드/행 추가(라인 끝).
- 포커스 순서: 위→아래, 좌→우. 포커스 트랩으로 모달 내에서 순환.
- ARIA 라벨 등 시맨틱: 가능한 범위에서 위젯 라벨/설명 제공.

## 17. 환경/피처 토글
- 환경 변수로 API 베이스 URL/타임아웃/로그 레벨 제어.
- 기능 플래그로 베타 화면/행동 토글(데이터는 항상 실 API 사용).
- 페이지네이션: 기본 20행, 최대 100행.

## 18. 상태 전이(결재)
- approval_statuses: 대기(기본, blocking), 진행중(blocking), 보류(blocking), 승인(non-blocking), 반려(terminal, blocking).
- 단계 행위: approve → 다음 단계 배정, 모든 단계 승인 시 전체 승인. reject → 전체 반려(terminal) 처리.
- 전이 금지: blocking 상태에서는 `can_proceed=false` 처리(버튼 비활성/툴팁).

## 19. API 매핑(연동 시)
- 트랜잭션 목록: `GET /stock-transactions?include=lines,customers`
- 생성: `POST /stock-transactions` 바디 내 헤더/라인/고객 배열 동시 전달
- 결재 상세: `GET /approvals/{id}?include=steps,histories`
- 단계 행위: `POST /approval-steps/{id}/actions` with `approval_action_id`
- 결재 템플릿: `GET/POST/PATCH /approval/templates`, `POST/PATCH /approval/templates/{id}/steps`
- 룩업: `/uoms`, `/transaction-types`, `/transaction-statuses`, `/approval-statuses`, `/approval-actions`

## 20. 컴포넌트 매핑(shadcn_ui)
- 입력: `ShadInput`, 숫자 입력은 우측 정렬 스타일.
- 선택: `ShadSelect`(단일), 자동완성은 `ShadSelect + 검색` 패턴 또는 커스텀 콤보(리스트 팝오버, 키보드 선택) — 레퍼런스: 슈퍼포트 구현체.
- 날짜: `SuperportShadDatePicker`, 기간 필터는 `SuperportShadDateRangePicker`.
- 스위치/체크: `ShadSwitch`, `ShadCheckbox`.
- 모달: `SuperportShadDialog`(헤더/본문/푸터), 모바일 풀스크린 전환.
- 테이블: `ShadTable.list` + `two_dimensional_scrollables`로 스크롤 최적화.

---
부록: 필요 시 각 스크린의 모바일 카드형 레이아웃 명세(요약 배지, 핵심 필드 순서)를 추가 정의한다.
