Commit Graph

147 Commits

Author SHA1 Message Date
chpark 29852110dc chore(admin): 공통코드 관리 메뉴/UI/API 일괄 제거
Deploy momo-erp / deploy (push) Successful in 2m52s
momo 영역에서 미사용. FITO 레거시 잔존 코드 정리:
- sidebar.tsx: __sys_code 가상 메뉴 항목 제거
- admin-panel/page.tsx: code 탭/메뉴/CodeManagement 함수 삭제
- admin-panel/code-form/: 폼 페이지 디렉토리 통째로 삭제
- api/admin/codes/: list/detail/save 라우트 통째로 삭제

/api/common/code-list (조회 전용) 는 product/part-change 등이
드롭다운 로드용으로 쓰고 있어 보존.
2026-05-13 16:29:48 +09:00
chpark 5778b845d1 fix(orders): 현재고 0 표시 버그 + 거래명세표 레이아웃 정리
Deploy momo-erp / deploy (push) Successful in 3m13s
- 마이그레이션 029 후 wh_type 이 새 enum(HQ_STOCK/KIMPO_STOCK 등)
  으로 바뀌면서 detail/approve 의 wh_type='STOCK' 필터가 매칭 안 됨
  → 거래명세표 현재고가 전부 0 으로 표시됨 (재고 부족 N건 오탐).
- detail: 거래처 default_wh_objid 우선 + IN ('STOCK','HQ_STOCK','KIMPO_STOCK') 폴백
- approve: fallback 창고 lookup 도 동일하게 IN 절 확장
- 거래명세표 헤더 레이아웃: grid-cols-1 sm:grid-cols-2 → flex justify-between
  으로 변경, 발주번호 라인과 공급자 박스가 항상 가로 배치(공급자 오른쪽 정렬)
- 거래명세표에서 '+ 택배 추가 / + 용차 추가' 버튼 제거 (요청)
2026-05-13 16:26:01 +09:00
chpark 0c380d94a0 feat(warehouses 029): 창고 7개로 정비 — 기존 5개 라벨/타입 갱신 + 김포 용차/시장 2개 신규
Deploy momo-erp / deploy (push) Successful in 2m15s
기존 5개 (objid/wh_code 그대로 유지 — 재고 이동·입출고 데이터 보존):
- WH001 본사창고 → 본사 창고 (HQ_STOCK)
- WH002 시장픽업 → 본사 시장 (HQ_MARKET)
- WH003 용차배송 → 본사 용차 (HQ_CHARTER)
- WH004 창고픽업팀 → 김포지사 (KIMPO_BRANCH)
- WH005 김포창고 → 김포 창고 (KIMPO_STOCK)

신규 2개 (idempotent INSERT):
- WH006 김포 용차 (KIMPO_CHARTER)
- WH007 김포 시장 (KIMPO_MARKET)

총 7개. 사용자 요청한 본사 3 + 김포 4 구성 정확히 맞춤.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 16:08:45 +09:00
chpark 2b3c4acdae fix(deploy): momo-erp 재기동 후 traefik 라우터 캐시 자동 새로고침
Deploy momo-erp / deploy (push) Successful in 2m15s
증상: momo-erp container 가 force-recreate 될 때 traefik docker provider 가
새 컨테이너의 라벨을 재인식 못 해 momotogether.com 요청이 Gitea 라우터로
fallback 되는 사고 (사용자 화면에 Gitea 500 에러 페이지 노출).

deploy.yml 의 docker compose up 직후 `docker restart traefik` 1회 추가.
1~2초 다른 도메인 잠시 down 되지만 라우터 정합성 보장됨.

병행: cron watchdog (/usr/local/bin/momo-traefik-watchdog.sh, 3분 간격)이
production HTML 의 "모모유통" 문자열 검증해 비정상 시 traefik 자동 재시작.
deploy 외 임의 시점 사고에도 최대 3분 안에 자동 복구.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 15:59:56 +09:00
chpark 19e3cf9048 feat(statement-branch-admin): 기준 명세표 관리 메뉴/페이지/API + 창고 카테고리 7개로 확장
Deploy momo-erp / deploy (push) Successful in 3m5s
마이그레이션 028:
- momo_statement_branches 테이블 신설 (code PK / name / bank_account / phone / email 등)
- HQ, KIMPO 기본 시드 INSERT (사용자가 관리자 페이지에서 편집 가능)
- 메뉴: 시스템 그룹에 '기준 명세표 관리' (M_ASBR / menu_info 9000310)

라이브러리 (src/lib/momo-branches.ts):
- 하드코딩 → DB 조회로 변경 (60초 in-memory 캐시)
- getSupplierByBranch 가 async — detail/statement/approve API 도 await 추가
- 저장 시 invalidateBranchCache() 호출

페이지/API (관리자 전용):
- /m/admin/statement-branches : list + 등록/수정/삭제 모달
- POST /api/m/admin/statement-branches/list
- POST /api/m/admin/statement-branches/save (regist / update / delete)

사용자 수정 폼:
- "기준 거래명세서" select 옵션이 하드코딩 본사/김포 → DB 의 branches list 동적 fetch

창고 관리:
- WH_TYPE 카테고리 5개 → 7개 (옛 enum 도 라벨 매핑은 유지)
  · HQ_STOCK 본사 창고
  · HQ_CHARTER 본사 용차
  · HQ_MARKET 본사 시장
  · KIMPO_BRANCH 김포지사
  · KIMPO_STOCK 김포 창고
  · KIMPO_CHARTER 김포 용차
  · KIMPO_MARKET 김포 시장
- 신규 추가 시 select 는 위 7개만 노출, 기존 데이터 (STOCK 등) 는 라벨로 자연 표시

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 15:48:08 +09:00
chpark 6ad57356a0 feat(statement-branch): 사용자별 거래명세서 공급자 정보 분기 (본사/김포)
Deploy momo-erp / deploy (push) Successful in 1m59s
마이그레이션 027:
- user_info 에 statement_branch VARCHAR(10) DEFAULT 'HQ' 컬럼 추가
- 기존 사용자 일괄 'HQ' 로 채움

라이브러리:
- src/lib/momo-branches.ts 신설 — HQ / KIMPO 두 branch 의 공급자 정보 정의
  · HQ: 기업은행 434-115361-01-016 (이상용) / 010-6369-8443 / momo8443@daum.net
  · KIMPO: 농협 351-1383-7634-13 (모모유통) / 010-5789-9431 / momokimpo@nate.com
- getSupplierByBranch(branch) helper

거래명세표 supplier 분기 (3개 API):
- /api/m/orders/detail: order.STATEMENT_BRANCH 따라 supplier 객체 결정
- /api/m/orders/statement/[id]: xlsx 다운로드도 동일
- /api/m/orders/approve: 메일 발송 stmt 도 동일

사용자 수정 폼:
- /api/admin/users/detail: statement_branch 반환 (default 'HQ')
- /api/admin/users/save: statement_branch 받아 UPDATE
- /admin-panel/user-form: "기준 거래명세서" select 추가 (본사/김포)

흐름: 거래처 사용자의 기준을 김포로 설정 → 그 사용자의 발주에 대한 거래명세표 supplier 가 김포 정보로 표시

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 15:29:02 +09:00
chpark 75f37d8eaf feat(filters+warehouse): 매입발주/입금관리 조건 한 줄 + 공급업체 SearchableSelect + 김포 창고 카테고리 추가
Deploy momo-erp / deploy (push) Successful in 2m8s
1) 매입 발주서 관리(/m/admin/procurements):
   - 조회조건 flex-wrap → flex-nowrap + overflow-x-auto (모바일 한 줄, 가로 스크롤)
   - 공급업체 select → SearchableSelect (타이핑으로 결과 내 검색)
   - 폰트/높이 축소 (h-9 → h-8, text-sm → text-xs)
2) 매입 입금관리(/m/admin/proc-payments): 동일 한 줄 정비
3) 창고 관리(/m/admin/warehouses):
   - WH_TYPE 에 KIMPO "김포 창고" 카테고리 추가 + 라벨/배지색 등록
   - 신규 창고 추가 시 select 옵션에 자동 노출

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:55:23 +09:00
chpark ec2e79d517 feat(filters): 매입발주·내발주이력·출고처리 조회조건 정비
Deploy momo-erp / deploy (push) Successful in 2m12s
- 매입 발주 관리(/m/admin/procurements):
  · 날짜 from~to + 공급업체 select 추가 (기본: 오늘 - 30일 ~ 오늘)
  · 조회 버튼 제거 — state 변경 시 자동 fetch
- 내 발주 이력(/m/orders):
  · 날짜 기본값을 오늘 - 30일 ~ 오늘로 설정 (URL 파라미터 우선 적용)
- 출고 처리(/m/admin/orders) 검색바:
  · 모바일에서 label 풀어진 5단 grid → 한 줄 flex-wrap 으로 압축 (h-8 + text-xs)
  · 모바일 폼이 화면을 너무 차지하던 문제 해소

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:42:39 +09:00
chpark 6b401071a4 fix(migration 026): menu_info 에 unique constraint 없어 ON CONFLICT 실패 → WHERE NOT EXISTS + UPDATE 분리
Deploy momo-erp / deploy (push) Successful in 2m10s
지난 commit 의 026 이 ON CONFLICT(objid) 로 INSERT 시도 → menu_info 에 PK/unique 없어 PG 에러.
패턴: INSERT WHERE NOT EXISTS + 그 다음 별도 UPDATE WHERE objid=... 로 idempotent 처리.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:25:48 +09:00
chpark 7d18285ac6 feat(menu+filter+history): 사이드바 메뉴 노출 + 자동조회 + 재고이력 한글/이동 상대창고 표시
Deploy momo-erp / deploy (push) Successful in 2m53s
1) 사이드바 메뉴 누락 fix (마이그레이션 026):
   - FITO menu_info 테이블에 9000304 '매입 입금관리', 9000305 '재고이력' INSERT
   - 기존 입고/재고 seq 재정렬 (11→12, 12→13)
   - momo_menus 만으로는 사이드바에 안 나옴 — menu_info 가 사이드바의 진짜 소스

2) 재고이력 표시 개선:
   - inventory/history API: REF_TYPE_LABEL (한글) + COUNTER_WH_NAME (이동 시 상대 창고) 추가
   - inventory/transfer 라우트: stock_moves 의 ref_objid 에 상대 창고 objid 박음
   - StockHistoryModal + history page: "INBOUND" → "입고", TRANSFER 시 "→ XX창고/← XX창고" 표시

3) 자동조회 (조회 버튼 없이 즉시):
   - m/orders (내발주이력): 날짜 from~to + 상태 input 추가 + state dep useEffect
   - m/orders/new (출고요청): "재고있는 품목만 / 전체 품목" 필터 추가 + 250ms 디바운스 자동 fetch

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:22:28 +09:00
chpark bf2339c242 feat(inbound+inventory): 입고는 입금완료(PAID) 만 + 재고이력 메뉴/모달
Deploy momo-erp / deploy (push) Successful in 2m17s
1) 입고 처리 (m/admin/inbounds):
   - 노출 대상: REQUESTED+PARTIAL → PAID+PARTIAL 로 변경 (입금 안 된 발주는 입고 불가)
   - editable 조건 / STATUS 라벨/색상 PAID 추가
   - 안내 문구 갱신

2) 재고이력 메뉴 (마이그레이션 025):
   - M_AINVH '재고이력' 메뉴 매입 그룹 sort 34 에 INSERT (페이지는 기존 /m/admin/inventory/history 활용)

3) 재고관리 페이지 (m/admin/inventory):
   - 데스크탑 표/모바일 카드 모두 행마다 "이력" 버튼 추가
   - 클릭 시 StockHistoryModal 팝업 — 해당 품목 + 해당 창고 한정 이력 조회 (POST /api/m/inventory/history)

매입 흐름 완성: 매입발주(REQUESTED) → 입금관리(PAID) → 입고처리(RECEIVED)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:03:29 +09:00
chpark b781722614 feat(proc-payment): 매입 입금관리 메뉴/페이지/API 신설
Deploy momo-erp / deploy (push) Successful in 2m9s
매입 흐름: 매입발주(REQUESTED) → 매입 입금관리(PAID) → 입고 처리(RECEIVED)

DB (마이그레이션 024):
- momo_procurements 에 paid_date, paid_amount, paid_method, paid_memo 컬럼 추가
- 매입 그룹 메뉴 sort 재정렬: 매입발주 30, 입금관리(신설) 31, 입고처리 32, 재고관리 33
- M_APROCPAY '매입 입금관리' /m/admin/proc-payments 메뉴 INSERT (ON CONFLICT idempotent)

UI/API:
- /m/admin/proc-payments 페이지 — 발주요청/입금완료 분리 카드 + 입금 처리 모달 (금액/방법/메모)
- 조회조건: 날짜 from~to + 공급업체 + 상태 (즉시 반영)
- POST /api/m/admin/proc-payments/list — REQUESTED|PAID 만 노출
- POST /api/m/admin/proc-payments/confirm — REQUESTED → PAID 전환 + paid_* 채움

다음 단계 (별도 batch): 입고 처리 페이지에서 PAID 만 노출 + 입고 시 RECEIVED 전환

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 12:30:31 +09:00
chpark 9293029631 chore: 제조사 관리 메뉴/페이지/API 삭제 + 엑셀 공급업체 80개 일괄 등록
Deploy momo-erp / deploy (push) Successful in 2m0s
1) 삭제:
   - src/app/(main)/m/admin/makers/page.tsx
   - src/app/api/m/makers/{list,save,delete}/route.ts
   (메뉴 DB 의 제조사 항목은 이전 commit 9705a04 에서 이미 제거됨)

2) 마이그레이션 023:
   - docs/모모유통 제조사 리스트(26.05.12).xlsx 의 80개 업체를 supply_mng 에 일괄 등록
   - idempotent: supply_name 중복 시 SKIP (NOT EXISTS)
   - supply_code: MM-NNNN 자동 채번 (기존 max(objid) + ROW_NUMBER)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 12:13:19 +09:00
chpark b8d0200831 fix(orders): 내발주이력 "동작" 컬럼 제거 — 행 클릭으로 상세 모달 열도록 통일
Deploy momo-erp / deploy (push) Successful in 2m4s
기존: 마지막 컬럼에 "보기" 버튼 + tr onClick 둘 다 있어 중복
변경: 동작 컬럼 + 보기 버튼 제거. tr 자체 클릭 시 상세 모달 (openDetail) 호출 — 이미 onClick 박혀있어 동작 동일.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 12:05:54 +09:00
chpark 7151a401d4 fix(orders): 일반 사용자 권한 매칭 (objid + userId) + 출고요청 리스트 가로스크롤 제거
Deploy momo-erp / deploy (push) Successful in 2m56s
권한 fix — order.customer_objid 와 매칭 시:
- 기존: user.objid 만 비교 → FITO 사용자(objid 없음)는 항상 fail → "권한 없음"
- 변경: user.objid ?? user.userId 와 customer_objid 매칭, 또는 user.userId 와 직접 매칭
- 적용: items/update, lines/save, cancel, statement, items/remark (5개 API)

출고요청 리스트(m/orders/new) UI:
- table 의 min-w-[640px] 제거 + table-fixed 적용
- 수량 컬럼 폭 180px → 112px, "담기" 버튼 텍스트 제거 (+ 아이콘만)
- 폰트 11~12px 로 축소
- 모바일 화면 한 줄에 들어오도록

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 11:49:26 +09:00
chpark a8049f57a6 feat(invoices): 계산서 발행 페이지 종합 개선 + deploy.yml 충돌 우회
Deploy momo-erp / deploy (push) Failing after 4m37s
invoices(계산서 발행) page:
- 조회조건 추가: 거래처(SearchableSelect) / 날짜 from~to / 상태
- 조회 버튼 제거 — 입력하면 즉시 클라이언트사이드 필터 적용
- "조회 결과 합계" 카드: 면세 / 과세(공급+세액) / 합계 분리 표시
- "선택 합산" 카드: 체크박스로 고른 건들의 면세/과세/합계 실시간 합산
- 표 행마다 면세/과세 컬럼 추가
- 전체 선택 체크박스 (헤더)

deploy.yml:
- docker compose up 흐름 강화: down --remove-orphans 후 docker rm -f momo-erp 로 잔존 컨테이너 강제 제거 + --force-recreate
- 수동 SSH 배포 + 자동 배포 겹쳤을 때 "container name already in use" 충돌 자동 해소

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 11:40:19 +09:00
chpark 80d2240a23 feat(items+einvoices): 품목 상태값 제거 + 공급업체/거래처 조회조건 + 합계 면세/과세 분리
Deploy momo-erp / deploy (push) Failing after 2m35s
- 품목관리(items):
  · STATUS 컬럼 표시/필터/폼에서 제거 (전부 ACTIVE 가 default — 사용자 사용 안 함)
  · 조회조건에 공급업체 SearchableSelect 추가 (이미 백엔드 vendorObjid 지원)
- 계산서 발행(einvoices):
  · 조회조건에 거래처 SearchableSelect 추가 (customers list API 사용)
  · 페이지 하단 tfoot 에 면세 합계 / 과세 합계 / 총 합계 분리 표시

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 11:29:55 +09:00
chpark 9cd9e5c0fd fix(orders): 거래명세표 캡처 레이아웃 다듬기
Deploy momo-erp / deploy (push) Successful in 2m47s
- 결제 계좌번호 셀: <br/> 줄바꿈 제거 + whitespace-nowrap + width 110px 로 한 줄 표시
- 총 합계 (VAT포함) 셀: whitespace-nowrap + 폰트 11px 로 좁은 셀에서도 한 줄
- 거래처 이메일(귀하 아래 라인) 표시 제거 — 외부 공유용 이미지에 사용자 이메일 노출 불필요

m/admin/orders 와 m/orders 두 곳 동일 적용.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 11:21:28 +09:00
chpark 083188332c feat(orders): 관리자가 출고완료(SHIPPED) 건도 수정 가능하도록 권한 확장
Deploy momo-erp / deploy (push) Successful in 5m18s
기존: REQUESTED 상태만 수정 가능 (admin/user 동일)
변경:
- USER: REQUESTED 만 (기존 그대로)
- ADMIN: PAID/CANCELED 가 아니면 모두 (REQUESTED / SHIPPED 등 입금완료 전까지)

items/update, lines/save 두 API 동일 적용. 입금완료(PAID) 이후나 취소건은 admin 도 수정 불가.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 11:08:02 +09:00
chpark 91ab88a359 fix(orders): 이미지 공유 버튼을 admin 만 노출하도록 보수적으로 변경
Deploy momo-erp / deploy (push) Successful in 2m47s
기존: user.role === "USER" 일 때 숨김 → 거래처라도 role 필드 비어있으면 노출되는 버그
변경: user.isAdmin === true || role === "ADMIN" 일 때만 노출 → 그 외는 모두 숨김
admin 계정만 거래명세표 이미지 공유 가능.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 00:49:08 +09:00
chpark bfb9470c85 fix(mobile): 뒤로가기 토스트가 페이지 이동 후에도 작동하도록
Deploy momo-erp / deploy (push) Successful in 2m59s
기존: mount 시 한 번만 history sentinel push → 사용자가 navigation 하면 sentinel 잃어버려 토스트 안 뜸.
변경: usePathname 의존성 useEffect → pathname 변경마다 sentinel 새로 push. lastBackRef 도 ref 로 변경(렌더 의존성 없이 상태 유지).
+ swal toast z-index 9999 강제 (다른 모달 위)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 00:45:14 +09:00
chpark 1e0a2640e9 feat(mobile): 로그아웃 모바일 분기 + 뒤로가기 토스트 활성화 조건 완화
Deploy momo-erp / deploy (push) Failing after 3s
- middleware: User-Agent 가 모바일이면 /login → /m/login 으로 redirect (서버 측 분기)
- auth-store.logout: window 가 모바일이면 /m/login, 아니면 /login (클라이언트 측 분기)
- BackButtonGuard: TWA 일부 환경에서 display-mode 가 standalone 으로 보고되지 않는 케이스 대응 — fullscreen/minimal-ui 도 포함, 모바일 UA 면 무조건 활성화

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 00:34:26 +09:00
chpark 0e9378a638 feat(orders): 사용자(USER)의 내출고이력에서 이미지 공유 버튼 숨김
Deploy momo-erp / deploy (push) Failing after 4s
m/orders 페이지의 거래명세표 DetailModal 에서 "이미지 공유" 버튼이 모든 사용자에게 노출되던 문제.
useAuthStore 의 user.role === "USER" 이면 버튼 hide. ADMIN 은 그대로 표시.

엑셀 다운로드 버튼은 그대로 유지 (사용자가 자기 주문 명세는 엑셀로 받을 수 있음).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 00:26:26 +09:00
chpark d8d508a78f feat(mobile): 로그인 스플래시 표시 시간 1.5초 → 3초로 늘림
Deploy momo-erp / deploy (push) Failing after 4m23s
사용자 요청으로 모모 로고 splash 가 더 충분히 보이도록 setTimeout 값 변경.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 00:04:25 +09:00
chpark 1039a11bbf feat(mobile): 안드로이드 뒤로가기 이중확인 + 모바일 로그인 스플래시
- src/components/back-button-guard.tsx 신규: standalone(PWA/TWA) 모드에서만 작동
  · 첫 뒤로가기 → sweetalert2 toast("한 번 더 누르면 앱이 종료됩니다") 표시
  · 2초 안에 두 번째 뒤로가기 → history.back() 으로 native back 위임 → 앱 종료
  · 일반 브라우저(non-standalone) 사용자에게는 영향 없음
- src/app/layout.tsx 의 RootLayout 에 BackButtonGuard 마운트
- src/app/(auth)/m/login/page.tsx 에 1.5초 스플래시 overlay 추가
  · 모모 로고 + "모모유통 ERP" + spinner ("로딩 중...")
  · z-60 fixed inset-0, 1.5s 후 opacity fade-out

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 23:47:35 +09:00
chpark 550fb12913 feat(capture): 거래명세표/매입발주서 이미지 공유 가로 출력
- src/lib/capture-share.ts 에 forceWidth 옵션 추가 → 캡처 직전 임시로 node width 강제 + 즉시 원복
- 출고 처리(거래명세표) 와 매입발주서 관리의 이미지 공유 호출에 forceWidth: 1100 적용
- 모바일 화면(좁은 viewport)에서 좁아진 표/품명 셀이 한 줄로 펼쳐져 엑셀 가로 출력처럼 캡처됨
- m/orders 페이지의 inline captureAndShare 를 capture-share lib 으로 통일 (toJpeg fallback / AbortError 처리 공유)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 23:44:37 +09:00
chpark 20e6255aa3 feat(auth): 모바일 전용 로그인 페이지 추가 (/m/login)
- src/app/(auth)/m/login/page.tsx 신규 — 한 화면에 딱 맞는 모바일 layout (logo + form + 푸터, safe-area inset 적용)
- middleware.ts publicPaths 에 /m/login + PWA 자원(/manifest.json, /sw.js, /.well-known) 추가
- 세션 있는 상태로 /m/login 진입 시 /m/dashboard 로 자동 redirect
- manifest.json 의 start_url 을 /m/login 으로 변경 → TWA APK 가 앱 실행 시 바로 로그인 화면

로그인 성공 시 /m/dashboard 로 이동 (기존 /login 은 API 응답의 redirectTo 사용, 모바일은 hardcode).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 23:44:37 +09:00
chpark 451117cfbe chore(pwa): assetlinks.json 에 APK 서명 SHA-256 fingerprint 박음
v1.0.0 APK (com.momotogether.erp) 의 서명 인증서 SHA-256 을 Digital Asset Links 에 등록.
이 commit 이 production 에 배포되면 TWA 앱이 URL bar 없이 풀스크린으로 동작.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 23:35:53 +09:00
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