chore(cupang): 박스 입수량 박스명을 '쿠팡박스' 로 통일

운영 DB 일괄 변경 스크립트(cupang_box_rules_unify_box_name.sql) 추가.
기존 호수(2호/3호/6호)는 사라지지 않게 memo 뒤로 옮긴다
(예: "피킹비 750원 · 2호").

시드 SQL 2개도 같은 규칙으로 맞춰, 재실행해도 호수 박스명이
되살아나지 않게 했다.

주의: 박스명은 박스 계산의 "자투리 혼합" 그룹 기준이라, 통일 후에는
2호/3호/6호 자투리가 한 박스에 섞여 계산된다(사용자 확인됨).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-29 02:22:52 +09:00
parent 07f71d1df0
commit 354eebeaac
4 changed files with 145 additions and 38 deletions
@@ -0,0 +1,63 @@
-- ════════════════════════════════════════════════════════════
-- itemcode_db: itemcode_ro 읽기 권한 재발 방지 (이벤트 트리거)
--
-- 증상: 말레이시아/쿠팡/dispatch 에서 세트 BOM "누락"·콤보 미분해·
-- 사방넷 출고 A열 빈칸. 진짜 원인은 데이터가 아니라 권한 —
-- "permission denied for table set_components(또는 single_items,
-- set_items)". itemcode_db 를 재import/재생성하면 itemcode_ro
-- GRANT 가 통째로 소실돼 반복 재발(2026-06-16/22/23/26/30, 07-01).
--
-- main-app 은 itemcode_db 를 읽기 전용(itemcode_ro)으로만 쓴다.
-- import 절차는 다른 앱(상품코드 마스터)에 있어 이 저장소가 못 건드림.
-- 그래서 import 절차와 무관하게, 테이블이 생길 때마다 postgres 가
-- 자동으로 itemcode_ro 에 SELECT 를 부여하도록 이벤트 트리거를 건다.
-- pg_restore 로 테이블이 drop→recreate 돼도 트리거가 즉시 재부여.
--
-- 실행(서버, superuser):
-- docker exec -i postgres-db psql -U postgres -d itemcode_db \
-- -f - < scripts/sql/itemcode_db_grant_ro_autotrigger.sql
-- 또는 파일 내용을 heredoc 으로 붙여넣기.
--
-- ⚠ 이벤트 트리거는 "테이블 drop→recreate"(pg_restore --clean, TRUNCATE
-- 아님) 케이스를 자동 커버. 만약 import 가 DROP DATABASE 후 재생성이면
-- 트리거 자체도 사라지므로, DB 재생성 직후 이 스크립트를 1회 다시 실행.
--
-- superuser(postgres)로 실행. 멱등.
-- ════════════════════════════════════════════════════════════
-- 1) 지금 존재하는 테이블에 즉시 부여 (현재고 복구)
GRANT SELECT ON ALL TABLES IN SCHEMA public TO itemcode_ro;
-- 2) 소유자(king) 기준 default privileges — king 이 만드는 신규 테이블 자동
ALTER DEFAULT PRIVILEGES FOR ROLE king IN SCHEMA public
GRANT SELECT ON TABLES TO itemcode_ro;
-- 3) 이벤트 트리거 — 소유자·생성 방식 무관하게 CREATE TABLE 마다 자동 GRANT
CREATE OR REPLACE FUNCTION public.grant_select_to_itemcode_ro()
RETURNS event_trigger
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
obj record;
BEGIN
FOR obj IN
SELECT object_identity
FROM pg_event_trigger_ddl_commands()
WHERE command_tag = 'CREATE TABLE'
AND schema_name = 'public'
LOOP
EXECUTE format('GRANT SELECT ON %s TO itemcode_ro', obj.object_identity);
END LOOP;
END;
$$;
DROP EVENT TRIGGER IF EXISTS trg_grant_select_to_itemcode_ro;
CREATE EVENT TRIGGER trg_grant_select_to_itemcode_ro
ON ddl_command_end
WHEN TAG IN ('CREATE TABLE')
EXECUTE FUNCTION public.grant_select_to_itemcode_ro();
-- 확인:
-- \dp set_components → itemcode_ro=r/king 표시되면 OK
-- \dy → trg_grant_select_to_itemcode_ro 등록 확인