마지막 단계. 차단당해 못 본 몰이 화면에서 '–'(없음)로 보여 사용자가 "쿠팡엔 더 싼 게 없구나"로 오해하던 문제를 끝낸다. 안 본 걸 없다고 말하지 않는다. 사용자 화면은 **셋으로 접는다**(lps/docs/result-states.md 3-2절). 할 수 있는 행동이 '쓴다/다시 시도/넘어간다' 뿐이라, 원인이 달라도 다음 행동이 같으면 같은 표기다: matched → 가격 no_match · empty → '–' (확인했고 없었다) blocked · env_blocked · unavailable → '확인 못함' (못 봤다) 운영자 화면(lps-admin)은 같은 데이터로 7상태를 그대로 본다 — 목적이 진단이라 접지 않는다. 체인 전체를 이었다: - postgres-init/alters/2026-08-07-iilp-source-state.sql — item_internet_lowest_prices 에 sources/partial 추가(멱등, **운영 적용 필요**) - models.py / lps_sync_crud 읽기 계약 / lps_sync_service 미러링 / LowestPriceEntry 프로토콜 - orval 재생성(ORVAL_INPUT 으로 저장 스펙에서 — 서버 없이). 생성 diff 는 새 필드만. - PriceUpdateModal: 가격이 없는 몰이 '못 본 몰'이면 '–' 대신 '확인 못함'. partial 은 LPS 가 판단해 내려준 사실을 그대로 쓴다 — 화면이 '어떤 상태가 확인된 것인가'를 다시 판정하면 상태 정의가 LPS 와 negodata 두 곳으로 흩어진다. E2E 검증(실 DB 2시나리오): by_mall 은 둘 다 naver 뿐인데 쿠팡 칸이 '확인 못함'(차단) / '–'(0건) 으로 갈린다. tsc 오류 없음(기존 xlsx 미설치 오류는 무관). negodata 97 · lps 292 passed. > 폴더 관례상 negodata 는 인수인계 대상이나, 사용자 요청으로 이번 건도 예외 적용. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
35 lines
2.2 KiB
SQL
35 lines
2.2 KiB
SQL
-- 2026-08-07 · 최저가 수집 이력에 '몰별 확인 상태' 미러링 (기존 DB 보정)
|
||
-- 배경: '그 몰에 더 싼 게 없었다'와 '그 몰이 막혀서 못 봤다'가 화면에서 똑같이 '–' 로 보인다.
|
||
-- 사용자는 앞쪽으로 읽지만 실제로는 뒤쪽일 수 있다 — 안 본 걸 없다고 말하는 셈이다.
|
||
-- by_mall 은 **가격이 있는 몰만** 담으므로 그 구분이 담길 자리가 없었다.
|
||
-- LPS 가 lps_db.price_history.sources/partial 로 내려주기 시작했고(2026-08-07),
|
||
-- lps_sync_service 가 이 컬럼으로 미러링한다. 상태 정의는 lps/docs/result-states.md.
|
||
-- 멱등: ADD COLUMN IF NOT EXISTS — 여러 번 실행해도 안전.
|
||
-- 적용: psql -h <host> -p <port> -U <user> -d <db> -f postgres-init/alters/2026-08-07-iilp-source-state.sql
|
||
|
||
\connect negosium_db
|
||
|
||
-- 몰별 확인 상태 — {"naver": {"state": "matched", "count": 40},
|
||
-- "coupang": {"state": "blocked", "error": "..."}}
|
||
-- state: matched / no_match / empty / blocked / env_blocked / unavailable / skipped
|
||
ALTER TABLE partner.item_internet_lowest_prices
|
||
ADD COLUMN IF NOT EXISTS sources JSONB NULL;
|
||
|
||
-- 결과가 완전한가. true = 못 본 몰이 있어 이 값이 최종이 아니다.
|
||
-- sources 에서 유도할 수 있지만 컬럼으로 둔다 — 화면이 '어떤 상태가 확인된 것인가'라는 판단
|
||
-- 규칙까지 알아야 하면 상태 정의가 LPS 와 negodata 두 곳으로 흩어진다. 판단은 LPS 가 끝낸다.
|
||
ALTER TABLE partner.item_internet_lowest_prices
|
||
ADD COLUMN IF NOT EXISTS partial BOOLEAN NOT NULL DEFAULT FALSE;
|
||
|
||
COMMENT ON COLUMN partner.item_internet_lowest_prices.sources IS
|
||
'몰별 확인 상태 {몰: {state, count|error}} — lps_db.price_history.sources 미러링. state=SourceState';
|
||
COMMENT ON COLUMN partner.item_internet_lowest_prices.partial IS
|
||
'못 본 몰이 있어 결과가 최종이 아님 — 화면은 이 값으로 "일부 확인 못함"을 표시';
|
||
|
||
-- 검증
|
||
SELECT column_name, data_type, column_default
|
||
FROM information_schema.columns
|
||
WHERE table_schema = 'partner' AND table_name = 'item_internet_lowest_prices'
|
||
AND column_name IN ('by_mall', 'sources', 'partial')
|
||
ORDER BY column_name;
|