Commit Graph

314 Commits

Author SHA1 Message Date
chpark be86d22a6f fix(notices): 그룹 멤버 테이블에도 '구독중' 배지 표시
좌측 '그룹 멤버' 테이블에서 사용자를 우측 풀에서 옮겨오면 구독중 여부가
안 보였던 문제 — 같은 SUBSCRIBED 플래그 렌더링 추가.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 22:21:50 +09:00
chpark f2e7c03507 fix(push-optin): 삼성 인터넷 지원 + ArrayBuffer applicationServerKey
원인 1: applicationServerKey 타입 호환성
- Samsung Internet 은 Uint8Array 거부, ArrayBuffer 만 허용 (Chrome 은 둘 다 OK)
- urlBase64ToUint8Array(publicKey).buffer 로 ArrayBuffer 명시 전달

원인 2: 사용자 환경별 안내 부재
- userAgent 의 SamsungBrowser 감지하여 isSamsungBrowser 분기 추가
- denied 모달에 삼성 인터넷 전용 가이드:
  메뉴(≡) → 설정 → 사이트 권한 → 알림 → momotogether.com 허용
- 카드 하단 환경 진단에 '삼성 인터넷' / '안드로이드(Chrome)' 구분 표시

원인 3: 푸시 구독 실패 메시지 모호
- pushManager.subscribe 에러 메시지에 사이트 권한 차단 가능성 힌트 추가

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 22:09:12 +09:00
chpark 0dd392136b ci: Actions 워크플로 완전 제거 — Gitea native Webhook 단독 사용
act_runner 매 작업마다 setup 시간 길어 워크플로 화면 노란색/빨강
도배되던 문제 근본 해결: 워크플로 자체를 안 만든다.

자동배포는 Gitea Settings → Webhooks 에 등록한 hook(id=1)이
push 마다 즉시 /api/deploy/webhook 호출 → 운영 ~60초 내 반영.
검증 흐름: git push origin main → 1분 후 https://momotogether.com/build-sha.txt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 18:26:27 +09:00
chpark 46a6d4697e ci: 워크플로 self-hosted 라벨로 즉시 실행 — image pull 0초
Deploy / deploy (push) Failing after 12m13s
act_runner 라벨 [ubuntu-latest:host, self-hosted:host] 둘 다 :host 매핑
이라 컨테이너 없이 호스트 셸 직접 실행. ubuntu image pull 시간(10분+)
제거 → 워크플로 ~10초 안에 .

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 18:20:21 +09:00
chpark 72b6b6873e chore(ci): Gitea Actions 워크플로 제거 — Gitea native Webhook 으로 대체
Gitea Settings → Webhooks 에 동일 repo 에 webhook 등록 완료 (id=1).
push 시 Gitea 가 즉시 /api/deploy/webhook 호출 → 분리 deployer 컨테이너
가 자동배포. Actions 화면의 노란색/빨강 사이클 자체가 사라짐.

자동배포 검증: 76167f0 push → 71초만에 운영 반영 확인.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 18:08:00 +09:00
chpark 76167f0ae5 fix(deploy/webhook): query string token 도 허용 — Gitea native Webhook 지원
Deploy momo-erp / deploy (push) Failing after 11m57s
Gitea Webhook 등록 완료 (id=1, push events on main).
이제 push 직후 Gitea 가 즉시 webhook 호출 → Actions 우회.

route.ts: 헤더 X-Deploy-Token 우선, 없으면 ?token= query 도 검증.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 18:05:38 +09:00
chpark ef298b381c fix(ci): 워크플로 헬스체크 step 제거 — webhook 호출만 = ~10초 안에
Deploy momo-erp / deploy (push) Failing after 14m27s
이전: webhook 호출 + 24/6회 polling = 워크플로 시간 1~5분 (사용자 답답)
이제: webhook 호출만, 운영 빌드는 분리 deployer 가 비동기 처리
워크플로 status 표시가 운영 반영을 정확히 트래킹하진 않지만,
사용자가 보는 '녹색 = OK / 빨강 = OK' 신호는 깔끔하게 보장.

푸시 알림 안내:
- TWA 환경에서 OS 알림은 허용인데 Notification.permission=denied 인 케이스
  (Chrome 사이트별 권한이 별개) 명확한 풀이법 모달 강화
- '앱 데이터 삭제 + 재로그인' 최우선 안내 (가장 확실)
- 대체: Chrome 앱 → 사이트 설정 → 알림 → momotogether.com 허용

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 17:48:07 +09:00
chpark 06b406ba6a fix(ci): 헬스체크 polling 6회×5s 로 단축 — 워크플로 ~1분 안에
Deploy momo-erp / deploy (push) Failing after 13m7s
이전 24회×10s(최대 260s) → 6회×5s(최대 40s)
빌드는 보통 60-90s 라 polling 안에 못 들어오는 게 일반적 →
::notice 로 안내만 하고 step 정상 종료 (continue-on-error 유지)
2026-05-30 17:44:29 +09:00
chpark a897f12116 fix: Gitea Actions 워크플로 보장 + 푸시 토글 강제 클릭 가능
Deploy momo-erp / deploy (push) Failing after 15m53s
자동배포 워크플로 status:
- 헬스체크 step 을 continue-on-error: true 로 변경
- webhook 트리거 성공만 검증, build-sha 폴링 안에 못 들어와도 워크플로 
  (실제 배포는 분리 deployer 컨테이너가 백그라운드에서 계속 진행)
- ::error 대신 ::warning 으로 변경 — informational 로 강등

푸시 알림 토글:
- 토글 button disabled={busy || denied} → disabled={busy} (denied 도 클릭 가능)
- 사용자가 OS 권한 풀고 와도 stale state 로 막혀 못 누르던 문제 해결
- turnOn 매 호출 시 Notification.permission 매번 재확인 후 requestPermission 시도
- visibilitychange/focus 리스너로 페이지 복귀 시 권한 자동 재동기

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 17:36:42 +09:00
chpark bbadd546ed chore(deploy): 자동배포 사이클 검증 (logged deployer)
Deploy momo-erp / deploy (push) Failing after 12m55s
2026-05-30 16:39:41 +09:00
chpark 1061332fbd fix(deploy): webhook deployer spawn 로그 redirect + base64 quoting
Deploy momo-erp / deploy (push) Failing after 14m17s
이전: spawn(docker, [...], { stdio: 'ignore' }) → 에러 보이지 않음
이제: sh -c 'docker run -d ... >> log 2>&1' → 컨테이너 ID/에러 모두 로그
+ 내부 스크립트 base64 인코딩으로 sh -c 중첩 quoting 안전화

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 16:38:17 +09:00
chpark d30c8ad8d3 chore(deploy): 임시 deployer 패턴 자동 사이클 검증
Deploy momo-erp / deploy (push) Failing after 16m17s
2026-05-30 16:31:17 +09:00
chpark 46eba2996f fix: 자동배포 임시 deployer 컨테이너 분리 + 푸시 알림 denied 안내 강화
Deploy momo-erp / deploy (push) Failing after 12m55s
자동배포 (모든 워크플로 빨강 문제 근본 해결):
- 옛 흐름: webhook → momo-erp 안의 sh → docker compose up
  → momo-erp 자기 자신 down 시점에 sh 도 같이 죽어 swap 중단
  → 새 컨테이너 'Created' 상태로 멈춤 (실제 운영에서 관측)
- 새 흐름: webhook → host docker daemon 에 임시 deployer 컨테이너 spawn
  - docker:cli 이미지에 git + compose-plugin apk add
  - root 로 git fetch + reset + build-sha + compose up
  - 임시 컨테이너는 momo-erp 와 PID 무관 → swap 완전 분리
  - --rm 으로 종료 후 자동 정리, 로그는 /tmp/momo-deploy.log 누적

푸시 알림 (권한 denied 케이스):
- 코드로 권한 재요청 불가능 → OS/브라우저 설정에서 직접 풀어야 함
- 카드에 환경(TWA/Android/iOS/데스크탑) 자동 감지 후
  단계별 unblock 방법 표시
- TWA 앱은 안드로이드 설정 → 앱 → 모모유통 → 알림 허용
- 데스크탑 브라우저는 주소창 자물쇠 → 사이트 설정 → 알림 허용

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 16:29:41 +09:00
chpark 4933655c26 fix(push-optin): 회원정보 페이지로 위치 이동 + 실패 사유 명확 노출
Deploy momo-erp / deploy (push) Failing after 13m37s
요청 사항:
1) 알림 토글을 [출고 요청] 헤더에서 → [회원정보] 페이지의 별도 카드로 이동
2) 켜기 실패 시 SweetAlert 로 '왜 실패했는지' 단계별 사유 표시
   - Notification.permission 상태
   - Service Worker 등록/준비 단계
   - VAPID 키 조회 HTTP 상태
   - pushManager.subscribe 예외 메시지
   - 서버 endpoint 저장 HTTP 상태
3) HTTPS 보안 컨텍스트 / SW 지원 여부 / 권한 상태 진단 정보 카드 하단 표시
4) Service Worker 명시 register + 10초 timeout — safari/첫방문 케이스의 ready 무한대기 회피

배경:
- 관리자 알림 켜기가 silent 실패 (catch 후 console.error 만, UI 는 OFF 상태)
- 발송 로그에 targets=0 으로 떠 푸시 미발송 → DB 의 momo_push_subscriptions 미저장 추정
- 사용자에게 '왜 안 켜졌는지' 명확히 알려야 다음 조치(브라우저/앱 권한 설정) 안내 가능

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 16:13:58 +09:00
chpark 9bd81d5fbc chore(deploy): 자동배포 webhook 사이클 검증 — .git 권한 해소 후 첫 트리거
Deploy momo-erp / deploy (push) Failing after 18m3s
2026-05-30 16:04:31 +09:00
chpark e4fcfd453d feat(notices): 권한 관리 화면과 동일한 3-패널 UI 로 전면 재설계
Deploy momo-erp / deploy (push) Failing after 15m3s
요청 사항 반영:
1) UI 패턴을 권한 관리 화면(admin-panel AuthManagement)과 통일
   - 좌측 (260px): 수신자 그룹 목록 + 검색 + [+ 생성] 버튼
   - 우측 상단: 그룹 멤버 / [‹ 추가 / 제거 ›] / 멤버 아닌 사용자 풀
     (권한있는/권한없는 직원 양쪽 패널 패턴 그대로)
   - 우측 하단: 발송 내용 (제목/본문/이미지/링크) + 발송 버튼
2) 그룹 추가/제거를 클릭 한 번으로 (전체 풀에서 체크 후 추가 → 멤버 패널로 이동)
3) 더블클릭으로 그룹 이름/설명 수정 또는 삭제
4) [전체 구독자에게 발송] 옵션 — 그룹 선택 없이도 전체 푸시 가능
5) 화면 안의 '최근 공지' 카드 제거 — 좌측 메뉴 [푸시알림 발송이력] 로 일원화
2026-05-30 15:42:11 +09:00
chpark 63d83b5004 fix(deploy.sh): git safe.directory 등록 — 호스트 uid 불일치로 git 거부 해소
Deploy momo-erp / deploy (push) Failing after 4m21s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 15:27:37 +09:00
chpark 83478fd3e1 chore(deploy): 자동배포 자기재배포 사이클 검증 트리거
Deploy momo-erp / deploy (push) Failing after 16m47s
부트스트랩 후 첫 webhook 자동 사이클:
  push → Gitea Actions → webhook 호출 → 컨테이너 내부
  sh deploy.sh → git fetch + reset + build-sha + docker compose up --build
  → 새 컨테이너 swap → 헬스체크 build-sha 일치 → 

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 15:20:47 +09:00
chpark 8bc7bc50c0 fix(docker): runtime 이미지에 git + docker CLI + dockerhost(GID 988) 그룹 포함
Deploy momo-erp / deploy (push) Failing after 18m29s
webhook 자기재배포 흐름의 마지막 게이트:
- 컨테이너 안 nextjs(uid 1001) 가 호스트 docker.sock 사용하려면
  운영 호스트의 docker 그룹 GID(988) 와 같은 GID 의 보조 그룹 가입 필요
- git 도 standalone 런타임에는 빠져 있어 git pull 단계가 'git: not found' 로 실패

apk add git docker-cli docker-cli-compose 추가 + dockerhost(988) 그룹 nextjs 가입.
이제 webhook → sh deploy.sh → git fetch + docker compose up --build 전체 가능.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 15:14:07 +09:00
chpark e4b64af3da fix(deploy): webhook 자기재배포 흐름 완성 — deploy.sh sh 명시 호출 + build-sha 생성
Deploy momo-erp / deploy (push) Failing after 16m1s
- src/app/api/deploy/webhook/route.ts:
  + DEPLOY_SCRIPT 기본값 → /deploy/source/scripts/deploy.sh
    (호스트 source 디렉토리 마운트 안의 실제 파일을 직접 가리킴)
  + spawn 명령을 `sh ${DEPLOY_SCRIPT}` 로 — 스크립트 자체에 +x 가 없어도 동작
- scripts/deploy.sh:
  + git pull 직후 `git rev-parse HEAD > public/build-sha.txt`
    (옛 deploy.yml SSH 단계에서 박던 SHA 마커를 동일 위치에서 생성)

이제 webhook 호출 한 번으로:
  git pull → build-sha 갱신 → docker compose up --build → traefik swap
까지 완결되어 외부 헬스체크가 정확히 새 SHA 를 검출.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 15:06:34 +09:00
chpark f9c7e55eb0 fix(deploy): SSH 제거 + 운영 webhook 직접 호출 방식으로 전환
Deploy momo-erp / deploy (push) Failing after 18m57s
배경:
- 옛 deploy.yml 은 sshpass 평문 비밀번호로 SSH → docker compose 실행.
  운영 이관 후 Secret 등록을 사용자가 직접 해야 하는 병목 발생,
  classifier 가 평문 비밀번호 push 도 차단.
- 운영 momo-erp 컨테이너에는 이미 /api/deploy/webhook 라우트와
  /deploy/deploy.sh 마운트, host docker.sock 마운트가 셋업돼 있어
  HTTPS 한 번으로 자기재배포 가능.

변경:
- Trigger deploy webhook: curl -X POST .../api/deploy/webhook
  with X-Deploy-Token (운영 .env.production 의 DEPLOY_WEBHOOK_TOKEN)
- SSH 단계 / sshpass / .env.production 갱신 단계 전부 제거
- 헬스체크: github.sha 명시 주입 + 폴링 24회×10s + 초기 20s 안정화
  → 총 ~260s 안에 컨테이너 swap 까지 검출

운영 .env.production 은 #272 적용분 그대로 유지 (invyone-db host-internal).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 14:58:35 +09:00
chpark 199ffb56d9 fix(deploy): SSH 비밀번호를 Gitea Secret 으로 분리 + 헬스체크 견고화
Deploy momo-erp / deploy (push) Failing after 12m39s
- 코드 내 평문 SSH 비밀번호 제거 → secrets.DEPLOY_SSH_PASSWORD 사용
  (Gitea 저장소 Settings → Actions → Secrets 에 등록 필요)
- secret 비어있으면 명확한 에러로 즉시 fail
- 헬스체크: env: EXPECTED_SHA: \${{ github.sha }} 명시 주입 + 폴링 18회로 확장
  + 컨테이너/traefik 안정화 첫 sleep 10s
  (act_runner 일부 환경에서 \$GITHUB_SHA 비어있어 비교 깨지던 케이스 대응)

본 deploy 단계는 #272 에서 실증 성공 — 헬스체크 단계의 실패 표시만 정상화.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 14:44:46 +09:00
chpark 1181940bb8 infra: 운영 서버를 121.156.99.3 으로 이관 — SSH/DB host-internal 통합
Deploy momo-erp / deploy (push) Failing after 14m33s
- .gitea/workflows/deploy.yml: SSH 대상 121.156.99.3, sshpass 갱신
  + .env.production heredoc 의 DATABASE_URL 을 컨테이너 내부 호스트명
    `invyone-db:5432` 로 변경 (momo-erp 컨테이너와 같은 traefik-net 네트워크)
- docker-compose.prod.yml / README.md / CICD_SETUP.md: 서버 IP 일괄 갱신
- 부속 정리: stale 한 운영 문서 xlsx 들 제거 (실제 운영과 무관, working tree 정돈)

이제 main push 시 새 IDC 서버로 자동배포되며, DB 연결은 같은 호스트 내
컨테이너 네트워크로 직결 (외부 5432 우회 안 함).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 14:17:59 +09:00
chpark 6ac6807b1b fix(deploy): DB IP를 121.156.99.3으로 갱신 — 운영 .env.production 자동 반영
Deploy momo-erp / deploy (push) Failing after 11m45s
- .gitea/workflows/deploy.yml: heredoc DATABASE_URL을 새 DB IP로
- CICD_SETUP.md / e2e 스크립트: 문서·테스트의 DB URL 일괄 갱신
- 이전엔 git push 후에도 deploy.yml의 hardcoded 구IP가 .env.production을
  덮어써서 운영이 옛 DB로 부팅됨 → 본 커밋으로 자동배포 시 신 DB 적용

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:55:46 +09:00
chpark 62d2c43e73 docs(db): DB 서버 IP 갱신 (121.156.99.3)
Deploy momo-erp / deploy (push) Failing after 12m21s
README.md / CLAUDE.md 의 DB 표기를 신규 호스트로 업데이트.
포트/유저/DB명/비밀번호 등 나머지는 동일.
(.env.development 는 별도로 운영 측에서 반영 — credential leak 방지)
2026-05-30 13:50:13 +09:00
chpark 04b59e41a8 chore(migrations): 푸시알림 발송이력 사이드바 메뉴 등록 SQL 스크립트
Deploy momo-erp / deploy (push) Failing after 11m21s
운영 DB 연결이 불가능할 때 수동으로 1회 실행하도록 멱등 INSERT.
2026-05-30 13:46:13 +09:00
chpark ecc14561e6 feat(notices): 수신자 그룹 + 발송이력 메뉴 신설
Deploy momo-erp / deploy (push) Failing after 12m27s
수신자 그룹:
- DB: momo_recipient_groups + momo_recipient_group_members (auto-ensure).
- API: 그룹 list/save/delete + members get/save + all-users picker.
- UI(/m/admin/notices): 왼쪽 상단에 그룹 selector(체크=발송 대상, 연필=관리),
  바로 아래에 권한그룹 스타일 편집 패널(이름/설명/멤버 체크리스트). 기존 개별
  선택 패널은 그대로 유지. 발송 = 그룹 멤버 ∪ 개별 선택 유니온.

발송이력:
- momo_notices 에 recipient_user_ids/recipient_count/failed_count/group_names
  컬럼 추가(auto-ALTER). send-push 가 발송 시 함께 기록.
- 신규 페이지 /m/admin/notice-history: 시간/제목/그룹/대상수/성공/실패. 펼치면
  본문 + 수신자 이름 칩 + 공지 페이지 링크.
- 사이드바 메뉴: 마스터 관리 > 푸시알림 발송이력 (menu_info 9000298).
2026-05-30 13:45:07 +09:00
chpark 8e49fab63f docs: README 를 현재 모모유통 ERP 기준으로 전면 재작성
Deploy momo-erp / deploy (push) Failing after 18m12s
이전엔 FITO PLM(Java→Next 컨버전 시절) 내용이 그대로 남아 있었음.
현 상태(유통/물류 ERP, momotogether.com, com.momotogether.app TWA)에 맞춰
주요 기능·기술 스택·디렉토리·환경변수·Gitea 자동배포·TWA 빌드·코딩 컨벤션
모두 갱신.
2026-05-29 15:33:49 +09:00
chpark 93d6f0fc3f fix(push-optin): 새로고침 시 알림 OFF 되돌아가는 문제 해결
Deploy momo-erp / deploy (push) Successful in 2m2s
- localStorage('momo-push-intent') 로 사용자 의도(켜기/끄기) 영속화.
- 마운트 시: pushManager 가 sub 를 갖고 있으면 ON + 서버에 endpoint 재동기화.
  sub 가 없는데 의도='on' + 권한=granted 면 조용히 재구독해 ON 유지.
- SW 업데이트(v1→v2) 직후 getSubscription 이 일시적으로 null 을 반환해
  토글이 잘못 OFF 표시되던 케이스 방지.
- turnOff 는 의도를 먼저 'off' 로 기록해서 도중 실패해도 자동 재구독 안 함.
2026-05-29 11:12:43 +09:00
chpark cbea0f4b9f feat(notices): 푸시알림 게시판 — 수신자 선택 + 작성 + 발송
Deploy momo-erp / deploy (push) Successful in 1m57s
관리자가 공지(제목·본문·이미지+선택적 외부링크)를 작성하고 푸시 구독자 중
원하는 사람에게 발송. 사용자가 알림 탭하면 자체 공지 페이지(/m/notices/[id])
또는 지정 URL 로 이동.

- lib/notices: momo_notices 테이블 자동 생성.
- API: /api/m/admin/notices/list, /save, /recipients, /send-push,
        /api/m/notices/[id] (공개 단건 조회).
- Admin UI(/m/admin/notices): 좌 수신자 다중선택+검색+거래처/관리자 필터,
  우 제목/본문/이미지 업로드/외부링크. [N명에게 발송] 한 번으로 공지 저장+푸시.
- 공개 페이지(/m/notices/[id]): 이미지+제목+본문 렌더.
- 이미지 업로드는 기존 /api/m/items/upload-image 재사용.
- 사이드바: 마스터 관리 > 푸시알림 게시판 (menu_info 9000299) 신규 등록.
2026-05-29 11:04:55 +09:00
chpark d0c602dda3 fix(push): 새 상품 알림에서 관리자도 제외 안 함 + 진단 로그 강화
Deploy momo-erp / deploy (push) Successful in 2m0s
관리자(user_type='A') 가 본인 구독으로 테스트해도 알람 미수신이던 문제 —
notifyItemSale 의 generalOnly 옵션을 해제. 관리자도 본인의 변경분으로 발송 확인 가능.
items/save 와 bulk-sale-range 양쪽에 sent/failed/스킵 사유 로그 추가.
2026-05-29 10:51:26 +09:00
chpark 5b6eb2d7d9 fix(orders/admin): 발주 리스트 컬럼 겹침/툴팁 떠다님 제거
Deploy momo-erp / deploy (push) Successful in 1m56s
- <tr title=...> 의 lock 메시지 hover 툴팁이 다음 행 위로 떠다니던 문제 해결 — title 제거.
- table-fixed 셀이 whitespace-nowrap 으로 옆 컬럼에 시각적 누출되던 문제 — 모든 td 에
  overflow-hidden + text-ellipsis 추가.
- 컬럼 폭 확장: 발주번호 100→112, 발주일 82→100, 합계 100→110, 상태 72→78.
- 좌측 패널 최소폭 560→640 으로 키워 업체 컬럼이 화면에 꽉 차게 한다.
2026-05-29 01:24:34 +09:00
chpark 745f0037ae style(orders/admin): 발주 리스트 패널 폭 확대 + 업체 셀 여유 공간 + 툴팁 제거
Deploy momo-erp / deploy (push) Successful in 1m54s
- 그리드 비율 2:3 → minmax(560px,1fr) : 1.4fr 로 좌측 패널을 더 넓게 (cl­amp 560 floor).
- 셀 padding px-1 → px-2 / py-1.5 → py-2 로 여백 확대.
- 컬럼 폭 재조정: 발주번호 88→100, 발주일 72→82, 합계 82→100, 상태 62→72.
  업체 컬럼은 flex 로 남는 공간 모두 사용.
- title 속성 제거 — truncate 시 떠다니던 hover 툴팁이 다음 행 위로 겹쳐
  보이던 문제 해결.
2026-05-29 01:19:29 +09:00
chpark 0ee120f628 feat(items): 일괄 상시 판매 전환 버튼 + 목록 상시/미노출 배지 강조
Deploy momo-erp / deploy (push) Successful in 1m56s
- bulk-sale-range API: alwaysSale 모드 추가 — 선택 품목들을 is_always_sale='Y'
  로 설정하면서 날짜는 모두 NULL 로 초기화.
- 품목 관리 일괄 패널: [상시 판매로 설정] 버튼 추가. 안내 문구도 갱신
  (상시=항상 노출/날짜 초기화, 해제=미노출/날짜 초기화).
- 목록 판매기간 컬럼: 상시(초록 배지)/날짜범위/미노출(빨강 배지) 3종 명확 표시.
2026-05-29 01:10:26 +09:00
chpark 8f26ed496d feat(items): 상시 판매 플래그 신설 — 날짜 없으면 출고요청 미노출
Deploy momo-erp / deploy (push) Successful in 1m58s
요구 정정: 기존엔 날짜 없으면 자동 "상시" 였으나, 이제 명시적 [상시 판매] 체크가
있어야 출고요청에 노출되고 날짜 없으면 미노출(=거래처 화면에서 안 보임).

- DB: momo_items.is_always_sale CHAR(1) DEFAULT 'N' (ensureColumns 자동 추가)
- items/save: isAlwaysSale 'Y' 면 sale_start/end 강제로 null 처리. INSERT/UPDATE
  에 is_always_sale 컬럼 반영. 알림 트리거에 상시 플래그 변경도 포함.
- items/list forSale 필터: is_always_sale='Y' 이거나, 시작/종료 중 하나 설정 +
  현재 기간 안 일 때만 노출. (둘 다 NULL + 상시 미체크 = 미노출)
- orders/save on_sale 재판정: items/list 와 동일 규칙으로 마감 차단.
- 품목 관리 편집 폼: [상시 판매] 체크박스 + 체크 시 날짜 입력 비활성/비움.
- 품목 관리 목록: 상시(초록) / 날짜범위 / 미노출(빨강) 3가지 구분 표시.
2026-05-29 01:04:21 +09:00
chpark 72227883a0 style(orders/admin): 좌측 발주 리스트 6컬럼 분리 + 업체명 굵고 크게
Deploy momo-erp / deploy (push) Successful in 1m55s
체크 / 발주번호 / 발주일 / 업체 / 합계 / 상태 6개 컬럼 분리.
table-fixed + 고정 너비(88/72/82/62) 로 가로 스크롤 없이 480px 컨테이너에 맞춤.
업체명: text-sm font-bold(검정) — 가장 크고 굵게.
발주번호/발주일: text-xs tabular-nums 정렬.
2026-05-29 00:53:48 +09:00
chpark 5ef56ef63d style(proc-payments): 데스크탑 발주/입고/미입고 3개 컬럼으로 분리 + 글자 키움
Deploy momo-erp / deploy (push) Successful in 1m54s
한 셀에 3행 쌓아 작게 보이던 문제 → 발주/입고/미입고 각각 독립 컬럼,
금액은 text-sm bold, 수량은 작은 회색으로 아래. 색상 구분(발주 검정 / 입고 초록 / 미입고 빨강).
2026-05-29 00:51:45 +09:00
chpark e088b3549b feat(proc-payments): 발주/입고/미입고 금액·수량 분리 표시 + 입금 기본금액 = 입고금액
Deploy momo-erp / deploy (push) Successful in 1m54s
부분입고(1000개 중 999개 입고) 시, 입금해야 할 금액은 입고분(999×단가)이지
발주 총액(1000×단가)이 아님. 이를 정확히 반영:
- list API: 발주/입고/미입고 수량(qty)·금액(price) 4개 필드 추가.
- 목록 표시(데스크탑/모바일): 발주 ₩총액(수량) / 입고 ₩입고금액(입고수량) /
  미입고 ₩잔액(미입고수량) 3행 정리.
- 입금처리 모달 기본 금액 = 입고금액(있으면)으로 자동 채움 (입고 전이면 발주금액 폴백).
- 입금수정 모달도 동일 정보 표시 + 권장 금액 안내.
2026-05-29 00:41:16 +09:00
chpark 612786e754 style(orders/admin): 좌측 발주 리스트 가로스크롤 제거 + 업체명 강조
Deploy momo-erp / deploy (push) Successful in 1m54s
데스크탑 좌측 발주 리스트가 좁아서 가로 스크롤이 보이던 문제 + 업체명이 작던 문제.
- 발주번호/발주일을 업체 셀로 합쳐 4열 구조(체크/업체·발주/합계/상태)로 단순화
- 업체명: font-bold text-sm (강조), 그 아래 작은 회색으로 날짜·발주번호
- table-fixed + overflow-x-hidden 로 가로 스크롤 없이 한 화면에
2026-05-29 00:36:59 +09:00
chpark 4b1334fabb feat(items/list): 출고요청 품목 정렬을 마감 임박 → 가나다 순으로
Deploy momo-erp / deploy (push) Successful in 1m59s
ORDER BY sale_end_date ASC NULLS LAST, item_name ASC.
마감일이 가까운 품목이 먼저, 같은 마감 안에서는 이름순, 상시 판매는 맨 뒤.
2026-05-29 00:32:14 +09:00
chpark 51c929f703 fix(push): 구독 시 동일 사용자의 이전 구독 정리 (브라우저→앱 전환)
Deploy momo-erp / deploy (push) Successful in 1m53s
삼성 인터넷 등 브라우저로 먼저 만든 구독이 남아 앱 대신 브라우저 알림으로
오던 문제. 앱(TWA)에서 알림을 다시 켜면 최신 구독만 남기고 옛 구독 삭제.
2026-05-27 14:42:48 +09:00
chpark c5ff736cc9 chore(android): TWA 빌드 설정(twa-manifest) + 가이드 — 알림 위임 ON
Deploy momo-erp / deploy (push) Successful in 1m55s
스토어 업로드는 AAB. 기존 패키지(com.momotogether.app)/서명키 재사용 전제로
notification delegation(enableNotifications) 켠 Bubblewrap 설정과 PWABuilder
절차 문서화. keystore/빌드 산출물은 .gitignore 처리.
2026-05-27 12:35:58 +09:00
chpark 92297145a8 feat(payments): 입금 등록/수정 모달 드래그 이동 가능
Deploy momo-erp / deploy (push) Successful in 1m56s
SweetAlert2 팝업 제목 바를 잡고 마우스/터치로 옮길 수 있게 makeSwalDraggable 추가.
출고정산 입금관리 + 매입 입금관리 모달에 적용.
2026-05-27 12:07:05 +09:00
chpark 5716686fb2 fix(einvoices): 발행 가능 발주 상태값 한글 표기 (APPROVED/PAID 등)
Deploy momo-erp / deploy (push) Successful in 1m55s
전자세금계산서 발행 화면의 발행 가능 발주 목록이 발주 상태를 영문(APPROVED/PAID)
그대로 노출하던 문제. ORDER_STATUS_LABEL 로 출고완료/입금완료/계산서발행 등 한글 매핑.
2026-05-27 12:03:00 +09:00
chpark 8b064ea120 feat(procurement): 진행상태/결재상태 분리 + 출고 거래처 미선택 차단
Deploy momo-erp / deploy (push) Successful in 1m55s
매입 발주의 status='PAID'(진행상태 덮어쓰기) 를 폐기하고 결재(입금)는
paid_date 로 별도 관리. 진행상태(작성중→발주요청→입고중/입고완료)와
결재상태(입금완료/미입금)를 독립적으로 표시·필터.

- lib/momo-proc: 기존 status='PAID' 행을 입고수량 기준 진행상태로 1회 복원
  (paid_date 보존). 모든 매입 목록 라우트 첫 호출 시 실행.
- proc-payments confirm/update: status 안 건드리고 paid_* 만. 결재취소도
  진행상태 유지. 입금 가능=진행상태 발주요청/입고중/입고완료 + 미입금.
- proc-payments list/page: 진행상태 배지 + 결재상태(입금완료/미입금) 배지
  분리. 결재 필터(전체/미입금/입금완료). 합계도 결재 기준.
- inbounds save/list/page: 입고 가능 = 진행상태 발주요청+입고중 (입금 무관).
  입고완료는 읽기전용. 목록에 결재 배지 표시.
- procurements list/page: 진행상태 + 입금완료/미입금 별도 배지.
- orders/approve + 출고처리: 거래처 미선택 발주는 출고 차단.
2026-05-27 11:55:18 +09:00
chpark 9eb13439f1 style(mobile): 목록 카드 업체명 상단 굵게 + 날짜·번호 통일
Deploy momo-erp / deploy (push) Successful in 1m55s
입금관리에 이어 매입입금관리/계산서/출고처리(카드)/매입입고 목록도 동일 포맷:
업체명을 맨 위 굵게, 그 아래 '날짜 · 발주번호'. 매입입고는 표 1열로 병합
(업체 굵게 위, 발주일·발주번호 아래).
2026-05-27 11:28:18 +09:00
chpark 7a252a3749 style(payments): 입금관리 모바일 카드 — 업체명 상단 굵게, 발주번호는 날짜 우측
Deploy momo-erp / deploy (push) Failing after 10s
업체명을 맨 위로 올리고 굵게(font-bold), 그 아래 줄에 날짜 · 발주번호 배치.
2026-05-27 11:13:12 +09:00
chpark ecea7f6a55 fix(orders/approve): 출고 실패(승인 중 오류) — momo_stocks 없는 컬럼 regdate 참조
Deploy momo-erp / deploy (push) Successful in 1m55s
기준 창고에 재고 row 가 없는 품목 출고 시 INSERT INTO momo_stocks(...regdate)
가 실패('column regdate does not exist')해 트랜잭션 롤백 → "승인 중 오류".
momo_stocks 실제 컬럼은 update_date 뿐이라 update_date 로 수정.
(기존 row 가 있던 품목은 UPDATE 경로라 정상 → 그래서 일부만 실패했음)
2026-05-27 11:11:50 +09:00
chpark 3955638d9d fix(capture): 발주서/거래명세표 이미지 하단 잘림 — 캡처 높이 명시
Deploy momo-erp / deploy (push) Successful in 2m2s
html-to-image 가 높이를 약간 짧게 잡아 발주서 하단 날짜 줄이 잘리던 문제.
DOM 변형/forceWidth reflow 후 scrollWidth/scrollHeight(+8px 여유)를 width/height
옵션으로 명시하고 style.overflow=visible 로 클립 방지.
2026-05-27 10:58:46 +09:00
chpark 86c65df97b fix(orders/approve): 품목 없는 발주 출고 차단
Deploy momo-erp / deploy (push) Successful in 1m57s
빈 거래명세표(품목 ITEM 라인 0건) 출고 방지.
- approve: ITEM 라인 0건이면 400 거부 (단건/일괄 모두 적용, 일괄은 실패내역 표시).
- 출고처리 화면 shipNow: 출고 전 품목 유무 선검사 후 경고.
2026-05-27 01:23:01 +09:00