Skip to content

재고 품목·수량·반품 대상 관리 ​

제품 개발 기록 · 조직·권한 · 총무

품목·카테고리·수량·반품의 관리 절차를 설명합니다. 실행한 조작과 추가 검증이 필요한 경로는 아래 영상 기록에서 구분합니다.

범위와 진입 ​

재고 담당자가 조직별 카테고리와 품목을 등록하고 현재 수량, 유효기간, 반품 대상 여부를 관리합니다. 별도 구매 발주·입출고 원장·반품 승인/배송/환불 완료 단계는 없습니다. 재고 수량 변경 사유는 API 로그에 기록되며 조회 가능한 입출고 이력 테이블로 저장되지 않습니다.

로그인 후 /inventory/에서 시작합니다. 탭은 대시보드(/inventory/, /inventory/overview), 재고관리(/inventory/items), 구분(/inventory/categories), 관리(/inventory/refunds)입니다. 구분은 카테고리, 관리는 반품 대상 목록입니다. 관리자 LNB에는 현재 재고 메뉴가 없으므로 관리자 내부 메뉴가 있다고 안내하지 않습니다. 배포의 앱 진입 주소는 환경별 기본 경로 설정을 따릅니다.

조회에는 inventory:read, 생성·수정·삭제·수량 조정·반품 표시에 inventory:manage가 필요합니다. API는 현재 조직을 조건으로 조회합니다. 역할명만으로 권한을 보장하지 않으며, 별도 팀/본인 단위 재고 화면은 없습니다. 최초 품목 등록에는 카테고리가 먼저 있어야 합니다. 로그인 및 비밀번호 변경은 인증을 따릅니다.

조작 목록 ​

ID조작입력·결과절차
IV01대시보드 조회활성 품목·카테고리·임박·부족·반품 대상 건수아래 현황 절
IV02품목 검색·카테고리 필터·초기화이름 부분 검색과 카테고리 교집합품목 절
IV03목록 페이지 이동품목·반품 목록, 30건씩품목 절
IV04카테고리 생성코드·이름·설명·순서카테고리 절
IV05카테고리 수정이름·설명·순서, 코드 변경 불가카테고리 절
IV06카테고리 삭제확인 후 논리 삭제카테고리 절
IV07품목 생성필수 이름·카테고리, 선택 정보품목 절
IV08품목 수정수량 포함 현재 값 수정품목 절
IV09품목 삭제확인 후 논리 삭제품목 절
IV10수량 증감정수 변경량, 선택 사유수량 절
IV11반품 대상·수량·메모 지정/수정품목의 반품 정보 저장반품 절
IV12반품 대상 해제후보 목록에서 제외반품 절

내보내기·가져오기·일괄 변경·활성 상태 전환·활성/임박 필터는 현재 화면에 없습니다. API에 isActive, expiringWithinDays가 있다는 이유로 UI 절차를 만들지 않습니다.

현황 읽기 ​

  1. 대시보드 탭을 누릅니다. 다섯 카드는 읽기 전용이며 눌러서 필터 목록으로 이동하지 않습니다.
  2. 재고 부족은 활성 품목 중 최소재고 > 0이고 현재 수량 ≤ 최소재고인 건수입니다. 최소재고 10, 수량 10도 포함됩니다. 최소재고 0은 부족으로 집계하지 않습니다.
  3. **유효기간 임박 품목 (90일 이내)**에서 오늘부터 30일 이내는 긴급, 31~60일은 주의, 61~90일은 알림으로 읽습니다. 이미 지난 만료일은 이 API 목록에서 제외됩니다. 품목 목록의 만료 표시와 대시보드 임박 건수는 같은 집합이 아닙니다.
  4. 결과가 없으면 유효기간 임박 품목이 없습니다.를 표시합니다. 품목 저장 뒤 대시보드 탭을 다시 누르면 집계를 다시 불러옵니다.

집계의 날짜 경계는 서버의 ISO 날짜를 사용하고 품목의 D-day 표시는 브라우저 날짜 계산을 사용합니다. 자정 부근 일치 여부는 실행 검증이 필요합니다.

카테고리 만들기·고치기·삭제하기 ​

  1. 구분 → + 카테고리 추가를 누릅니다. 예: 코드 SUPPLY, 이름 진료 소모품, 설명 외래 공용, 정렬순서 10.
  2. 코드, 이름에는 화면의 필수 표시가 있습니다. 서버는 이름 1자 이상을 요구하지만 코드는 선택 문자열입니다. UI 필수 표시와 서버 검증이 완전히 같지 않습니다. 설명은 선택이며 빈 값은 null, 순서는 기본 0입니다. 순서 오름차순, 이름 오름차순으로 표시됩니다.
  3. 저장하면 모달이 닫히고 카드 목록을 다시 조회합니다. 카드에는 이름·코드·설명·활성 상태·품목 수가 나옵니다.
  4. 카드 수정에서 기존 값을 불러와 이름·설명·순서를 바꾼 뒤 저장합니다. 코드 입력은 수정 중 비활성입니다.
  5. 삭제 → 확인하면 카테고리에 deletedAt을 기록하고 목록에서 제외합니다. 취소하면 유지합니다. 품목이 있는 카테고리의 삭제를 막는 API 검사는 없고 품목도 함께 삭제하지 않습니다. 하위 품목 정리·재배정은 따로 확인해야 합니다. 복원 버튼은 없습니다.

카테고리 이름·설명은 조직 데이터입니다. 기존 가이드에 나온 특정 의약품 카테고리나 신고 안내가 모든 조직에 기본 제공된다는 의미는 아닙니다.

품목 찾기·등록·수정·삭제하기 ​

  1. 재고관리에서 **품목 검색...**에 이름 일부를 입력하고 카테고리를 선택합니다. 서버 검색은 품목명에 적용됩니다. 초기화는 검색어와 카테고리를 비우고 재조회합니다. 목록 아래 « ‹ 페이지 › »로 30건씩 이동합니다. 반품 목록도 같은 단위입니다.
  2. + 품목 추가를 누릅니다. 필터에 카테고리가 선택되어 있으면 그 값, 아니면 첫 카테고리가 기본 선택됩니다. 카테고리가 없으면 먼저 구분에서 생성합니다.
  3. 아래 필드를 입력하고 저장합니다. 목록이 재조회되며 서버 InventoryItem에 저장됩니다.
입력필수·기본값·형식주의
품목명필수, 1자 이상예: 멸균 거즈 10장
카테고리필수, 조직 카테고리 UUID생성 API가 같은 조직 카테고리 존재 확인
코드선택빈 값은 null
수량 / 최소재고기본 0, 정수폼의 음수 제한과 별개로 생성·수정 스키마에는 음수 하한 검증이 없음
단위기본 개예: 팩; 자유 문자열
유효기간선택, 날짜 입력예: 2027-03-31; 별도 과거일 금지 없음
보관위치 / 공급업체 / 비고선택빈 값은 null
  1. 행 수정에서 기존 값을 수정하고 저장합니다. 이 경로는 수량을 절대값으로 덮어씁니다. 증감하려면 다음 절의 수량을 사용합니다.
  2. 행 삭제 → 확인은 품목을 논리 삭제하고 목록에서 제외합니다. 확인의 취소는 아무 값도 바꾸지 않습니다. 삭제 취소/복원 UI는 없습니다.
  3. 생성·수정 모달의 취소, X, Esc는 닫습니다. 별도 미저장 확인이 없으며 다시 열면 서버/목록 값으로 초기화됩니다. 저장 오류는 오류 대화상자를 표시하고 모달에 입력이 남습니다.

유효기간을 비워 저장하면 프런트는 null을 보내지만 API가 undefined로 바꾸는 경로가 있습니다. 기존 유효기간이 실제로 지워졌는지는 재조회로 확인해야 하며, 정상 삭제를 보장하는 절차로 설명하지 않습니다.

수량 조정 ​

재고 품목의 수량 변경 모달

재고 수량 변경 화면입니다. 아래 번호 순서대로 입력란을 채우고 저장합니다. 입력 전 모달을 보여 주며 저장 결과는 이 이미지에 포함되지 않습니다.

  1. 재고관리 → 대상 행 작업 → 수량을 눌러 현재 수량을 확인합니다.
  2. **변경량 (+ 입고 / - 출고)**에 정수를 넣습니다. 현재 42개에서 -2이면 변경 후: 40을 미리 표시합니다. 변경량 0이면 실행하지 않습니다.
  3. 사유에 진료실 사용처럼 이유를 입력합니다. 운영상 남기는 것이 유용하지만 필수 검증은 없습니다.
  4. 변경하면 서버가 현재 수량을 다시 읽고 증감한 값을 저장하며 목록을 재조회합니다. 결과가 음수이면 Quantity cannot be negative 오류로 거절됩니다. 취소/X/Esc는 저장하지 않습니다.
  5. 성공 이후 잘못된 조정은 별도 반대 증감으로 바로잡습니다. 최초 요청이 성공했는지 모호하면 먼저 목록을 재조회해야 합니다. 같은 증감을 재전송하면 한 번 더 적용될 수 있습니다. 서버에 잠금·원자 증감이 없으므로 동시 수정 충돌도 별도 검증 대상입니다.

반품 대상 표시와 해제 ​

  1. 품목 행 반품에서 반품 대상으로 표시를 체크합니다. 체크해야 반품 수량, 반품 사유 입력이 나타납니다.
  2. 수량은 기본 0이며 폼에 min=0이 있습니다. API는 정수만 확인하고 현재 재고 이하인지 확인하지 않습니다. 반품 수량 2, 미사용 포장을 입력하고 저장합니다.
  3. 관리 탭의 반품 대상 목록에서 품목·수량·메모를 확인합니다. 이 저장은 현재 재고 수량을 줄이지 않으며 반품 완료나 환불을 생성하지 않습니다.
  4. 반품 목록의 수정으로 메모와 수량을 바꾸거나 체크를 해제해 저장합니다. 해제는 확인 없이 isRefundCandidate=false를 저장하고 목록을 재조회합니다.
  5. 해제 시 프런트는 메모·수량에 null을 보내지만 API는 이를 undefined로 변환합니다. 후보 표시는 해제되더라도 과거 메모·수량이 DB에 남을 가능성이 있으므로 데이터 초기화로 간주하지 않습니다.

데이터 관계와 유지보수 ​

InventoryService는 화면의 목록·CRUD·증감·반품 호출을 inventory.router.ts에 전달합니다. 유효성은 inventory.schema.ts, 저장은 InventoryCategory와 InventoryItem입니다. 앱 상태 처리는 대부분 조회 오류를 조용히 처리하므로 비어 있는 화면만으로 실제 0건인지 권한/네트워크 실패인지 판별할 수 없습니다.

직접 /items나 /refunds로 들어오면 탭 이름은 복원하지만 최초 loadData()는 요약·카테고리만 불러옵니다. 해당 탭을 다시 눌러 목록 조회가 실행되는지 확인해야 합니다. 조회 재시도는 탭 재선택/재접속이며 자동 재시도 버튼은 없습니다. 이 차이는 문서로 가리지 않고 남깁니다.

기존 기록과 이번 정합화 ​

HBIV000~230 명세, 앱 소개, HTML 가이드와 현재 구현을 대조했습니다. 명세의 추정 sdk.inventory.dashboard.get()은 실제 getDashboardSummary()로 추적했고, 부족 기준을 <에서 ≤로 바로잡았습니다. 소개의 활성/임박 필터·반품 처리 상태는 화면에 맞춰 정정했습니다. 외부 동기화 명세와 생성 Markdown은 수정하지 않았습니다.

실행 검증과 새 미디어는 없습니다. 필요한 캡처는 카테고리 생성 전후, 품목 저장 후 재열기, 42→40 수량 조정의 저장 결과, 부족 임계값 10/10, 30·60·90일 경계, 반품 지정/해제 전후, 읽기 전용 계정의 저장 거절, 직접 경로 첫 로드입니다. 참고 이미지는 입력 전 모달 하나만 설명하며 현재 동작 전체를 검증하지 않습니다.

재고 관리 사용 영상 ​

28초 · 소리 없음 · 화면 안의 번호와 강조 위치를 따라 보세요. 전체화면으로 확대할 수 있어요.

처음에는 재생 버튼을, 다시 볼 때는 아래 동작 번호를 누르세요.

  1. 재고 목록 열기

    재고관리 앱에서 「재고관리」 탭을 열고 품목·현재 수량을 확인합니다. 현재 관리자 메뉴에 직접 연결되지 않은 별도 앱입니다. 자세히 따라 하기

  2. 수량 변경 열기

    변경할 ‘소독 알코올’ 행의 「수량」을 누릅니다. 재고 수정 권한이 필요합니다. 자세히 따라 하기

  3. 입고량·사유 입력

    변경량은 입고 시 양수, 출고 시 음수로 입력합니다. 예제는 현재 28개에 20개를 더하고 사유 ‘정기 입고 20개’를 입력합니다. 자세히 따라 하기

  4. 저장 결과 확인

    「변경」을 누르고 목록에서 48개가 저장된 것을 확인합니다. 입력한 값은 최종 수량이 아니라 증감량입니다. 자세히 따라 하기

교육용 예제 조직에서 촬영했어요. 이름·금액·날짜는 교육용 예시이며, 사용 중인 조직의 자료를 확인하세요.

재고 관리 소개와 사용자 교육에서 실제 누르는 위치와 결과를 따라갈 수 있도록 번호 자막·강조 표시를 붙여 촬영했습니다. 별도 DB의 로컬 예제 조직·관리자 테스트 계정을 사용했습니다. 화면 크기는 1440×900입니다. 소독 알코올 수량을 28개에서 48개로 변경하고 목록 결과를 확인했습니다. 출고·음수 결과 거절·실패 복구·다른 기기 재진입은 별도 검증 대상입니다.

앱 소개 · 영상 목록과 교육 범위 · 촬영·검증 기록

사용자용 절차 연결 ​

재고 수량 조정은 고객이 개발 기록을 열지 않고 읽는 사용법입니다. Codex가 사용자용 절차에 현재 수량 확인, 증감 입력, 저장과 취소, 중복 반영 주의를 보완했습니다. 영상의 자세히 따라 하기는 이 절차로 연결합니다. 수량 조정의 입력 검증과 저장 규칙을 바꾸면 이 설명도 함께 갱신합니다. 이 문서 연결 정리는 제품 동작을 다시 실행하거나 녹화 범위를 확장한 검증이 아닙니다.