Commit Graph

119 Commits

Author SHA1 Message Date
chpark b343565bc1 feat(pwa): PWA + TWA 화 (Android APK 빌드 대비)
- public/manifest.json + service worker(sw.js) 추가
- icon PNG 변환 (192/512/180)
- public/.well-known/assetlinks.json placeholder (Bubblewrap 빌드 후 APK 서명 SHA256 채울 자리)
- layout.tsx 에 manifest/theme-color/apple-touch-icon 메타데이터 + 서비스 워커 등록 스크립트 추가

Bubblewrap 으로 APK 빌드 시 https://www.momotogether.com/manifest.json 을 source 로 사용.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 23:19:42 +09:00
chpark 7d7b22f388 docs: 인프라 이관 가이드 추가 (집 PC → IDC)
운영 서비스 목록, 데이터 볼륨 위치, 노출 포트, 운영 중 적용한 hotfix(Mailu DNSSEC/MariaDB 11.8 등), Phase 별 이관 체크리스트.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 23:17:57 +09:00
chpark 3785577442 chore: 원본 FITO Java/JSP 잔존물 제거 (Next.js 전환 완료)
WebContent/ (JSP + SmartEditor2 + 정적 자원) 와 src/com/ (Spring Controller/Service/Mapper) 디렉토리 전체 삭제. 총 2,191 파일.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 23:17:57 +09:00
chpark 4a00620d86 ci(deploy): 배포 후 dangling 이미지 자동 prune (옛 momo-erp sha 누적 방지)
Deploy momo-erp / deploy (push) Successful in 2m55s
docker compose build 시 latest 태그가 새 sha 로 갱신되면서 옛 sha 가 untagged
상태로 남아 매 배포마다 누적되던 문제. docker image prune -f 로 dangling 만 회수
(다른 프로젝트의 사용 중 이미지는 안 건드림).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 13:48:01 +09:00
chpark 1d3597ecb4 fix(dashboard): USER 분기 dead code 제거 (직전 commit 빌드 fail fix)
Deploy momo-erp / deploy (push) Successful in 23s
2026-05-12 11:56:37 +09:00
chpark 4206d57810 fix(dashboard): 거래처(USER) 진입 시 /m/orders/new 로 자동 이동
Deploy momo-erp / deploy (push) Failing after 3m42s
대시보드는 관리자 전용. USER 가 직접 URL 로 진입해도 즉시 출고 요청 화면으로
리다이렉트되게 차단. (메뉴 매핑 없어도 직접 URL 접근 방지)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 11:56:00 +09:00
chpark 9705a04328 feat(items): 제조사 필드/메뉴 제거 + 공급업체 검색 + 원가/단가 천단위 콤마
Deploy momo-erp / deploy (push) Failing after 1m31s
- 품목 폼/리스트/모바일 카드에서 제조사 컬럼·셀렉트 제거 (dead code 정리)
- 공급업체 셀렉트 → SearchableSelect (결과내 검색 가능)
- 단가/원가 인풋: type=number → text + 천단위 콤마 표시, 소수점 제거(반올림)
- 운영 menu_info: '제조사 관리' (9000204) status='inactive'

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 10:54:32 +09:00
chpark 52084d6075 feat(statistics): '업체별 발주통계' 명확화 + SHIPPED 필터 제거
Deploy momo-erp / deploy (push) Failing after 1m29s
- 화면 제목: '통계 — 업체별 월간 매출' → '업체별 발주통계 (월별)'
- 메뉴명: '월간 매출' → '업체별 발주통계' (운영 DB menu_info 9000501)
- statistics/monthly API: status IN 에서 SHIPPED (dead code) 제거
- 기존 기능 그대로: 년/월 선택, 업체별 합계 + 면세/과세 분리, 엑셀 다운로드

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 10:28:04 +09:00
chpark f62660952b fix(migration): 009 의 DELETE FROM user_info 비활성화 — 매 배포마다 거래처 삭제 사고
Deploy momo-erp / deploy (push) Successful in 1m54s
[원인]
- db/migrations/009_items_user_permissions.sql 가 user_type<>'C' AND
  NOT IN (admin 7인) 사용자를 삭제하는 정리 쿼리를 포함
- user_type 'C' → 'U' 통합 이후 'U' 거래처 134명이 위 조건에 걸려
  매 배포마다 통째로 삭제됨 (어제·오늘 두 번 사용자 관리에 거래처 0명)

[수정]
- 해당 DELETE 블록 통째로 주석 처리 — 마이그레이션은 idempotent 해야 하고
  destructive 작업은 두지 않는다는 원칙
- 거래처 134명은 별도 복구 스크립트로 다시 INSERT (이 commit 직후)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 10:20:02 +09:00
chpark f6e1436252 fix(items): 숨김 품목이 권한 없는 사용자에게 노출되던 문제
Deploy momo-erp / deploy (push) Successful in 1m44s
[원인]
- lib/auth.ts verifyCredentials 는 user.role 을 설정하지 않음
- /api/m/items/list 가 `r.user.role === 'USER'` 만 체크 → 일반 거래처도
  isUser=false 가 되어 status='ACTIVE' 필터 & view_hidden 필터 모두 우회
- 결과: 골드망고(status=active, is_hidden=Y) 가 모든 사용자에게 보임

[수정]
- isAdmin = role==='ADMIN' || isAdmin || userType==='A' (3가지 모두 검사)
- isUser = !isAdmin
- items/list: status 'ACTIVE' 비교를 UPPER(...) 로 대소문자 안전화
- orders/save: 숨김 품목(is_hidden='Y') 발주 시도를 view_hidden 권한 없으면 차단
- orders/new 클라이언트의 unlimitedQty 판정에도 userType==='A' 보강

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 10:14:36 +09:00
chpark 1e631c9181 fix(user-form): 부서 셀렉트 매칭 + 사번 제거 + 컴팩트 레이아웃
Deploy momo-erp / deploy (push) Failing after 1m33s
[부서 안 선택되던 문제]
- /api/admin/dept 가 DEPT_CODE/DEPT_NAME 대문자 반환인데 폼은 dept_code 소문자
  로 접근 → 옵션 매칭 실패. 대문자로 통일

[필드 제거]
- 사번(sabun) 입력 제거 (요청)
- dead var isCustomer 제거

[레이아웃 컴팩트화 — 스크롤 없이 한 화면]
- 폰트 13→12, 인풋 h-9→h-8, 여백/마진 축소
- 출고 기준 창고 + 특수 권한 섹션을 별도 큰 카드 → 2열 그리드 안에 통합
- 특수 권한 체크 라벨도 컴팩트 (가로형 inline 칩)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:58:51 +09:00
chpark 4e85dd56fe fix(user_type): 유형을 관리자(A)/사용자(U) 2가지로 통일
Deploy momo-erp / deploy (push) Successful in 1m42s
거래처/협력사 구분 제거 — 거래처 = 일반 사용자(U).
공급업체는 별도 supply_mng 테이블(공급업체 관리)에서 관리.

[UI]
- user-form 유형 셀렉트: 관리자/사용자 2개만 (거래처·협력사 제거)
- UserManagement 검색 구분 셀렉트: 관리자/사용자만
- profile 라벨: USER_TYPE='A' 면 '이름', 그 외 '업체명/이름'

[API/로직]
- signup: user_type='C' → 'U' / user_type_name '거래처' → '사용자'
- customers/list & customers/save: user_type='C' 강제 → user_type != 'A'

[운영 DB]
- 기존 user_type IN ('C','P') 134명 → 'U' 일괄 변경
  (분포: A 7명 / U 134명)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:53:33 +09:00
chpark a940c0735b fix(orders/new): ListView 에 unlimitedQty prop 전달 (빌드 fail fix)
Deploy momo-erp / deploy (push) Successful in 1m42s
직전 commit 9e9922e 에서 ListView 내부에서 부모 scope 의 unlimitedQty 를
직접 참조 → TS2304. props 로 명시 전달

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:48:44 +09:00
chpark 9e9922e219 feat(perm): 사용자 특수권한(발주한도 무시·숨김 품목 보기) UI 노출 + 출고요청 반영
Deploy momo-erp / deploy (push) Failing after 43s
[사용자 관리]
- /api/admin/users 목록에 UNLIMITED_QTY / VIEW_HIDDEN / USER_TYPE 컬럼 반환
- UserManagement 그리드에 '발주한도무시' / '숨김품목보기' 컬럼 추가 (/—)
- 사용자 수정 폼: '거래처 특수 권한' → '특수 권한 (발주 시 적용)' 으로 라벨 변경,
  거래처(C) 전용이던 조건을 풀어서 일반 사용자(U) 도 권한 부여 가능

[출고요청 (/m/orders/new)]
- /api/auth/me 가 unlimitedQty / viewHidden 반환
- 클라이언트가 unlimitedQty true 면 MAX_ORDER_QTY 무시하고 재고만큼 발주 가능
- '한도 ≤ N' 라벨도 권한자에겐 숨김

(백엔드 검증 — /api/m/items/list 의 view_hidden, /api/m/orders/save 의
 unlimited_qty 우회 — 는 이미 구현돼 있어 그대로 동작)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:46:37 +09:00
chpark 77d89527b8 fix(dept): 부서코드/회사명 입력 숨김 + 자동생성 + DB 정리
Deploy momo-erp / deploy (push) Failing after 1m30s
[UI]
- 부서 등록 폼: 부서코드/회사명 입력 제거 (부서명만 입력)
- 부서 목록 grid: 부서코드/회사명 컬럼 제거 (부서명/활성여부/등록일만)

[API]
- /api/admin/dept/save: dept_code 비어있으면 'DEPT' + MAX+1 자동 생성
- company_name 기본값 '모모유통'

[운영 데이터 정리]
- 거래처(user_type='C') 134명 dept_code → DEPT003 일반구매자
- 전체 사용자 141명 비밀번호 → '1' (AES 암호화 저장)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:39:15 +09:00
chpark 2ea2a6759e fix(auth): 권한그룹 코드 입력칸 숨김 + 자동생성
Deploy momo-erp / deploy (push) Failing after 1m31s
- 권한그룹 생성 모달에서 권한CODE 입력 제거 (권한명만 입력)
- 서버: 신규 등록 시 auth_code 비어있으면 GRP_<base36 timestamp> 자동 생성
- 좌측 권한 목록에서도 코드 노출 제거 (내부 식별자만 유지)
- 수정 시 기존 auth_code 는 보존 (COALESCE)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:30:55 +09:00
chpark 52db6eff53 fix(menu): isAdmin 백도어 제거 — 권한 그룹 매핑대로 동적 노출
Deploy momo-erp / deploy (push) Failing after 1m32s
기존 SQL 은 $isAdmin=true 면 모든 메뉴 통과 → 권한 매핑이 의미 없었음.
사용자 요청: "로그인한 사용자 권한 그룹에 따른 메뉴가 동적으로 나오도록"

- /api/menu: isAdmin 분기 제거, authority_sub_user JOIN authority_sub_menu
  매핑만 사용. 자식이 권한에 있으면 부모도 자동 노출(트리 유지) 로직은 유지
- 운영 DB: 관리자그룹에 active 메뉴 36개 일괄 매핑 (재고 이력 9000304 포함).
  사용자 관리 화면에서 권한 그룹 멤버 / 메뉴 매핑을 직접 조정해 사용자별
  사이드바를 동적으로 제어

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:26:22 +09:00
chpark 10e8dad841 fix(user/default_wh_objid): numeric → text 로 변환
Deploy momo-erp / deploy (push) Successful in 1m42s
운영 momo_warehouses.objid 가 text 타입(예: MOMOWH000000001)이라
default_wh_objid 도 text 로 일치시켜야 매핑 가능.
- db/migrations/022_user_default_wh_text.sql
- /api/admin/users/save: ::numeric 캐스트 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 23:36:49 +09:00
chpark 3ba6237a32 feat(orders+users): 사용자별 기준 창고 매핑 → 출고 시 그 창고에서 차감
Deploy momo-erp / deploy (push) Successful in 1m49s
본사팀 / 김포팀 거래처 리스트처럼 거래처별로 출고 창고가 다른 케이스 대응.
회원은 가입 시 기본 정보만 입력하고, 관리자가 사용자 수정에서 창고를 매핑.

[스키마]
- db/migrations/021_user_default_wh.sql: user_info.default_wh_objid numeric NULL

[API]
- /api/admin/users/detail: default_wh_objid 반환
- /api/admin/users/save: 수정 시 default_wh_objid 저장 (빈 값 → NULL)
- /api/m/orders/approve: 1) 거래처의 default_wh_objid → 2) STOCK 첫 창고 fallback

[UI]
- admin-panel/user-form: '출고 기준 창고' 셀렉트 추가 (수정 모드만)
  미지정 시 기본 창고로 fallback

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 15:18:22 +09:00
chpark ed66ca36eb fix(orders+payments): SHIPPED 상태 중복 라벨 제거 + 입금관리 검색조건 추가
Deploy momo-erp / deploy (push) Successful in 48s
[출고 상태 셀렉트 중복 fix]
- STATUS_LABEL 에 APPROVED='출고완료' / SHIPPED='출고완료' 둘 다 매핑돼
  셀렉트 옵션에 '출고완료'가 두 번 노출됐음. 운영 DB 분포 확인 결과
  SHIPPED 상태값은 0건(dead) → 라벨/색상 매핑에서 SHIPPED 제거.
  StatementPreview 의 'SHIPPED' OR 분기도 정리

[입금 관리 검색조건]
- 시작일 / 종료일 / 입금 상태(전체·입금 전·입금완료) / 업체명·발주번호 키워드
- 기본 기간: 이번달 1일 ~ 오늘
- 입금 상태: UNPAID = APPROVED, PAID = PAID + INVOICED 묶어서 필터
- 초기화 / 조회 버튼

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:09:22 +09:00
chpark d5954d39e9 fix(procurements): 발주서 품명 옆 [품목코드] 노출 제거
Deploy momo-erp / deploy (push) Failing after 35s
거래처에 보내는 양식이라 내부 ITEM_CODE 는 보일 필요 없음.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:05:42 +09:00
chpark 8a263467ba fix(inventory/history): 모바일 카드 + 검색바 반응형
Deploy momo-erp / deploy (push) Successful in 47s
- 기존: <table overflow-hidden> 으로 모바일에서 가로 컬럼이 잘려 스크롤이 안 됨
- 데스크톱(sm 이상): hidden sm:block + overflow-x-auto + min-w-[760px]
- 모바일(sm 미만): sm:hidden 카드 — 유형 배지/품목명/수량/창고/메모/처리자/일시
  → 페이지 자체 스크롤로 자연스러운 UX
- 검색바 모바일 1열 → sm 3열 → lg 5열, 요약카드 폰트도 화면별 분기

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:04:20 +09:00
chpark d1683a3c6e feat(inventory+warehouse): 재고 이동 + 모바일 카드 + 창고코드 자동생성
Deploy momo-erp / deploy (push) Failing after 35s
[재고 관리]
- 새 기능 '재고 이동' (A창고 → B창고): 출발창고 잠금 + 충분재고 검증 + 도착
  창고 upsert + 이동 로그 2건(OUT/IN, ref_type=TRANSFER) 트랜잭션 처리
- /api/m/inventory/transfer 신규
- 모바일에서 테이블 가로 스크롤이 안 되던 문제 → sm:hidden 카드 + sm:block
  desktop 테이블로 분리. 페이지 자체 스크롤로 자연스러운 UX
- 검색 영역 모바일 1열 / sm 3열 그리드 정리
- 재고 이동 모달은 출발창고 선택 시 그 창고에 재고 있는 품목만 셀렉트
- list API 응답에 WH_OBJID 추가 (이동 모달에서 출발창고 필터 용도)

[창고 관리]
- 창고 코드는 자동생성(WH001, WH002 ...) — 등록/수정 폼에서 readonly + 회색.
  save API: regist 시 nextWhCode() 로 MAX+1 패딩. update 시 wh_code 미변경
- 클라이언트가 whCode 보내도 무시되도록 서버에서 분기

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 16:34:19 +09:00
chpark 2d40678358 feat(dashboard+orders): 카드별 정확한 필터 전달 + 출고요청 카드 컴팩트화
Deploy momo-erp / deploy (push) Failing after 35s
[대시보드 → 출고처리 카드 필터]
- 승인 대기 / 진행중 / 미수금 → ?status=...&dateFrom=&dateTo= (전체 기간, 빈 날짜)
- 오늘 발주 → ?dateFrom=오늘&dateTo=오늘
- 이번달 매출/누적 → ?dateFrom=이번달1일&dateTo=오늘
- orders 페이지: 쿼리에 dateFrom/dateTo 키가 있으면(빈값 포함) 그 값 사용,
  키가 아예 없을 때만 기본값 오늘. 사용자 모드 페이지도 동일

[출고 요청 카드 그리드]
- grid-cols-3 / md-4 / lg-5 — PC 5개·모바일 3개/줄
- 카드 padding p-3~p-4 → p-2, 폰트/버튼/이미지 라벨 모두 컴팩트
- IS_TAX_FREE/REQUIRES_DELIVERY 배지를 이미지 위 좌상단으로 이동해 공간 절약
- 품목명 line-clamp-2 + min-h-[2em] 로 카드 높이 일정화

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 15:45:49 +09:00
chpark ebabd726f3 feat(admin/orders): 검색 조건 + 모바일 레이아웃 + 페이지명 단순화
Deploy momo-erp / deploy (push) Successful in 50s
- 페이지명: '발주서 관리 · 출고처리' → '출고 처리'
- 검색바 신규: 시작일 / 종료일 / 상태 / 검색어(발주번호·업체명·이메일) / 초기화·조회
- 모바일 1열, sm 2열, lg 5열 그리드로 반응형 정리
- API list: keyword 파라미터 추가 (order_no/user_name/email LIKE)
- 기본 기간 = 오늘. 단 ?status= 으로 진입(대시보드 카드)한 경우 30일 범위
- 검색 조건 변경은 [조회] 버튼으로만 트리거 (자동 reload 제거 → 입력 도중 깜빡임 X)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 15:00:47 +09:00
chpark 5b457b8f0d feat(menu): 사이드 메뉴 API 에 권한그룹 필터 적용
Deploy momo-erp / deploy (push) Failing after 36s
- /api/menu: super admin 은 모든 메뉴, 일반 사용자는 authority_sub_menu 매핑된
  메뉴만 노출. 자식이 권한에 있으면 부모 메뉴도 자동 포함 (트리 유지)
- 권한 관리 화면에서 메뉴 체크 → 다음 로그인부터 사이드바 즉시 반영

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 14:54:15 +09:00
chpark a3ab0d7629 feat(admin/auth): 권한관리 통합 화면 — 권한그룹/직원/메뉴 동시 매핑
Deploy momo-erp / deploy (push) Failing after 37s
[권한그룹 사용자 추가 SQL 에러 fix]
- $3 파라미터에 ::text 명시 캐스트로 inconsistent types 해결
  ("inconsistent types deduced for parameter $3")

[새 UI - admin-panel/auth]
- 좌측: 권한 목록 + 검색 + 생성 (목록에서 클릭으로 활성화, 더블클릭으로 수정/삭제)
- 우중·우우: 권한있는/권한없는 직원 패널 (체크박스 + 전체선택 + 검색)
  · ‹ 추가  / 제거 › 버튼 즉시 반영
- 하단: 메뉴 전체 트리 (체크 즉시 서버 반영)
- 모달 헬퍼 안 띄우고 한 화면에서 모두 처리 → 사용 흐름 단순화

[새 스키마/API]
- db/migrations/020_authority_sub_menu.sql
- /api/admin/auth/menus  : 그룹의 메뉴 OBJID + 전체 메뉴 트리
- /api/admin/auth/menus/toggle : 단일 메뉴 ON/OFF

[거래명세표]
- 수량 컬럼 너비 w-14 → w-20 (모바일에서 잘리던 문제)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 14:36:16 +09:00
chpark 004a8e4a6b feat(dashboard): 카드 클릭 → 해당 리스트로 즉시 이동
Deploy momo-erp / deploy (push) Failing after 41s
- 관리자: 승인 대기 → /m/admin/orders?status=REQUESTED, 오늘/이번달 → /m/admin/orders,
  미수금 → /m/admin/payments
- 사용자: 대기중 → /m/orders?status=REQUESTED, 진행중 → ?status=APPROVED, 미수금/누적
  → /m/orders
- orders 페이지가 ?status= 쿼리로 초기 필터 자동 적용

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 14:15:38 +09:00
chpark 23599b9c18 fix(capture): Windows Chrome 에서 이미지 캡처 실패 — 외부 폰트 임베드 회피
Deploy momo-erp / deploy (push) Failing after 42s
- html-to-image 의 toPng 가 Pretendard CDN 임베드 단계에서 fail 하면 캡처 전체가
  깨짐 (Windows Chrome 에서 자주 발생). skipFonts + cacheBust + jpeg fallback 추가
- 거래명세표(orders) / 발주서(procurements) 양쪽이 같은 코드를 복붙으로 갖고 있던
  걸 lib/capture-share.ts 로 통합
- 실패 시 err.message 를 swal 에 노출 (이전엔 "잠시 후 다시 시도하세요" 만 떠서
  사용자가 원인 추적 불가)
- navigator.share 의 AbortError(사용자 취소) 는 silent 처리 + 그 외엔 다운로드 폴백

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 14:10:52 +09:00
chpark ffada52fd4 ci: deploy 단계를 build → down → up 패턴으로 (컨테이너 이름 충돌 방지)
Deploy momo-erp / deploy (push) Successful in 52s
5cbc324 배포 시 --force-recreate 가 이름 충돌(Conflict, 65adeb31db46_momo-erp)을
일으켜 컨테이너 swap 실패. 명시적으로 down --remove-orphans 후 up 으로 분리.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 13:45:48 +09:00
chpark 5cbc324627 fix(admin): 권한 멤버 추가 fail 표시 + 사이드바 중복 제거 + 로그인 ID/PW 저장
Deploy momo-erp / deploy (push) Successful in 51s
- 권한그룹 멤버 추가/제거 API: history insert 를 best-effort 로 분리해 메인 INSERT
  실패가 누적 에러로 noisy 응답에 담김. 클라이언트는 fail 분기에서 swal 로 사유 표시
- admin-panel 좌측 사이드바: '메뉴관리' 카테고리는 항상 고정 노출되므로 DB groups
  에서 같은 라벨이 다시 내려와도 중복 렌더링 안 함
- 로그인 화면: '아이디/비밀번호 저장' 체크박스 추가 (localStorage SAVE_KEY).
  체크 후 로그인 → 다음 방문 시 자동 채움. 해제하면 즉시 삭제

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 13:44:25 +09:00
chpark faf8315260 fix(admin-panel): useSearchParams 제거 + deploy 강건성 개선
Deploy momo-erp / deploy (push) Failing after 43s
- useSearchParams 가 Next.js 15 prerender 단계에서 Suspense 경계를 강제해
  /admin-panel 빌드 자체가 실패 → docker image 재빌드 안 됨 →
  컨테이너 swap 누락(2시간째 옛 이미지). window.location.search 직접 읽기로 대체
- deploy.yml: set +e 제거 (빌드 실패가 워크플로우 success 로 묻히는 문제 차단)
- docker compose 에 --force-recreate 추가 (이미지가 같아도 컨테이너 강제 재생성)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 13:33:40 +09:00
chpark 93f27d70f2 ci: 헬스체크를 build-sha.txt 일치 검증으로 강화
Deploy momo-erp / deploy (push) Failing after 14m15s
- 기존 마커(WORKFLOW/매입 발주/SCREEN PREVIEW)는 옛 빌드에도 들어있어
  배포가 실패해도 success로 묻혔음 (사용자: 사이드바 변경이 운영에 안 반영됨)
- SSH 단계에서 git rev-parse HEAD → public/build-sha.txt 에 기록 후 빌드
- 헬스체크가 운영의 /build-sha.txt 를 GITHUB_SHA 와 비교 → 불일치면 워크플로우 fail

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:31:05 +09:00
chpark 63cdc6cab9 feat(menu): 사용자/관리자 모드 사이드바 분리 + 거래명세표 즉시출고
Deploy momo-erp / deploy (push) Successful in 36s
- 사이드바: '거래처' 키워드 필터 제거. 사용자 모드 = DB 권한 메뉴 전체,
  관리자 모드 = 시스템 관리 가상 카테고리(사용자/권한/메뉴/공통코드/로그)
- admin-panel: ?tab= 쿼리로 진입 탭 결정. 좌상단 '← 사용자' 복귀 링크
- header: admin 자동 admin 모드 진입 제거 (기본 사용자 모드)
- 출고관리 거래명세표 미리보기: 엑셀 다운로드를 이미지 공유/인쇄 옆으로
  이동, 출고요청 상태일 때 [출고] 버튼 추가하여 체크 없이 바로 처리
- 발주서 미리보기: [인쇄] 버튼 추가

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:18:59 +09:00
chpark 6cfe0041a2 feat: 매입 발주서 납품조건 + 공급업체 샘플 + 관리자/사용자 모드 토글 + 모달 sticky
Deploy momo-erp / deploy (push) Successful in 53s
[DB 019]
- momo_procurements 에 delivery_place / delivery_period / payment_terms / freight_terms 컬럼 추가
- 기존 supply_mng (공급업체) 데이터 모두 삭제 + 샘플 10개 신규 등록
  · (주)아바텍, 대성식품, (주)고기파는농부, 광이진천 농장, 단과일,
    봉담수산, 명일동유기농, 울산단과일, 농부의아침, 초록마을 도매
- 시퀀스 가정 없이 MAX(objid)+1 로 안전하게 부여

[발주서 양식 — 표준 거래명세표 양식 반영]
- ProcurementForm: "2. 납품조건" 섹션 추가
  · 1)~3) 표준 조항 (납기 지연 공제 / 검수 부적합 반출 / 수량 규격 변경)
  · 4) 납품장소 5) 납품기간 6) 대금지불 7) 운임부담 — 표 형식 입력칸
  · 8)~9) 표준 조항 (3일 이의 제기 효력 / 명시되지 않은 사항)
  · 하단 "상기와 같이 발주함." + 발주일 + 발주자
- update-header API: 4개 필드 동적 업데이트
- /api/m/procurements/excel/[id]: 엑셀 출력에도 납품조건 9개 항목 + 4필드 표
- /api/m/procurements/send: 메일 본문 HTML 에도 납품조건 표 + 표준 조항

[관리자/사용자 모드 토글]
- 헤더 매뉴얼 옆에 [👥 사용자 / 🛡 관리자] 토글 버튼 (admin 권한자만 노출)
- menu-store: viewMode("user"|"admin") + setViewMode 추가
- 사이드바: viewMode 에 따라 대메뉴 필터링
  · 사용자 모드: '거래처 주문' 그룹만
  · 관리자 모드: 출고/정산 + 매입/입고 + 마스터 관리 + 통계
- admin 권한자 자동으로 로그인 시 관리자 모드 진입

[ItemPicker 모달 모바일 친화]
- 모바일에서 화면 하단 도킹(items-end) → 풀스크린 시트 처럼
- 헤더는 sticky top-0 으로 고정 → 긴 목록에서도 검색바 항상 보임

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 11:42:45 +09:00
chpark 91a7eecc61 feat: 로그인 계속 유지 + 거래명세표 양식 정교화 + 미수액·비고
Deploy momo-erp / deploy (push) Successful in 51s
[로그인 — 계속 유지]
- session.ts: REMEMBER 30일 → 10년 (사실상 영구)
- 로그인 폼 라벨: "로그인 유지 (30일)" → "로그인 계속 유지"
  · 한 번 로그인하면 계속 자동 로그인 (브라우저/쿠키 유지되는 한)

[거래명세표 양식 정교화 — 엑셀 + 메일 본문]
- 첨부 엑셀(buildStatementXlsx) + 메일 HTML(buildStatementHtml) 모두 양식 통일
- 사용자 이미지의 표준 거래명세표 양식 반영:
  · 좌상단: 일자 + 거래처(귀하) 박스
  · 우상단: 공급자 표 (결제계좌·전화·이메일 — 회색 헤더 + 세로 "공급자" 라벨)
  · "아래와 같이 계산합니다." 가운데 정렬
  · 합계 (VAT포함) + 미수액 강조 박스 (노란색)
  · 표: 순번/품명/구분/단위/수량/단가/공급가액/세액/합계(노란 강조)/비고
  · 거래처용이라 현재고는 처음부터 컬럼에 없음
  · 비고 컬럼에 라인별 remark 표시 (statement API 응답에 remark 추가)
  · 미수액 = total - paid_amount (입금 등록되면 자동 차감 반영)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 11:30:42 +09:00
chpark 3a0400a0c2 feat: 거래명세표 캡쳐 시 현재고 숨김 + 로그인 유지(30일) 체크박스
Deploy momo-erp / deploy (push) Successful in 53s
[현재고 — 캡처/공유 시에만 숨김]
- 거래처에 보낼 이미지에서 내부 정보(현재고)가 보이면 안 됨
- 거래명세표 표의 현재고 th/td 와 재고 부족 경고 박스에 .js-no-export 클래스 추가
- captureAndShare 안에서 toPng 직전 임시로 display:none → 캡처 후 복원
- 화면에서는 그대로 보이고, 다운받은 PNG/공유 이미지에서만 빠짐

[로그인 유지 — 30일 세션]
- /api/auth/login 요청 body 에 remember 추가
- /lib/session.ts createSession(user, remember=false) — 24시간(기본) / 30일(remember=true)
- 로그인 폼에 [✓ 로그인 유지 (30일)] 체크박스 (기본 ON, 나이 많은 사용자 친화)
- 체크 해제하면 24시간 세션 유지 (기존 동작)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 11:13:28 +09:00
chpark 3cbb28bbbd fix(반응형): 출고관리·매입발주·입고처리 모바일 스크롤 가로채기 해제
Deploy momo-erp / deploy (push) Successful in 53s
증상: 모바일에서 좌-우 분할 화면(출고관리 등) 의 페이지 스크롤이 안 됨.
원인:
- 컨테이너 minHeight: calc(100vh - 200px) 가 모바일에서도 적용 →
  좌·우 박스가 각각 거의 풀높이 차지
- 박스 내부의 overflow-auto 가 페이지 스크롤을 가로채 박스 안만 스크롤됨

수정:
- minHeight 인라인 스타일 → lg:min-h-[calc(100vh-200px)] 로 lg 이상에서만 적용
- 좌측 리스트 컨테이너: max-h-[60vh] lg:max-h-none 로 모바일에서 자연스러운 높이
- flex-1 overflow-auto → flex-1 lg:overflow-auto (모바일은 페이지 스크롤로 통일)
- 동일 패턴을 매입발주(/m/admin/procurements) + 입고처리(/m/admin/inbounds) 에도 적용

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 11:02:12 +09:00
chpark a5fd64da62 feat(출고요청): 카드 안에서 수량 입력/조절 + 카드/리스트 토글 + 거래명세표 라인 sync 버그 수정
Deploy momo-erp / deploy (push) Successful in 53s
[출고요청 화면 개선 — /m/orders/new]
- 카드에 [수량 입력 + 담기] 한 번에. 엔터 또는 버튼 클릭 시 그 수량만큼 카트에 추가
- 이미 담은 품목은 카드 안에 [- 1 +] 컨트롤 + [×] 빼기 버튼이 즉시 노출
  · 카트 수량 그 자리에서 직접 수정. 카드 외 카트 펼치기 불필요
- 담은 품목 카드는 emerald 테두리 + 우상단에 "담은 N" 배지로 강조

[보기 모드 토글]
- 검색바 우측에 [카드 / 리스트] 토글
- 카드: 기존 그리드 (이미지 위주, 시각적)
- 리스트: 표 형태 (품목 많을 때 한눈에) — 행마다 동일 [수량+담기] 컨트롤

[관리자 거래명세표 라인 sync 버그 fix]
- /m/admin/orders 에서 [+택배/+용차] 클릭 시 합계만 올라가고 인풋 표시값이 안 바뀌던 문제
- ExtraRow key 를 `OBJID-QTY-UNIT_PRICE-LABEL` 로 변경해 line 변경 시 컴포넌트 강제 재마운트
- useState 초기값이 새 line 값으로 확실히 반영됨

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 10:02:14 +09:00
chpark 2f4c5d5d02 feat(반응형): 입금/계산서/공급업체/창고/제조사/품목 — PC + 모바일 통일 UI
Deploy momo-erp / deploy (push) Successful in 51s
[패턴]
- 데스크탑(sm 이상): 표 + 가로 스크롤 (min-w 명시)
- 모바일(<640px): 카드 리스트 — 한 행을 그대로 카드 한 장으로
- 헤더: title + 부제 + 추가 버튼이 flex-wrap 으로 재배치
- 모달: max-w 유지 + 모바일에서 max-h-[90vh] overflow-y-auto

[페이지별 변경]
- /m/admin/payments: 요약 카드 3장 (전체/처리됨/미수금) + 표/카드 분기
- /m/admin/invoices: 선택건수+합계 부제 + 카드 리스트 + 표
- /m/admin/vendors: 카드 클릭 → 수정 모달 직행, 데스크탑 표 분리
- /m/admin/warehouses: 카드(아이콘+유형 배지)+표, 유형 색상 매핑
- /m/admin/makers: 검색바 폭 자동 + 카드(아이콘+버튼)+표
- /m/admin/items: 카드(이미지 썸네일+모든 배지) + 표, min-w 900px

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:34:19 +09:00
chpark 1502960151 feat(모바일 반응형): 사이드바 햄버거 오버레이 + 자동 닫기
Deploy momo-erp / deploy (push) Successful in 51s
증상: 모바일로 로그인 시 사이드바가 콘텐츠를 덮어 사용 불가능.
원인: 사이드바가 모든 폭에서 항상 정상 폭으로 자리잡음.

[레이아웃]
- 사이드바를 모바일에서 fixed + translate-x-full 로 화면 밖에 두고,
  mobileOpen=true 시 translate-x-0 슬라이드 인 (200ms transition)
- 모바일 오버레이 배경 클릭 시 닫기
- lg 이상에서는 기존대로 좌측 고정

[헤더]
- 모바일에서만 햄버거(≡) 버튼 노출 → setMobileOpen(true)
- 사용자명 모바일 width 줄이고 부서명 숨김 (110px → sm 이상 200px)

[사이드바]
- 헤더 우측에 모바일 전용 X 버튼 추가 (lg:hidden)
- 데스크탑 햄버거 토글은 hidden lg:flex 로 분리
- handleSubMenuClick 에서 setMobileOpen(false) 호출 → 메뉴 선택 시 자동 닫힘

[스토어]
- mobileOpen 상태 + setMobileOpen 액션 추가

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:23:27 +09:00
chpark f85b2f17e0 feat(header): 상단에 [📖 매뉴얼] 링크 추가
Deploy momo-erp / deploy (push) Successful in 56s
요구사항: 메인 화면 어디서든 사용 설명서로 빠르게 이동.
- 헤더 우측 (사용자명 옆) 에 BookOpen 아이콘 + "매뉴얼" 텍스트
- /manual.html 새 탭으로 열기 (target=_blank)
- 모바일에서는 텍스트 숨기고 아이콘만

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:09:02 +09:00
chpark 88e7eab65e feat(입고 처리): 매입발주 선택 → 라인별 창고/수량 입고 (부분/전체) + 매뉴얼 보강
Deploy momo-erp / deploy (push) Successful in 51s
[입고 처리 화면 재설계 — 등록 → 수정 방식]
- 좌-우 분할:
  · 좌: 매입 발주서 리스트 (발주요청+입고중 기본 필터)
  · 우: 발주 라인별 [창고 선택 + 정상 입고 + 불량] 인라인 입력
- 발주/입고/미입고 한눈에 표시 (예: 10 / 5 / 5)
- 완전 입고된 라인은 ✓ 완료 표시 + 입력 칸 잠김
- 정상+불량은 남은 수량(qty - received_qty) 이하로 자동 클램프

[/api/m/procurements/list]
- 응답에 TOTAL_QTY, RECEIVED_QTY 추가 → 좌측 리스트에 진척 표시

[/api/m/inbounds/save]
- procObjid 있으면 라인별 입고 한도 사전 검증 (qty - received_qty 초과 차단)
- 0 입고 라인은 건너뛰기
- 매입발주 상태 자동 갱신:
  · 모든 라인 완전 입고 → RECEIVED (입고완료)
  · 일부 라인만 입고 → PARTIAL (입고중)
  · 시작 안 함 → REQUESTED 유지

[매뉴얼 — 가-1, 가-2, 다-2 대폭 보강]
- 거래처 출고 요청: 6단계 체크리스트 + 화면 도식 + 토스트/모달 예시 + 시나리오
- 내 주문 내역 + 거래처 자기 주문 수량 수정/품목 삭제/취소: 화면 도식 + 단계별 가이드 + 상태표
- 입고 처리: 화면 도식 + 발주/입고/미입고 표시 의미 + 부분입고 시나리오

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:16:29 +09:00
chpark da9b16f012 fix(품목 추가 모달): 체크박스 선택 안되던 문제 + 손모양 커서
Deploy momo-erp / deploy (push) Successful in 52s
증상: 품목 추가 모달에서 행 클릭과 체크박스 클릭 둘 다 toggle 호출 →
       두 번 발생해서 체크 상태가 변하지 않음.
수정:
- 체크박스 td 에 stopPropagation 추가 (행 onClick 으로 버블되지 않게)
- 행 클릭은 그대로 행 전체 토글로 동작
- 체크박스 명시 cursor:pointer + 크기 18px + 색상 accent-emerald-600
- select-none 추가 (드래그 시 글자 선택 방지)
- 헤더 전체선택 체크박스도 동일 처리

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:07:34 +09:00
chpark 03838af90c feat(거래처 출고이력): 본인이 출고요청 상태 품목 수량/삭제 직접 수정
Deploy momo-erp / deploy (push) Successful in 51s
[새 API: /api/m/orders/items/update]
- 본인 또는 관리자가 자기 발주의 품목(ITEM) 라인 수량 변경 또는 삭제
- REQUESTED 상태에서만 허용. 단가는 변경 불가 (momo_items.unit_price 기준 자동 재계산)
- 재고 / max_order_qty 한도 자동 검증 (unlimited_qty 권한이면 한도 우회)
- 트랜잭션으로 라인 수정 + momo_orders 합계 7종 자동 재집계

[/m/orders 거래명세표 모달 UI]
- 출고요청 상태 거래처 본인 화면에서 품목 라인 직접 편집:
  · 수량 인풋 (블러 시 자동 저장)
  · 행 끝의 [×] 버튼으로 그 품목만 삭제
- 택배/용차 라인은 인풋 안 보이고 "자동" 표시 — 모모 담당자가 조정
- 저장/삭제 후 onReload 로 모달 + 리스트 동시 갱신
- 안내 배너: "수량 수정 / 품목 삭제 / 주문 취소" 모두 가능 명시

[매뉴얼]
- 가-2 내 발주 이력 섹션에 수량 수정 / 품목 삭제 / 주문 취소 사용법 추가

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 00:38:23 +09:00
chpark e86017c42a feat(통계+세금계산서): 거래처×일자 피벗 통계 신설 + 중복 발행 차단
Deploy momo-erp / deploy (push) Successful in 53s
[새 통계 — 거래처×일자 매출 피벗]
- API: POST /api/m/statistics/monthly-pivot
  · 입력: { year, month }
  · 응답: dates[] / rows[ {거래처, BY_DAY:{날짜:{면세,과세}}, TOTAL_TAXFREE/TAXABLE} ] / totalsByDay / grandTotal
  · 출고완료/입금완료/계산서발행 상태 발주만 집계
- 화면: /m/admin/statistics/pivot
  · 가로 스크롤 피벗 표 (왼쪽 sticky 업체명)
  · TOT 행: 월간 일자별 총합 (부가세 신고용)
  · 거래처별 정렬: 매출 큰 순
  · 합계 카드 3종: 면세/과세/총
  · 엑셀 다운로드 (거래처 행 × 일자 컬럼 평면화)
- 메뉴 등록: 018 마이그레이션 (objid 9000504, 통계 그룹)

[세금계산서 중복 발행 차단]
- /api/m/einvoices/issue: orderObjid 가 이미 발행됨(FAIL/CANCELED 제외) 이면 400
  · "이미 발행된 발주입니다 (상태/승인번호)" 메시지 + alreadyIssued=true 플래그
- /m/admin/einvoices: 발행 가능 발주 리스트에서 이미 발행된 건 자동 제외
  · orders/list 와 einvoices/list 동시 조회 후 클라이언트 측 필터
  · DRAFT/QUEUED/SENT/ACK 모두 발행 완료로 간주 — 재발행 불가
  · FAIL/CANCELED 만 다시 발행 가능

[매뉴얼]
- 통계 표에 "거래처×일자 매출 (피벗)" 항목 추가, 부가세 신고 자료 활용 안내

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 23:51:05 +09:00
chpark b95ac11015 fix(items/list): 마이그레이션 미적용 환경에서도 동작하도록 컬럼 자동 보장
Deploy momo-erp / deploy (push) Successful in 51s
증상: 마스터 품목 관리 화면에 품목이 하나도 안 보임.
원인: 마이그레이션 016 (vendor_objid) 이 운영 DB 에 적용 안 된 상태에서
       SELECT I.vendor_objid 가 'column does not exist' 로 실패 → 빈 배열 응답.

해결: API 첫 호출 시 ALTER TABLE ... ADD COLUMN IF NOT EXISTS 로
       vendor_objid + max_order_qty + is_hidden + requires_delivery 모두 자동 보장.
       idempotent 하므로 이미 적용된 환경에서도 NOOP.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 23:24:58 +09:00
chpark 58645a0b3f feat(매입 발주): 엑셀 다운로드 + 이미지 공유 + 품목조회 JOIN 캐스팅 수정
Deploy momo-erp / deploy (push) Successful in 53s
[발주서 엑셀 다운로드]
- /api/m/procurements/excel/[id] 신설
- 이미지의 표준 발주서 양식대로 .xlsx 생성
  · 분류번호/발주서번호/발주일/공급업체/연락처/이메일
  · 1.물품의 표시 (품목코드·품명·단위·수량·단가·금액)
  · 총액 + V.A.T 별도
  · 2.비고 + 발주자 정보

[발주서 이미지 공유]
- 매입 발주서 양식 우상단에 [📤 이미지 공유] [⬇ 엑셀 다운로드] 버튼
- html-to-image 로 PNG 캡처 → Web Share API (카톡 등) 또는 PNG 다운로드
- 거래명세표(출고/정산)와 동일한 사용자 경험

[버그 수정 — 품목 모달에 결과 안 나옴]
- /api/m/items/list 의 supply_mng JOIN 캐스팅 누락
  · momo_items.vendor_objid (TEXT) vs supply_mng.objid (NUMERIC) 타입 충돌로 SQL 에러 → 빈 배열 응답
- LEFT JOIN supply_mng V ON I.vendor_objid = V.objid::text 로 명시적 캐스팅

[매뉴얼]
- 매입 발주 섹션에 "발주서 공유 / 엑셀 다운로드" 안내 추가

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 23:23:21 +09:00
chpark 6b60178b1d feat(v0.7 round2): 매입 발주서 양식 + 좌-우 분할 + 공급업체 일괄 불러오기
Deploy momo-erp / deploy (push) Successful in 51s
[화면 — /m/admin/procurements 전면 개편]
- 좌측: 발주서 리스트 (상태 필터, 발주번호, 공급업체, 금액)
- 우측: 발주서 양식 (이미지의 표준 발주서 형태)
  · 분류번호/발주서번호/발주일/공급업체 표
  · "1. 물품의 표시" 표 (품명·단위·수량·단가·금액)
  · "2. 비고" 텍스트 영역
  · 합계 자동 계산
- [+ 새 발주] / [발주 요청] 상단 버튼
- 작성중(OPEN) 상태에서만 인라인 편집 가능, 발주요청 후 잠김

[품목 추가 모달]
- 검색 + [공급업체 필터(현재/전체)] + [결과 내 검색]
- 다중 선택 + 헤더 체크박스로 전체 선택
- 이미 담긴 품목은 '이미' 표시
- 한 번에 N개 일괄 추가 (수량 1, 원가는 품목 마스터의 cost_price)

[API 4종 신설]
- POST /api/m/procurements/create-empty: 빈 발주서 1건 생성 (proc_no 자동 부여, status=OPEN)
- POST /api/m/procurements/lines/save: 라인 추가/수정/삭제 + 합계 재집계 (트랜잭션)
  · 같은 품목 중복 추가 시 수량 누적
- POST /api/m/procurements/update-header: 공급업체/메모 수정
- POST /api/m/procurements/send: 발주 요청 — status OPEN→REQUESTED + 공급업체 이메일로 발주서 HTML 메일 발송
  · 메일 실패해도 상태는 변경 (mailSent/mailError 응답)

[매뉴얼]
- 다-1 매입 발주 단계별 가이드 재작성
- "공급업체별 품목 일괄 불러오기" 팁 추가

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 22:26:21 +09:00
chpark 99565bf6e0 feat(v0.7 round1): 공급업체 명칭 변경 + 품목-공급업체 연결 + 거래처 출고이력 거래명세표 모달
Deploy momo-erp / deploy (push) Successful in 55s
[DB]
- 016: momo_items.vendor_objid 추가, momo_vendors 컬럼 보강 (email/address/memo/regdate)
- 017: 메뉴 9000202 "매입처 관리" → "공급업체 관리"

[명칭 일괄 변경]
- src/app/api/m/vendors/* + (main)/m/admin/vendors/* + procurements/* + inbounds/*
- 모든 UI/메시지의 '매입처' → '공급업체'

[품목 ↔ 공급업체 연결]
- /api/m/items/list 응답에 VENDOR_OBJID/VENDOR_NAME 추가, vendorObjid 필터 지원
- /api/m/items/save: vendorObjid 입력/저장 (insert + update)
- 품목 등록·수정 폼에 [공급업체] 드롭다운 신설 (제조사 옆)

[/m/orders 거래처 출고 이력 화면 — 모달 + 이미지 공유]
- 행 클릭 / [보기] 버튼 → 거래명세표 모달
- 모달 안에 [📤 이미지 공유] [⬇ 엑셀 다운로드] 버튼 (출고/정산 화면과 동일)
- 출고요청 상태이면 [🗑 주문 취소] 버튼 노출 → /api/m/orders/cancel
- html-to-image 로 PNG 캡처 → Web Share API 또는 다운로드

[매뉴얼]
- 공급업체 명칭 반영, 출고이력 거래명세표 보기 동작 추가, 품목 폼에 공급업체 필드 설명 추가

Round 2 예정: 매입 발주 양식 (좌측 리스트 + 우측 발주서 + 품목 검색/공급업체 일괄 불러오기) + 매뉴얼 보강

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 22:19:08 +09:00