Commit Graph

95 Commits

Author SHA1 Message Date
king da6ae2cd13 fix(cupang): 혼합 상자 이동은 용량 제한 없이, ③ 목록 max-height 로 스크롤 보장
- mixPut/moveUnits 에서 용량 제한 제거. 이동 목록도 "가득"이어도 선택 가능
  (채움률이 100% 를 넘으면 빨간색으로 표시만)
- 부모 flex 높이 계산에 기대던 스크롤을 max-height 로 직접 지정
  (③ 72vh, ① 표 64vh, ② 목록 64vh)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 16:42:51 +09:00
king 58ebf1c232 change(cupang): 미배치 자투리 제거 — 상자 간 직접 이동만, ③ 스크롤 보정
- "미배치로 빼기" 옵션과 미배치 풀 UI/상태 삭제
- [−] 는 자리가 있는 다른 상자로 1개 이동(없으면 새 상자 자동 생성),
  [+] 는 같은 제품이 있는 다른 상자에서 1개 가져오기 → 총량 항상 보존
- 혼합 상자 ✕ 는 내용물을 다른 상자로 옮긴 뒤 상자를 없앤다
- 3열이 2열/1열로 접히는 폭에서 카드 max-height 를 줘서 ③ 목록이
  카드 안에서 스크롤되도록 수정(편집으로 줄이 늘어나도 페이지가 안 밀림)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 16:33:32 +09:00
king f3a681ccfe feat(cupang): 혼합 상자 내용물 편집 (수량 스테퍼 + 이동 + 미배치 풀)
- ③ 센터 분배의 혼합 상자 트리에서 항목마다 [−] n [+] 와 이동 드롭다운
  (다른 혼합 상자 / 새 상자 / 미배치로 빼기). 용량(부피 합)을 넘지 않게 제한
- 센터마다 "미배치 자투리" 풀 + [자동 담기], [+ 새 혼합 상자] 버튼
- 혼합 상자 ✕ 는 내용물을 미배치로 옮기고 상자를 없앤다
- 상자가 비면 자동 제거, 채움률은 헤더에 실시간 표시
- 확정 조건에 "미배치 자투리 0" 추가
- 혼합 상자 키를 위치 index → 상자별 고유 id 로 바꿔 추가/삭제에도 배분 유지
- 미배치 풀은 출고일 탭 전환 시에도 함께 보관

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 16:26:58 +09:00
king ba3b3a5ad8 feat(cupang): 출고 삭제 시 구글 시트도 동기화
- GoogleSheetsWriter.delete_sheet 추가 (없으면 no-op, 마지막 남은 시트면
  삭제 대신 내용만 비움 — 구글이 마지막 시트 삭제를 거부)
- 건별 삭제(soft/hard)와 날짜 전체 삭제 후 해당 출고일 시트를 동기화:
  남은 출고가 있으면 다시 기록, 없으면 시트 삭제
- 시트 설정 조회를 _sheet_target 으로 공통화, 결과는 로그로 남김
- 건별 삭제 후 기본 이동 경로를 그 출고일 달력으로

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 16:17:32 +09:00
king 4a260cb161 change(cupang): 화면 문구 "박스" → "상자" 통일
템플릿·라우터 메시지·페이지 제목과 seed/DDL 기본값(쿠팡박스→쿠팡상자)까지
표기를 맞췄다. URL(/box-calc)과 코드 식별자(box_name 등)는 그대로.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 16:00:09 +09:00
king 1c1ca69feb feat(cupang): 출고 박스 구성(box_plan) 저장 + 달력 상세를 센터 분배 형식으로
- 마이그레이션 005: cupang_shipments.box_plan JSONB (확정 당시 박스 구성)
  확정 payload 에서 제품별/혼합 상자와 내용물·상자 종류를 받아 저장
- 달력 오른쪽 목록을 ③ 센터 분배 카드 형식으로 변경 — 혼합 상자는
  내용물 트리까지 표시. box_plan 이 없는 예전 출고는 기존 합계 표시로 폴백
- 출고 보기(view.html) ③ 목록도 동일하게 box_plan 기준

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 15:58:29 +09:00
king 8c8f6aebb2 change(cupang): 출고 상세를 읽기 전용 3열 보기로 교체, 수정 기능 제거
- detail.html / form.html 삭제, GET·POST /{id}/edit 라우트와
  _form_context / _parse_lines 헬퍼 제거
- GET /{id} → view.html: ① 품목 / ② 박스 요약(서버 재계산) / ③ 센터
  (박스 계산 화면과 같은 3열 구성, 편집 불가)
- 박스 계산 로직을 _compute_boxes 로 분리해 API 와 보기 화면이 공유

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 15:48:05 +09:00
king da90d1eec8 style(cupang): 직접 입력 수량칸 70px 고정
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 15:39:52 +09:00
king 58d33aa926 change(cupang): 출고 칸 표기 "쿠팡상자, 41개" + K열 120px
상자 종류가 여럿이면 " / " 로 구분한다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 15:37:37 +09:00
king 21018a5332 fix(cupang): 열 너비를 픽셀 기준으로 (A=10, C·D·E=106)
구글 시트 요청에 pixelSize 를 8배로 넣어 A열이 80px 로 벌어져 있었다.
WIDTHS_PX 를 픽셀 그대로 쓰고, xlsx 는 px/7 로 환산한다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 15:31:03 +09:00
king b3090ced4f change(cupang): 확정 시 엑셀 자동 다운로드 제거
출고리스트는 구글 시트에 기록한다. 엑셀이 필요하면
GET /cupang/export.xlsx?date=YYYY-MM-DD 로 따로 받는다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 15:25:24 +09:00
king ebf1710982 feat(cupang): 출고리스트 서식 보강 (요일·머리글색·파렛트 강조)
- 시트명 20260903(목) 형식, 작성일/출고일/센터입고일에 요일 표기
- 머리글 행 배경 #DBE9F7 + 굵게
- 출고방식이 파렛트인 센터 블록 행 배경 #FAE2D5
- A열 너비 10
xlsx·구글시트 양쪽에 동일 적용(google_sheets.write_table 에
header_bg / row_highlights 인자 추가).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 15:24:55 +09:00
king 042d5f8574 fix(cupang): 시트 기록 결과를 로그·화면에 항상 표시
미설정/건너뜀도 사유를 보여준다(이전엔 조용히 넘어가 원인 파악이 어려웠음).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 15:05:36 +09:00
king db19a2fcbf feat(cupang): 확정 시 Google 스프레드시트에 출고일 시트 기록
- app/modules/cupang/export.py: 출고리스트 양식(셀/병합)을 한 곳에서 생성 →
  xlsx 다운로드와 구글 시트 기록이 같은 표를 쓴다
- app/integrations/google_sheets.py: 서비스 계정 기반 시트 쓰기 공통 계층
  (없거나 미설정이면 enabled=False 로 조용히 skip, 키는 로그에 남기지 않음)
- 확정 응답에 sheet 결과 포함, 화면에 성공/실패 메시지 표시
- env: CUPANG_SHEET_ID, GOOGLE_SHEETS_CREDENTIALS(_JSON) 추가
- requirements: google-api-python-client, google-auth

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 14:26:24 +09:00
king afa144fc02 feat(cupang): 확정 시 출고리스트 엑셀 생성, 센터 선택 드롭다운 제거
- ③ "센터를 고르면 바로 추가" 드롭다운 삭제(업로드가 센터를 자동 구성)
- 확정 payload 에 상자 종류별 박스 수(box_summary, 예: 쿠팡상자41) 추가 →
  출고 묶음의 outbound_summary 로 저장
- 센터입고일 = 출고일 + 1일로 저장(쿠팡 발주서 입고예정일과 일치)
- GET /cupang/export.xlsx?date=YYYY-MM-DD — 쿠팡로켓 밀크런 출고리스트 양식
  (제목/회사명/머리글 + 센터 단위 병합, 시트명 YYYYMMDD). 확정 직후 자동 다운로드

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 14:21:44 +09:00
king 275e51c93b feat(cupang): 발주 업로드 UX 개선 + 3열 프레임 각각 스크롤
- [쿠팡 발주파일 업로드] 라벨 버튼, 파일 선택 즉시 자동 분석(분석 버튼 제거)
- 안내 문구와 분석 결과 상세 표시 제거 — 경고만 남김
- ①②③ 카드가 각자 스크롤: 문서 전체는 스크롤되지 않음
  · ① 표 머리글 sticky, 행 높이 축소로 품목 더 많이 표시
  · ② KPI 요약까지 고정, 아래 목록만 스크롤
  · ③ 헤더/센터 선택 고정, 센터 목록만 스크롤

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 14:08:13 +09:00
king 5542748539 feat(cupang): 자투리 혼합 박스 상자 종류 선택
박스 요약 카드에서 쿠팡상자 / 3호상자 / 6호상자 중 하나를 고른다.
고른 종류는 카드 제목·박스 그림·③ 센터 분배 라벨에 반영되고,
출고일 탭 전환과 임시 저장/불러오기에도 함께 보관된다.
드롭다운 조작 시에는 드래그·담기 대화상자가 열리지 않게 예외 처리.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 13:56:10 +09:00
king 5217c4b6bb feat(cupang): 발주 업로드 결과를 출고일별로 분리
- 업로드 API가 (출고일, 센터, 제품)으로 합산해 groups[] 로 반환
- 화면 상단에 출고일 탭 — 날짜마다 ①직접입력 / ②박스요약 / ③센터분배 상태를
  따로 보관하고 탭으로 전환 (박스 계산은 날짜 × 센터 단위로 실행)
- 확정은 현재 날짜만 대상. 남은 날짜가 있으면 달력으로 나가지 않고 다음 탭으로 이동
- 업로드 결과 카드에 출고일별 센터 수·수량 요약 추가

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 13:49:21 +09:00
king a6d7de709d feat(cupang): 쿠팡 발주 엑셀 업로드 → 센터별 박스 자동 계산
- ① 카드를 "쿠팡 발주 업로드"로 개편, xlsx 다중 선택 업로드
- POST /cupang/api/box-calc/upload (openpyxl): F13 입고예정일 −1일 = 출고일,
  22행부터 B=쿠팡상품코드 / F=센터명 / G=수량을 읽어 파일들을 합산
- 쿠팡상품코드 → cupang_products.coupang_item_code 로 제품 매칭,
  센터명 → cupang_centers.name 매칭. 미매칭 코드/센터/박스규칙은 경고로 표시
- 박스는 센터 단위로 포장되므로 센터마다 박스 계산을 돌려 ② 요약에 합치고
  ③ 센터에 자동 배분(자투리 혼합 박스는 소속 센터를 라벨에 표시)
- 확정 대화상자 기본 출고일도 업로드한 발주서 날짜로 채움

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 13:23:33 +09:00
king eef18f7eb9 style(cupang): 달력 셀 테두리 복원, 요일/일자 글자 확대
- 요일 행 높이 고정(34px) — grid-template-rows: auto 로 주 행만 균등 분할
- 요일 11→22px, 일자 13→20px, 둘 다 bold
- 날짜 셀 1px 테두리 + hover 강조, 타월은 회색 배경으로 구분
- 오늘 원 24→32px, 출고 태그 12px

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 12:24:38 +09:00
king 1cf6ba385d feat(cupang): 달력을 2개월(현재+다음 달) 뷰로 개편
- index 라우터가 두 달치 출고를 합쳐(중복 id 제거) 달 별 격자 2개를 생성
- 상단 바: ‹ › 이동 + 기간 제목 + [오늘], 달마다 머리글/월 출고 합계 배지
- 셀 UI 정리: 오늘=검은 원, 선택=링, 출고일=건수/센터수 태그, 타월은 흐리게
- 범례 추가, 1200px 이하에서는 두 달을 세로로 배치

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 12:20:41 +09:00
king 0db54b6300 style(cupang): 등록 제품 카드 680px, 가로 스크롤 제거
셀 box-sizing: border-box 로 지정 폭에 padding 포함(기존엔 열마다 20px 씩
초과해 표가 카드보다 넓어짐). 카드 폭 600→680, 줄바꿈 브레이크포인트 1240px,
erp-table-wrap overflow-x: hidden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 12:13:24 +09:00
king d03bb15b6b style(cupang): 등록 제품 표 나머지 열 폭 조정
제품코드 96 / 쿠팡상품코드 112 / 상태 72 / 동작 104 (합계 544px).
머리글과 값이 잘리지 않게 잡고, 코드 열은 12px mono 로 축소.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 12:11:20 +09:00
king dcc059815e style(cupang): 등록 제품 표 제품명 열 160px 고정
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 12:09:25 +09:00
king 163c6c2f00 style(cupang): 등록 제품 표 한 줄 고정 (긴 이름/코드는 … 처리)
table-layout: fixed + 열 폭 지정, 셀 nowrap/ellipsis, 동작 버튼 한 줄.
잘린 값은 title 툴팁으로 전체 확인.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 12:07:15 +09:00
king 418166d810 style(cupang): 선택 등록 팝업 입력란 400px, 가로 스크롤 제거
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 12:04:11 +09:00
king 7174edd702 feat(cupang): 등록된 제품 수정 팝업
- 동작 열에 [수정] 버튼 → 제품명/제품코드/쿠팡상품코드 수정 팝업
- POST /cupang/api/products/{id}/edit (JSON), 제품코드 중복은 400
- 제품코드 변경 시 cupang_box_rules 의 product_code/스냅샷도 함께 이동
  (같은 코드 규칙이 이미 있으면 이동하지 않음). 출고 라인은 과거 기록이라 유지

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 12:00:33 +09:00
king bf3407b6ec feat(cupang): 제품 카탈로그에 쿠팡상품코드 + 상태 토글
- cupang_products.coupang_item_code 컬럼 추가 (마이그레이션 004, init.sql 동기화)
- 설정 화면: 쿠팡상품코드 열 표시/정렬, 수기 추가 폼 입력란 추가
- 선택 등록 시 바로 등록하지 않고 쿠팡상품코드 입력 팝업을 먼저 표시
- 상태 배지를 클릭 토글로 변경 (POST /cupang/api/products/{id}/toggle)
- 빈 쿠팡상품코드는 "미입력"으로 처리해 기존 값을 덮어쓰지 않음

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 11:30:00 +09:00
king 3a18b185a9 style(cupang): 박스 계산 상단 액션 정리
임시 저장·불러오기를 ① 카드 안 버튼 줄에서 상단 액션줄로 올린다. 계산 흐름과
무관한 동작이라 계산/추가/초기화와 섞여 있으면 눈에 안 들어왔다. 규칙이 없어
계산 화면이 뜨지 않는 경우엔 두 버튼도 숨긴다.

설정으로 넘어가는 [박스 입수량 설정]·[입고센터 관리] 링크는 달력 화면에
있으므로 여기서는 뺀다.
2026-08-31 17:52:37 +09:00
king 1dc4cfc097 feat(cupang): 달력 상세에서 출고 삭제 (건별 / 날짜 전체)
분배 확정으로 만든 출고를 지우려면 상세 페이지까지 들어가야 했다. 달력에서
날짜를 고른 뒤 오른쪽 카드에서 바로 지울 수 있게 한다. 센터가 여러 건일 때를
위해 목록 헤더에 "이 날짜 전체 삭제" 도 둔다. 둘 다 가운데 확인 팝업을 거친다.

삭제는 기존 정책대로 status='취소' soft delete 이고, 대신 달력·목록에서
취소 건을 걸러내 사용자에게는 삭제로 보이게 했다(기록은 DB 에 남는다).

- router: /{id}/delete 에 next 폼값(내부 경로만 허용) 추가, POST /cupang/day-delete 신설
- index.html: 카드 헤더에 삭제 버튼, 앵커 안에 버튼이 들어가지 않게 구조 정리
2026-08-31 17:13:10 +09:00
king 7a01c140b0 feat(cupang): 출고 등록 경로를 박스 계산으로 일원화, 달력 표시 정리
출고 묶음을 만드는 길이 둘(신규 등록 폼 / 박스 계산 분배 확정)이라 헷갈렸다.
폼 경로를 없애고 [+ 신규 등록] 이 박스 계산을 열게 한다. 중복이던 오른쪽
[박스 계산] 버튼은 제거. /cupang/new 는 북마크가 깨지지 않게 박스 계산으로
리다이렉트하고 POST /new(생성)는 삭제했다. 기존 묶음 수정은 그대로 동작한다.

달력 칸은 작성/출고/입고 세 배지를 늘어놓아 읽기 어려웠다. 출고 기준으로
"출고 N건 · 센터 M곳"만 남긴다. 오른쪽 상세도 같은 기준(출고일)으로 맞추고
센터별 출고방식·총 박스/개수와 상품별 수량·박스를 카드 안에 펼친다. 품목이
바로 보이므로 hover 툴팁은 제거.

임시 저장 기본 제목은 "2026.08.31(월) 오후 04시 50분" 형식으로.
2026-08-31 16:58:39 +09:00
king 7f879d279a fix(cupang): 출고방식 드롭다운 목록을 흰 바탕·검은 글씨로
닫힌 버튼의 배경색(빨강/반투명 흰색)이 펼친 option 까지 번져 읽기 어려웠다.
option 에 흰 배경과 검은 글씨를 직접 지정한다.
2026-08-31 16:42:42 +09:00
king 5d84ae4874 feat(cupang): 센터별 출고방식 + 분배 확정 → 출고 묶음 생성
③ 센터 분배 헤더에 [분배 확정] 을 두고, 조건이 갖춰질 때만 활성화한다.
조건은 두 가지다. 남은 박스가 0 이어야 하고, 담긴 센터마다 출고방식
(택배/파렛트)이 골라져 있어야 한다. 비활성일 때는 버튼 툴팁에 막힌 사유를
적는다(남은 박스 수, 출고방식 미선택 센터명).

확정을 누르면 달력이 바로 뜨는 팝업에서 출고일자를 고르고, 확인 시 센터마다
출고 묶음 1건(status=출고준비)을 만들어 쿠팡 달력의 그 날짜로 이동한다.
혼합 박스는 내용물 제품으로 풀어 담고 같은 제품끼리 합산한다. 박스 수는
화면 값을 믿지 않고 저장 시 서버가 수량·입수량으로 다시 계산한다.

- router: POST /cupang/api/box-calc/confirm
- box_calc.html: 센터 헤더 출고방식 select(미선택은 빨간 배경), 확정 팝업 달력
- 임시 저장 스냅샷에 출고방식 포함
- 센터입고일은 출고일과 같게 저장(상세에서 수정)
2026-08-31 16:22:48 +09:00
king b3e1f0a462 feat(cupang): 박스 계산 임시 저장 / 불러오기
계산 중 화면 상태를 서버에 이름 붙여 저장하고 다시 불러온다. 다른 PC 에서도
이어서 작업할 수 있어야 해서 localStorage 대신 DB 에 둔다.

저장 대상은 화면 스냅샷(입력 품목·열어둔 센터·분배 내역·도장 상태)뿐이고,
박스 수는 불러온 뒤 기존 계산 API 로 서버에서 다시 구한다. 저장값을 그대로
믿지 않으므로 입수량 규칙이 바뀌어도 어긋나지 않고, 계산 결과에서 사라진
항목은 제외한 건수를 알려준다. 같은 제목으로 저장하면 덮어써 목록이 무한히
늘어나지 않는다.

- scripts/sql/cupang_db_003_box_calc_drafts.sql (신규 테이블 + 권한, 멱등)
- db.py: list/get/save/delete_box_calc_draft
- router: GET·POST /cupang/api/box-calc/drafts, GET·DELETE /{id}
- box_calc.html: [임시 저장]·[불러오기] 버튼 + 목록 대화상자
2026-08-31 16:04:44 +09:00
king bd53533b77 style(cupang): 센터 분배 헤더/목록 구분, 박스 수량 입력란 축소
센터 이름과 담긴 품목이 같은 평면에 있어 경계가 흐렸다. 헤더를 바로 만들어
분리하고(담긴 센터는 검정 바 + 흰 배지) 품목은 패널 안쪽에서 구분선으로
나눈다.

박스 수량은 세 자리를 넘지 않으므로 입력란을 62px → 46px 로 줄이고,
자리만 차지하던 number 스피너를 숨겼다. 고정폭 글꼴로 자릿수 정렬,
max=999·inputmode=numeric 추가.
2026-08-31 12:40:02 +09:00
king 74e33efa55 feat(cupang): 센터 알림을 가운데 팝업으로, 그룹 헤더/목록 구분 강화
브라우저 기본 alert/confirm 은 상단에 붙고 URL 이 그대로 보여 어수선했다.
기존 .cpg-modal 스타일을 재사용해 화면 가운데 팝업으로 바꾸고, 삭제 확인도
같은 팝업(빨간 확인 버튼)으로 통일했다. ESC·배경 클릭으로 닫힘.

목록은 헤더와 항목이 같은 평면에 있어 구분이 약했다. 그룹을 테두리 있는
패널로 만들고 헤더에 회색 바 + 카운트 배지 + 접기 캐럿을 뒀다. 센터명은
고정폭 글꼴로 정렬감을 주고, 비활성은 취소선으로 표시.
2026-08-31 12:12:18 +09:00
king 21ee27ac40 feat(cupang): 센터 중복 등록 알림 + 목록 지역별 그룹화
추가 시 같은 이름이 있으면 조용히 재활성되던 동작(ON CONFLICT DO UPDATE)
때문에 사용자가 중복을 알 수 없었다. 등록 전에 먼저 조회해서 이미 있으면
만들지 않고 알림(활성/비활성 구분)을 띄운다.

목록은 29개가 가로 4열로 흩어져 훑기 어려웠다. 센터명 앞 지역 접두사로
묶고(인천14 → "인천") CSS 멀티컬럼으로 한 열을 위→아래로 읽게 바꿨다.
숫자는 자연 정렬(인천4 < 인천14). 행 액션은 hover/focus 시에만 노출해
이름이 먼저 눈에 들어오게 했다.

- 라우터: _center_group / _center_sort_key / _group_centers 추가
- 검색은 그룹 단위로 접히고 결과 0건이면 안내 표시

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 12:07:23 +09:00
king 7b358b0189 refactor(cupang): 입고센터 이름 수정 기능 제거
이름을 바꾸면 그 센터를 쓰던 기존 출고 건과 어긋날 수 있어 수정 경로를
막는다. 잘못 등록한 센터는 삭제 후 새로 등록.

- 목록 행: 이름 input+저장 버튼 → 읽기 전용 텍스트
- center_edit 라우터에서 name 폼 파라미터 제거(활성/정렬만 수정)
- 행이 좁아져 그리드 최소폭 340px → 240px

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 12:02:57 +09:00
king 026a9ab526 refactor(cupang): 입고센터 관리 UI 단순화
센터 목록은 이름 등록·조회·관리가 목적이므로 "사용중" 표시를 없애고
활성/비활성/삭제만 남긴다. 좌우 2단(추가 카드 360px + 900px 고정 목록)
대신 상단 추가·검색 바 + 다중 컬럼 그리드로 바꿔 29개 이상 센터를
한 화면에서 훑을 수 있게 했다.

- 행마다 폼 하나(formaction/name=active)로 저장·토글·삭제 처리
- 상태는 배지 대신 좌측 점(활성 초록 / 비활성 회색+흐리게)
- 클라이언트 검색 필터, 카운트 실시간 갱신
- 라우터에서 center_in_use 조회 제거(화면에서 미사용)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 11:59:44 +09:00
king 26beab1ae7 feat(cupang): 전체 배분 완료 시 빨간 도장
모든 박스(제품별 + 혼합)를 센터에 담아 미배분 잔여가 0 이 되면 ② 요약의
"센터 배분" 칸에 빨간 "전체 배분 완료" 도장을 찍는다. 처음 완료될 때만
찍히는 애니메이션이 돌고, 하나라도 빼면 도장이 사라진다. 재계산하면
기록도 초기화된다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 04:04:19 +09:00
king 2d84a20814 fix(cupang): 도장은 또렷하게, 애니메이션은 방금 완료된 것만
- 혼합 박스 도장이 흐리게 보이던 원인: 부모(.cpg-box-title)에 opacity 를
  주면 자식 도장까지 함께 흐려진다 → 제목은 색만 낮추고 도장은 opacity 1.
- 렌더할 때마다 모든 도장에 애니메이션이 다시 걸리던 문제: 이미 찍힌
  항목을 stamped 로 기억해 새로 완료된 도장(.is-new)에만 애니메이션.
  잔여가 다시 생기거나 재계산하면 기록을 지워 다음 완료 때 다시 찍힌다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:55:35 +09:00
king 2779a6285d feat(cupang): 배분 완료 도장·완료 카드 흐리게, 박스명 배지 제거
- ② 제품별 카드에서 "쿠팡박스" 배지 제거(모든 규칙이 같은 박스명이라 무의미)
- 배분이 끝난 제품 카드·혼합 박스에 파란 "배분 완료" 도장(살짝 기울어진
  테두리, 찍히는 애니메이션)
- 완료된 카드는 글자를 회색으로 낮추고, 혼합 박스는 상자 아이콘까지
  흑백 처리해 남은 카드와 한눈에 구분되게 함

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:50:46 +09:00
king c9a16d8cc4 feat(cupang): 센터에 담긴 혼합 박스 내용물 트리 표시
③ 센터 분배에서 혼합 박스 줄 아래에 무엇이 몇 개 들어가는지 트리로
펼쳐 보여준다. 2박스 이상이면 총 개수와 함께 "(4개 × 2박스)" 를 덧붙인다.
수량을 바꾸면 트리 수치도 즉시 갱신된다. 단일 제품 박스는 트리가 없다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:42:39 +09:00
king 87b49abb71 feat(cupang): 센터 즉시 추가·대화상자 센터 버튼 선택
- ③ 센터 분배: 목록에서 센터를 고르는 즉시 추가된다. "+ 센터 추가" 버튼
  제거. 고른 뒤 선택값을 비워 같은 센터를 다시 고를 수 있게 한다.
- 담기 대화상자: 센터 select 를 추가된 센터 버튼 목록으로 바꿔 한 번에
  대상을 고른다(현재 대상은 검은 버튼 + aria-pressed).

tests/js: 센터 추가를 change 이벤트로, 대화상자 센터 버튼 표시·전환·
선택한 센터로 담기는지까지 검증. 전체 통과.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:37:48 +09:00
king 8f71ef4d71 chore(cupang): 되돌린 뒤 CSS 캐시버전 갱신
47e09b9 되돌리기로 cupang.css 내용이 20260829e 시점으로 돌아갔지만,
브라우저에 20260829f(핸들 스타일 포함)가 캐시돼 있을 수 있어 새 버전으로
올린다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:33:24 +09:00
king 45807e545d Revert "feat(cupang): 드래그 조작감 개선 — 핸들·플레이스홀더·오토스크롤"
This reverts commit 47e09b94d7.
2026-08-29 03:33:03 +09:00
king 47e09b94d7 feat(cupang): 드래그 조작감 개선 — 핸들·플레이스홀더·오토스크롤
Pointer Events 기반으로 바꾸고(터치·펜 지원, setPointerCapture 로 창 밖
이동에도 이벤트 유실 없음) 업무툴 수준의 조작 피드백을 붙였다.

- 드래그 핸들(⠿)에서만 드래그 시작 → 카드 클릭/텍스트 선택과 충돌 없음
- 커서를 따라오는 고스트에 "잔여 N박스" 배지, 담을 수 없는 위치에서는
  빨간 테두리로 금지 표시
- 대상 센터에 "○○ — 여기에 담기" 플레이스홀더를 끼워 놓일 자리를 보여줌
- 센터 목록 위/아래 44px 안에 커서가 오면 자동 스크롤(센터가 많을 때 필수)
- pointermove 처리는 requestAnimationFrame 으로 1프레임 1회만 실행
- pointercancel / 창 blur / Esc 에서 드래그를 안전하게 취소

SortableJS 도입은 보류했다. 웨일에서 네이티브 DnD 가 시작조차 되지 않아
어차피 fallback 모드로만 동작하고, 브라우저 실측 검증 수단이 없는 상태에서
의존성만 늘어난다.

tests/js: 핸들 밖 드래그 차단·고스트 배지·플레이스홀더·금지 표시·Esc 취소
시나리오 추가(rAF 지연을 고려해 프레임 대기). 전체 통과.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:28:12 +09:00
king e7db2a90fc fix(cupang): 센터 분배를 마우스 기반 드래그로 교체 (웨일 대응)
웨일에서 카드를 눌러 움직여도 드래그 미리보기조차 생기지 않았다 =
HTML5 네이티브 DnD 가 시작 자체를 못 한 것. 브라우저 구현에 기대는
draggable/dragstart 를 걷어내고 마우스 이벤트로 직접 구현했다.

- mousedown 후 4px 이상 이동하면 드래그 시작, 카드 복제본(고스트)이
  커서를 따라온다. 커서 아래 센터 패널은 elementFromPoint 로 찾아 강조.
- mouseup 위치의 센터에 놓으면 수량 대화상자가 열린다. ③ 카드 여백에
  놓아도 센터가 하나면 그 센터로, ③ 밖이면 안내만 띄우고 담지 않는다.
- Esc 로 드래그 취소. 카드 위에서 손을 뗀 경우에만 뒤따르는 click 을
  1회 무시해, 드래그 후에도 클릭 경로가 막히지 않는다.

tests/js: 드래그 시작 임계값·고스트 생성/제거·대상 강조·여백 드롭·
③ 밖 드롭·클릭 대체 경로까지 마우스 이벤트로 검증. 전체 통과.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:17:08 +09:00
king ae7daabae5 fix(cupang): 센터 분배 드래그 실패 지점 제거·센터 목록 가나다 정렬
드래그가 브라우저에서 먹지 않던 문제를 추정 대신 실패 가능 지점별로
전부 막았다.

- dragstart 리스너를 카드 요소에 직접 바인딩(위임으로는 잡히지 않는
  환경 대비). 렌더할 때마다 다시 바인딩한다.
- dragenter/dragover 를 모두 preventDefault — 하나만 막으면 드롭을
  거부하는 브라우저가 있다.
- 드롭 대상 범위를 ③ 카드 전체로 확대하고, 대상 패널은
  closest → elementFromPoint → (센터가 하나면) 그 센터 순으로 찾는다.
  패널 사이 여백에 놓아도 담긴다.
- dataTransfer.setData/getData 가 막힌 환경 대비로 dragKey 를 따로 보관해
  드롭 시 사용한다. 그래도 못 읽으면 클릭으로 담으라는 안내를 띄운다.
- 드래그 중에는 ③ 영역에 점선 강조를 준다.
- 드래그 직후 발생하는 click 은 무시해 대화상자가 두 번 뜨지 않게 한다.

센터 선택 목록은 이름 가나다순 정렬(한글 음절은 코드포인트 순).

tests/js: 여백 드롭·dragenter·setData 차단 환경 시나리오 추가. 전체 통과.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:08:09 +09:00
king ead1361790 fix(cupang): 센터 분배 드롭 동작·수량 대화상자·센터 선택
드래그가 먹지 않던 원인: 드롭 대상이 점선 상자(.cpg-dist-drop) 안쪽으로
한정돼 센터 카드 여백에 놓으면 dragover 에서 preventDefault 가 걸리지
않았다 → 드롭 대상을 센터 패널 전체로 넓혔다. 카드를 클릭해도 같은
대화상자가 열리는 대체 경로도 추가.

- ③ 은 처음에 비어 있고, 셀렉트에서 고른 센터만 패널로 추가된다(✕ 로 제거,
  제거하면 담긴 박스는 잔여로 복귀)
- 드롭/클릭 시 대화상자에서 박스 수량을 입력한다. "잔여 전부 담기" 버튼으로
  남은 수량을 한 번에 담을 수 있고, Enter 로 확정 / Esc 로 취소
- 센터에 담긴 줄과 센터 합계에 박스 수와 상품 수(박스×입수량)를 함께 표시
- 요약 카드에도 잔여 개수(잔여 박스 × 입수량)를 표시

tests/js: jsdom 으로 계산→드래그→대화상자→수량 수정→제거까지 36개 항목을
검증하는 UI 테스트 추가(README 에 실행법). 전체 통과 확인.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:01:01 +09:00