Commit Graph

184 Commits

Author SHA1 Message Date
chpark fac0f0d83e feat(orders): admin 출고관리 인라인 수기 발주 + 품목 추가 + 거래처 변경
Deploy momo-erp / deploy (push) Successful in 2m19s
매입 발주서 작성 패턴처럼 출고관리 안에서 직접 빈 발주 → 거래처 → 품목 채워가는 흐름.

신규 API:
- /api/m/orders/create-empty (admin) — 빈 발주 INSERT
  · status='REQUESTED', customer 임시 admin, HQ 기본 supplier snapshot
- /api/m/orders/update-customer (admin) — 발주의 거래처 변경
  · 변경 시 새 거래처 statement_branch 기반 supplier snapshot 재계산
  · REQUESTED/APPROVED 만 변경 허용 (입금 후 잠금)

UI (/m/admin/orders):
- '수기 발주' 버튼 → 즉시 create-empty 호출 → 리스트 새로고침 + 새 row
  자동 활성화 (모달/redirect 제거)
- detail 의 거래명세서 안 '귀하' 줄 → editable 시 CustomerEditor (select)
- 액션바에 '+ 품목 추가' 버튼 → AdminItemPickerModal (재고 있는 품목 검색)
  · items/add API 호출, ITEM 라인 일괄 INSERT
2026-05-14 22:07:45 +09:00
chpark 527cfddc1b feat(stock): 창고별 재고 현황 메뉴 (출고/정산 > 창고별 재고 현황)
Deploy momo-erp / deploy (push) Successful in 2m7s
매트릭스 뷰 — 행: 품목, 열: 창고 7개, 셀: 발주수량/여유분 2행.

- 발주수량 = 현재 보유 재고 (momo_stocks.qty)
- 여유분  = 현재고 - 기간 내 발주(REQUESTED/APPROVED/INVOICED/PAID)
           의 출고 예정 수량 (거래처 default 창고 기준)
- 기간 필터: dateFrom/dateTo (기본 이번 주 월 ~ 오늘) + '금주' 버튼
- 엑셀 다운로드 지원
- 여유분 음수면 rose 강조 (재고 부족 경고)

운영 DB menu_info 9000420 등록 (parent 9000400 출고/정산).
2026-05-14 16:47:03 +09:00
chpark 789909991a feat(orders): USER 측 품목 추가 + 택배/용차 직접 수정
Deploy momo-erp / deploy (push) Successful in 2m5s
USER 가 본인의 출고요청/출고완료 발주에 직접:
- 신규 품목 추가 (피커 모달 — /api/m/items/list 재고 있는 품목 검색)
- 택배비 단가/수량 인라인 수정 + 라인 삭제
- 용차 단가/수량 인라인 수정 + 라인 삭제

신규 API:
- /api/m/orders/items/add — ITEM 추가 (재고/숨김/한도 검증, admin 우회)
- /api/m/orders/lines/save — 가드 풀어서 REQUESTED + APPROVED 둘 다 허용

UI:
- detail modal 상단 액션 바: '+ 품목 추가' / '택배 추가/+1' / '용차 추가/+1'
- 표 안의 택배/용차 행에 수량/단가 QtyInput → onBlur 자동저장
- ItemPickerModal — 키워드 검색 + 행별 수량 입력 → 일괄 추가
2026-05-14 16:17:19 +09:00
chpark d25db4a023 feat(orders): admin 수기 발주 작성 — 거래처 대신 명의로 등록
Deploy momo-erp / deploy (push) Successful in 2m26s
전화 요청 등 시 admin 이 거래처를 대신해 발주를 작성할 수 있도록.

- /m/admin/orders 헤더에 '수기 발주' 버튼 + SearchableSelect 거래처 picker
  → 선택 후 /m/orders/new?customerObjid=momoNNN 로 이동
- /m/orders/new 가 query param customerObjid 받음:
  · admin 일 때만 활성 (USER 가 query 박아도 무시)
  · 상단 배너에 거래처명 표시 + 취소 링크
  · save 호출 시 body 에 customerObjid 포함
- /api/m/orders/save: admin 이 body.customerObjid 명시하면 그걸로
  발주 INSERT (supplier_branch snapshot 도 해당 거래처 기준)
2026-05-14 16:10:05 +09:00
chpark 8d8bb17345 feat(statistics+admin-panel): 통계 4개 거래명세서 필터 + 거래명세서 관리 메뉴
Deploy momo-erp / deploy (push) Failing after 4m39s
통계 페이지 4개에 거래명세서 기준(전체/본사/김포) 필터 추가:
- /m/admin/statistics (월간 매출)
- /m/admin/statistics/daily (일자별)
- /m/admin/statistics/margin (원가/마진)
- /m/admin/statistics/pivot (거래처×일자)

각 API 의 WHERE 절에
  COALESCE(O.supplier_branch, U.statement_branch, 'HQ') = $N
추가. supplier_branch snapshot 우선, 옛 발주는 user_info.statement_branch
폴백. ALL/생략 시 전체.

admin-panel 권한 및 사용자 관리 섹션에 '거래명세서 관리' 항목 추가
— activeTab='statement-branches' 시 /m/admin/statement-branches iframe
으로 로드 (기존 페이지 재사용, 별도 컴포넌트 중복 없음).
2026-05-14 16:09:41 +09:00
chpark 3e2d8572f1 feat(orders): USER 측 출고요청 + 출고완료 모두 수정 가능 (입금완료 전까지)
Deploy momo-erp / deploy (push) Successful in 2m5s
- 사용자 detail modal editable: REQUESTED → REQUESTED + APPROVED 모두 허용
- items/update API USER 가드: 동일하게 REQUESTED + APPROVED 허용
- 안내 문구 상태별로 분기

품목 추가/택배비 수정은 다음 단계에서 작업.
2026-05-14 16:05:36 +09:00
chpark 7977ffff19 fix(branch-fee): 본사(HQ) 제외 + 계산서 발행 명의(supplier_branch) 기준
Deploy momo-erp / deploy (push) Successful in 2m6s
지사관리:
- WHERE COALESCE(supplier_branch, statement_branch, 'HQ') != 'HQ'
  → 본사 발주 완전 제외, 김포 등 지사 명의 계산서만
- snapshot 우선 (supplier_branch) → 옛 발주 폴백 (user_info.statement_branch)
- UI: 본사 row 표시 분기 제거, '본사 외' 명시

창고이동 통계:
- 본사 계열(HQ_*) → 김포 계열(KIMPO_*) 이동만 필터링
- 같은 본사 내 이동, 같은 김포 내 이동, 김포→본사 역방향 모두 제외
2026-05-14 15:08:18 +09:00
chpark bb21be260f fix(branch-fee): 본사(HQ) 제외 + 계산서 발행 명의(supplier_branch) 기준
Deploy momo-erp / deploy (push) Successful in 2m11s
사용자 요구 — 지사 수수료 페이지는 본사 거래처를 보여줄 필요 없음.
계산서가 김포 등 지사 명의로 발행된 발주만 표시.

- 그룹핑 기준: COALESCE(supplier_branch, user.statement_branch, 'HQ')
  · 발주 시점의 supplier_branch snapshot 우선 (= 계산서 발행 명의)
  · 옛 발주(snapshot 없음) 는 거래처 statement_branch 폴백
- WHERE branch != 'HQ' 로 본사 제외
- UI: 본사 분기 제거 (모든 행이 지사)
2026-05-14 15:05:10 +09:00
chpark 7b5951c227 feat(alerts+transfers): 유통기한 임박 알림 + 창고이동 통계 메뉴
Deploy momo-erp / deploy (push) Successful in 2m8s
A. 유통기한 임박 알림 (/m/admin/expiry-alerts)
   - momo_inbounds.expiry_date/completed_by 컬럼 운영 DB 추가
   - inbounds/save API: 입고 시 expiryDate/completedBy 함께 저장
   - 페이지: 만료/7일이내/30일이내 분류 카드 + 행별 D-N 뱃지
   - 빠른 필터 (7/14/30/60/90일)

B. 창고 이동 통계 (/m/admin/transfers)
   - stock_moves WHERE ref_type='TRANSFER' AND move_type='OUT' 기준
   - 출발창고 / 도착창고 / 품목 / 수량 / 단가(cost_price) / 금액
   - 이동자(regid + user_name), 이동일시, 메모
   - 합계 카드 + 엑셀 다운로드

운영 DB:
- ALTER TABLE momo_inbounds ADD COLUMN expiry_date, completed_by
- 인덱스 idx_momo_inbounds_expiry
- menu_info: 9000511 (유통기한), 9000512 (창고이동) 등록 — 통계 메뉴 산하
2026-05-14 14:58:58 +09:00
chpark 9fd1160b38 feat(branch-fee): 지사 수수료 관리 메뉴 — 본사 20% 수수료 산정
Deploy momo-erp / deploy (push) Successful in 2m9s
신규 메뉴 /m/admin/branch-fee — 거래처의 statement_branch(HQ/KIMPO 등)
기준으로 매출/원가/순수 마진 그룹핑 + 지사(HQ 외) 의 마진 × 20% =
본사 수수료 자동 계산.

표시:
- 합계 카드 4개: 총 매출 / 총 마진 / 본사 수수료 합 / 지사 실수령 합
- 지사별 표: 매출/원가/마진/수수료/실수령(마진-수수료)
- 본사(HQ) 행은 수수료 0 (— 표시)

집계 범위: 출고완료(APPROVED)/계산서발행(INVOICED)/입금완료(PAID) 발주.
운영 DB 의 menu_info objid=9000510 으로 등록 완료. (parent 9000500 통계)
2026-05-14 14:49:43 +09:00
chpark b568a8858a feat(procurements+inbounds): 발주서 납품조건 1번 삭제 + 입고 체크리스트
Deploy momo-erp / deploy (push) Successful in 2m16s
매입 발주서 납품조건:
- '상기 품목의 납기 지연 시...' 1번 항목 삭제. 검수/수량변경 2개만 유지.

입고 처리 체크리스트 (memo 컬럼에 텍스트로 저장 — 스키마 변경 없음):
1) 발주수량 vs 입고수량 일치 (체크박스)
2) 1카톤 N개 일치 (체크박스 + 카톤 단위 입력)
3) 소비기한 (date)
4) 물류창고 입고 최종완료자 (물류팀 4명 select)
5) 특이사항 (textarea)

저장 시 momo_inbounds.memo 에 줄단위 텍스트로 박힘:
  [수량 일치]   Y ✓
  [카톤 일치]   Y ✓ (1카톤 12개)
  [소비기한]    2026-11-30
  [입고완료자]  이효철 (물류총괄)
  [특이사항]    ...
2026-05-14 14:43:03 +09:00
chpark 3505148994 feat(orders): 출고완료 상태 수량 변경 시 재고 ± 동기화 + 이력
Deploy momo-erp / deploy (push) Successful in 2m6s
- 직전엔 items/update 가 momo_order_items.qty 만 UPDATE → 출고완료
  발주의 수량을 줄여도 재고는 그대로 (출고 시 차감된 양 그대로 묶임).
- 수정: status='APPROVED' 인 경우 newQty - oldQty 차이만큼 재고 보정
  · diff > 0 (추가 출고) → stock 차감 + stock_moves OUT
  · diff < 0 (수량 줄임)  → stock 복원 + stock_moves IN
- 사용된 창고는 기존 stock_moves(ref_type='ORDER', ref_objid=order, 동일
  item) 의 wh_objid 로 lookup (approve 시 사용했던 창고와 동일 유지).
- 이력 memo: "수량 수정: oldQty → newQty"
2026-05-14 01:33:53 +09:00
chpark 88686d0461 fix(orders): '내 발주 이력' 은 admin 이라도 본인 발주만 (mine=true)
Deploy momo-erp / deploy (push) Successful in 2m6s
momo5315(배연진) 같은 admin 임직원이 사용자 측 '내 발주 이력' 페이지를
열면 모든 발주가 노출되던 문제. admin 판정만으로는 부족 — 메뉴 의도가
'본인 것' 이라 isAdmin 여부 무관 customer_objid 본인 매칭 필요.

- list API: body.mine === true 면 admin 이어도 본인 발주만
- /m/orders/page.tsx fetch 에 mine: true 추가
- admin 메뉴(/m/admin/*)는 mine 안 보냄 → 기존대로 전체 노출
2026-05-14 01:31:07 +09:00
chpark 13d02cac6a chore(migrations): db/migrations 전체 삭제 + deploy 마이그레이션 단계 제거
Deploy momo-erp / deploy (push) Successful in 2m3s
사용자 명시 요청 — 운영 DB 는 이미 모든 스키마/데이터 변경 반영됐고,
더 이상 자동 reload 가 필요 없음. 매 deploy 시 마이그레이션이 실행되며
사용자 변경(비밀번호, 부서, 추가 거래처 등) 을 원복하는 사고를 막기 위해
폴더 통째로 삭제.

- db/migrations/*.sql 35개 모두 삭제
- .gitea/workflows/deploy.yml 의 migrate-momo.mjs 호출 단계 제거
- scripts/migrate-momo.mjs 파일 자체는 유지

운영 DB 의 모든 user_info 비밀번호는 '1' 로 직접 reset 완료(142명).
2026-05-14 01:26:30 +09:00
chpark f29024744d fix(orders): 비고 수정 = REQUESTED + APPROVED 두 상태 모두 허용 (출고완료 포함)
Deploy momo-erp / deploy (push) Successful in 2m34s
2026-05-14 01:22:11 +09:00
chpark e2c5c5b396 fix(orders): 내 발주 이력 — FITO 세션도 본인 발주만 보이도록
Deploy momo-erp / deploy (push) Successful in 2m39s
root cause:
- FITO auth.ts 는 user 객체에 role 필드를 만들지 않음 (isAdmin/userType 만).
- 새봄-마켓소풍(momo125) 가 FITO 폴백 경로로 로그인 → session.user.role
  = undefined → list API 의 `if (role === "USER")` 가 false → 필터 무효
  → admin 의 발주까지 다 노출.

→ admin 판정을 MOMO/FITO 공통 isAdmin/role/userType 세 조합으로 통일.
   !isAdmin 인 경우 본인 발주만 매칭.
2026-05-14 01:16:23 +09:00
chpark f4b1e31f7f fix(orders): 매출 출고 수정 = REQUESTED/APPROVED 만 (계산서발행/입금완료 차단)
Deploy momo-erp / deploy (push) Successful in 2m38s
2026-05-14 01:12:46 +09:00
chpark 5294554384 fix(orders): admin 그룹은 출고 발주 모든 상태 수량 수정 가능
Deploy momo-erp / deploy (push) Successful in 2m39s
momo5315(배연진) 같은 user_type='A' admin 이 출고요청/출고완료 발주
수량 수정이 안 된다는 사용자 신고. 직전 commit 에서 'REQUESTED/APPROVED'
만 허용으로 좁혔던 게 너무 빡빡했음.

→ admin 권한자는 취소(CANCELED) 외 모든 상태 수정 가능으로 풀기.
  · API items/update admin 분기: status === 'CANCELED' 만 차단
  · UI editable: order.STATUS !== 'CANCELED'
USER 권한자는 그대로 REQUESTED 만.
2026-05-14 01:08:29 +09:00
chpark b204f14265 fix(orders): 내 출고 이력에서 본인 발주만 — user.objid undefined 폴백
Deploy momo-erp / deploy (push) Successful in 2m37s
USER 권한 사용자의 list API 필터링에서 r.user.objid 가 undefined 인
세션에선 customer_objid 비교가 NULL 매칭 → 필터링 무효화돼 모든 발주가
노출되던 버그. user_id 폴백 + customer_objid 가 user_id 로 박힌 경우
모두 IN 절로 매칭.
2026-05-14 01:03:43 +09:00
chpark 34ee374796 feat(orders): ITEM 수량/비고 인라인 즉시저장 + 왼쪽 리스트 실시간 갱신
Deploy momo-erp / deploy (push) Successful in 2m35s
1) ITEM 라인 수량을 QtyInput 인라인 인풋으로 (REQUESTED/APPROVED 상태).
   onBlur/Enter 시 /api/m/orders/items/update 호출 → 자동 저장.
2) 비고(REMARK) 는 이미 onBlur 자동 저장이었음. 출고요청/출고완료 모두
   editable 이라 동작.
3) ExtraRow(택배/용차) 의 V(저장) 버튼 제거. onBlur 시 자동 저장으로 변경
   — label/단가/수량 어느 인풋이든 포커스 떠나면 자동 commit.
4) 모든 라인 수정 작업 (saveRemark/saveItemQty/upsertExtra/deleteExtra)
   에서 onReload + onReloadList 동시 호출 → 왼쪽 발주 리스트의 합계도
   즉시 반영.

부수: 운영 DB 의 모든 user_info 비밀번호를 '1' 로 reset (사용자 요청).
2026-05-14 01:01:06 +09:00
chpark 053a21c30e fix(invoices): 계산서 발행 대상 = 입금완료(PAID) 만
Deploy momo-erp / deploy (push) Successful in 2m42s
리스트:
- 기본 표시 = PAID + INVOICED 만 (APPROVED 출고완료 제외)
- 상태 필터 옵션도 PAID/INVOICED 만

발행 가드:
- frontend: 선택 + PAID + 미발행만 issue 가능
- API: UPDATE 조건 status='PAID' (이전엔 APPROVED 도 허용했음)
2026-05-14 00:45:39 +09:00
chpark 665a560486 fix(orders): 출고관리 수정 범위 좁히기 — REQUESTED + APPROVED 만
Deploy momo-erp / deploy (push) Successful in 2m52s
직전엔 PAID/CANCELED 외 모두 허용했는데, 사용자 재요청으로 계산서발행
(INVOICED) 도 잠금. editable = REQUESTED || APPROVED.
items/update API admin 가드도 동일하게 좁힘.
2026-05-14 00:43:22 +09:00
chpark 3a7d17b3e5 feat(orders): 출고 처리 기본 날짜 한 달 전 ~ 오늘로 변경
Deploy momo-erp / deploy (push) Successful in 2m50s
2026-05-14 00:42:02 +09:00
chpark 2d5b94a026 feat(admin/users): 수정 화면에서도 비밀번호 변경 가능
Deploy momo-erp / deploy (push) Successful in 2m36s
- 사용자 수정 폼에 '비밀번호 변경' 입력란 추가 (빈 칸이면 기존 유지)
- /api/admin/users/save update 분기: password 값이 있으면 AES 암호화 후
  user_password 갱신
2026-05-14 00:16:07 +09:00
chpark 9a086dae50 fix(migrations): momo001..momo135 부서 '일반구매자' (DEPT003) 매 deploy 보장
Deploy momo-erp / deploy (push) Successful in 2m42s
운영 DB 에는 직접 UPDATE 로 부서 설정 완료. 035 도 INSERT/UPSERT 시
dept_code='DEPT003', dept_name='일반구매자' 박도록 패치.
임직원 6명(user_type='A') 은 영향 없음.
2026-05-14 00:10:19 +09:00
chpark 4661981da5 feat(procurements): 입고완료 이후 수정 잠금 + 공급업체 SearchableSelect
Deploy momo-erp / deploy (push) Successful in 2m54s
- 매입 발주서 editable 재조정: OPEN/REQUESTED 만 수정 가능. RECEIVED/
  PARTIAL/PAID/CANCELLED 는 수정 불가. lines/save API 가드도 동일.
- 공급업체 select 를 SearchableSelect 로 교체 (typeahead):
  · 매입 발주서 관리 페이지의 발주서 폼 (page.tsx)
  · 매입 발주 신규 작성 페이지 (new/page.tsx)

운영 DB 의 매입 발주/입고/관련 stock_moves 데이터는 직접 모두 삭제했음
(사용자 명시 요청). UI 에 깨끗한 상태로 보임.
2026-05-14 00:08:27 +09:00
chpark d86a1154a9 fix(migrations+procurements): supply_mng objid numeric + setActiveId 빌드 에러
Deploy momo-erp / deploy (push) Successful in 2m34s
운영 DB 직접 점검 후 발견:
- supply_mng.objid 는 numeric NOT NULL (TEXT 아님) → 'MOMOSUP000000001'
  같은 문자열 INSERT 가 cast fail 로 80개 다 fail 하고 supply_mng = 0개
  잔존 상태였음. 운영 DB 에는 직접 80개 박아둠 (objid 1..80).
- 035 마이그레이션도 동일 패턴(numeric objid)으로 재작성. 매 deploy 안전.

직전 deploy #137 (485aea4) 빌드 실패 원인:
- procurements/page.tsx 의 deleteProc 에서 setActiveId(null) → state 가
  string 이라 타입 에러. setActiveId("") 로 수정.
2026-05-14 00:02:28 +09:00
chpark 6ea1f13003 fix(migrations): 031/032/033 NO-OP 화 + 035 plain SQL 단일 책임으로 통합
Deploy momo-erp / deploy (push) Failing after 58s
직전 batch 가 운영 반영 후에도 supply_mng 가 10개로 유지된다는 사용자 신고.
원인 추정: 031/032/033 의 DO block 안에서 어딘가 fail → migrate-momo.mjs 가
process.exit(1) → 그 뒤 마이그레이션 (034, 035) 실행 자체 못 함.

→ 031/032/033 본문을 SELECT 1; 로 NO-OP 화. fail 지점 우회.
→ 035 가 단독으로 회원 135 + 공급업체 80 + 제조사 메뉴 삭제 모두 처리.
  · DO block 없이 plain SQL 만 (각 statement 가 별도 transaction)
  · supply_mng: 통째 DELETE 후 80개 plain INSERT
  · user_info: user_type='U' DELETE 후 ON CONFLICT (user_id) UPSERT
  · 매 deploy 안전 — UPSERT 라 중복 INSERT 도 OK
2026-05-13 23:58:36 +09:00
chpark 485aea4d4f feat(procurements): 작성중 삭제 + 입금완료전 수정 + 035 plain SQL reload
Deploy momo-erp / deploy (push) Failing after 58s
- 매입 발주서: OPEN 일 때 삭제 버튼 노출, 라인 포함 hard delete
  · 신규 API /api/m/procurements/delete (status='OPEN' 만 허용)
- 매입 발주 editable: STATUS === 'OPEN' → STATUS not in (PAID, CANCELLED)
  · lines/save API 가드도 동일 (PAID/CANCELLED 만 차단)
- 035_supply_mng_plain_reload.sql: 직전 DO block 마이그레이션이 어디서
  fail 하는지 추적 불가 → 가장 단순한 plain SQL 로 supply_mng 다 비우고
  엑셀 기준 80개 INSERT ON CONFLICT(supply_code) UPSERT
  · momo_items/momo_procurements 의 vendor_objid 모두 NULL 처리
  · UNIQUE INDEX 보장 후 INSERT — 매 deploy 안전
2026-05-13 23:53:32 +09:00
chpark 5fce695f09 fix(migrations): 019 의 supply_mng 10개 매 deploy reset 차단 + 034 UPSERT
Deploy momo-erp / deploy (push) Successful in 2m36s
진짜 root cause — 019_proc_terms.sql 이 매 deploy 시
  DELETE FROM supply_mng;
  INSERT INTO supply_mng ... 10개 시드 (VND-001 ~ VND-010)
를 실행해서 supply_mng 가 항상 10개로 reset 되고 있었음.

→ 019 의 supply_mng 시드 부분 제거 (납품조건 ALTER 만 유지).

034 신설 — idempotent 매 deploy 안전 실행:
- product_lines 컬럼 보장
- supply_code UNIQUE 인덱스 보장 (ON CONFLICT 동작)
- 옛 'VND-*' 시드는 items/procurements 의 vendor_objid 끊은 후 DELETE
- 엑셀 80개 INSERT ON CONFLICT (supply_code) DO UPDATE
- sentinel 가드 없이 매번 안전 — 사용자 추가 supply (다른 supply_code) 는 보존
2026-05-13 23:46:30 +09:00
chpark 2d2f32f4f8 fix(auth-panel): 권한 제거 silent fail + 버튼 클릭 영역 확대
Deploy momo-erp / deploy (push) Successful in 2m36s
1) delete API: MASTER_OBJID/OBJID 가 numeric 가 아닐 때 ::numeric cast 가
   매칭 0건으로 silent fail. ::text 양쪽 비교로 안전하게.
2) 추가/제거 버튼: h-9 w-24 → h-12 w-32, cursor-pointer + hover 색상
   강화. 가운데 컬럼 min-w-[120px] 로 클릭 영역 넓힘.
2026-05-13 23:41:22 +09:00
chpark 1fde88bcd8 fix(migrations): 008/023 매 deploy 원복 사고 차단 + 033 강제 리로드
Deploy momo-erp / deploy (push) Successful in 2m49s
근본 원인:
- 008_makers_menu.sql: 매 deploy 시 제조사 관리 메뉴를 status='active' 로
  되돌려놓아 사용자가 메뉴 삭제해도 다음 배포 때 부활.
- 023_seed_momo_vendors_from_xlsx.sql: 매 deploy 시 옛 100개 공급업체를
  비-idempotent 한 INSERT 로 박아 supply_mng 가 영원히 옛 데이터로 원복.

→ 두 파일을 빈 NO-OP 으로 교체.

033_force_reload_v2.sql 신설 (sentinel 가드 momo_migration_marks 기반):
- 제조사 메뉴 menu_info objid=9000204 삭제
- momo_einvoice_items/einvoices/stock_moves(ORDER)/order_items/orders 통째
- user_info user_type='U' 다 삭제 후 momo001..momo135 ON CONFLICT UPSERT
  · 본사팀 85 (HQ), 김포팀 50 (KIMPO), 카테고리별 default_wh 매핑, 비번 '1'
- supply_mng 다 삭제 후 80개 INSERT (엑셀 모모유통 제조사 리스트 26.05.12)
  · product_lines 컬럼 ALTER (DO block 밖)
2026-05-13 23:37:40 +09:00
chpark 3d5a283955 feat(orders): 입금완료 전까지 거래명세표 수정 허용
Deploy momo-erp / deploy (push) Successful in 2m46s
사용자 요청 — 구매자가 수량 변경 요청하면 담당자가 거래명세표에서 수기로
수정하고 다시 입금 요청하는 흐름. 출고요청(REQUESTED) 뿐만 아니라
출고완료(APPROVED) / 계산서발행(INVOICED) 까지 수정 가능해야 함.

- editable: order.STATUS === 'REQUESTED' → STATUS !== 'PAID' && !== 'CANCELED'
- items/update API 의 admin 가드는 이미 PAID/CANCELED 외 모두 허용
- 수정하면 사용자 측 명세표도 그대로 갱신 (detail API 가 동일 데이터 반환)
2026-05-13 23:31:59 +09:00
chpark 91313351f9 chore(data): 회원/공급업체 마스터 통째 리로드 (마이그레이션 032)
Deploy momo-erp / deploy (push) Successful in 2m33s
사용자 요청 — docs 의 엑셀 두 파일을 기준으로:
- 회원(user_info user_type='U') 전부 삭제 후 momo001..momo135 신규 등록
  · 본사팀(85): 창고픽업 WH001 / 시장픽업 WH002 / 용차배송 WH003
  · 김포팀(50): 김포지사 WH004 / 창고픽업 WH005 / 시장픽업 WH007 / 용차배송 WH006
  · statement_branch: 본사='HQ' / 김포='KIMPO'
  · 비번 '1' (AES 암호화)
- 공급업체(supply_mng) 전부 삭제 후 80개 신규 등록 (제조사 리스트 엑셀 기준)
  · supply_mng 에 product_lines TEXT 컬럼 추가하여 제품명 보관
  · items.vendor_objid 는 NULL 처리 (참조 무결성)

1회성 sentinel — momo_migration_marks 테이블로 가드. 신규 데이터가
다음 deploy 때 또 지워지는 사고 방지.
2026-05-13 23:29:57 +09:00
chpark 94fc425ef3 chore(orders): 옛 발주 데이터 1회성 삭제 (마이그레이션 031)
Deploy momo-erp / deploy (push) Successful in 2m19s
사용자 명시 요청 — supplier snapshot 이전의 옛 발주 데이터를 통째로
비우고 신규 발주만 운용. 사용자가 새로 등록하기로 함.

⚠️ migrate-momo.mjs 가 매 deploy 시 모든 .sql 을 재실행하므로 raw DELETE
를 그대로 박으면 신규 발주가 다음 deploy 때 또 지워지는 사고가 남.
→ sentinel 테이블 momo_migration_marks 도입, 1회만 실행되도록 가드.

삭제 범위:
- momo_einvoice_items (발주연결분)
- momo_einvoices WHERE order_objid IS NOT NULL
- momo_stock_moves WHERE ref_type='ORDER'
- momo_order_items 전체
- momo_orders 전체

보존: momo_stocks.qty — 사용자가 inventory 메뉴에서 직접 보정.
2026-05-13 17:44:03 +09:00
chpark 0bfe85dc69 fix(orders): 거래명세표 공급자 정보 발주 시점 snapshot 처리
Deploy momo-erp / deploy (push) Successful in 3m37s
기존: 거래명세표 발급 때마다 user_info.statement_branch + branches table
을 실시간 조회 → 사용자의 기준 명세표를 바꾸거나, branches 의 계좌/
전화/이메일을 수정하면 과거 이미 찍힌 명세표까지 함께 바뀌어버림.

수정: 출고요청(REQUESTED) 시점에 supplier 8개 컬럼을 momo_orders 행에
박아두고, 이후 detail/statement/approve 는 이 snapshot 을 사용.

- 마이그레이션 030: momo_orders 에 supplier_branch / supplier_name /
  supplier_ceo / supplier_bank_account / supplier_phone / supplier_email
  / supplier_biz_no / supplier_address 컬럼 추가 (idempotent IF NOT EXISTS)
- save: 발주 INSERT 시 getSupplierByBranch(user.statement_branch) 호출 결과
  를 그대로 박음
- detail/statement/approve: snapshot 컬럼이 있으면 그것을 사용, 없으면
  옛 발주용 폴백으로 user_info.statement_branch → branches table 조회
2026-05-13 16:39:40 +09:00
chpark 2fffc42575 fix(orders): 거래명세표 택배/용차 추가 버튼 복구 + 캡처에서만 제외
Deploy momo-erp / deploy (push) Successful in 5m53s
직전 commit 에서 버튼 자체를 통째로 지웠던 게 잘못. 출고요청 건은
admin 이 화면에서 택배/용차 라인을 추가/수정해야 함.

- 화면: 버튼 항상 보임 (editable 시)
- 이미지 공유 캡처: .js-no-export 클래스로 hide (capture-share.ts 동작)
2026-05-13 16:35:47 +09:00
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