-- LPS 몰별 확인 상태 — **lps_db 에 연결해서 실행**. 재실행 안전(IF NOT EXISTS). -- -- 왜 필요한가: '그 몰에 더 싼 게 없었다'와 '그 몰이 막혀서 못 봤다'가 지금 화면에서 똑같이 -- '–' 로 보인다. 사용자는 앞쪽으로 읽지만 실제로는 뒤쪽일 수 있다 — 안 본 걸 없다고 말하는 셈이다. -- 크롤러는 그 차이를 이미 알고 있는데(SourceState), 담을 자리가 없어 화면까지 못 갔다. -- -- 상태 정의와 표기 규칙은 lps/docs/result-states.md 가 소스다. -- 몰별 확인 상태 — {"naver": {"state": "matched", "count": 40}, -- "coupang": {"state": "blocked", "error": "AdapterError: ..."}} -- 열린 스키마(JSONB)로 둔다: 몰이 늘거나 상태에 근거를 덧붙여도 마이그레이션이 필요 없다. -- state 값: matched / no_match / empty / blocked / env_blocked / unavailable / skipped ALTER TABLE price_history ADD COLUMN IF NOT EXISTS sources JSONB; -- 결과가 **완전한가**. true = 못 본 몰이 있어 이 값이 최종이 아니다. -- sources 에서 유도할 수 있지만 굳이 컬럼으로 둔다 — 소비자(negodata)가 '어떤 상태가 확인된 -- 것인가'라는 판단 규칙까지 알아야 하면 상태 정의가 두 곳으로 흩어진다. 판단은 LPS 가 하고, -- 소비자는 사실 하나만 읽게 한다. ALTER TABLE price_history ADD COLUMN IF NOT EXISTS partial BOOLEAN NOT NULL DEFAULT FALSE; -- '확인 못한 결과'만 빠르게 뽑기 위한 부분 인덱스(운영 점검·알림용). -- 전체가 아니라 partial=true 행만 담아 인덱스가 작게 유지된다. CREATE INDEX IF NOT EXISTS ix_price_history_partial ON price_history (triggered_at) WHERE partial; -- ── 검증 ────────────────────────────────────────────────────────────────────── SELECT column_name, data_type, CASE WHEN column_name IN ('sources','partial') THEN '이번 추가' ELSE '' END AS note FROM information_schema.columns WHERE table_name = 'price_history' AND column_name IN ('outcome','by_mall','sources','partial') ORDER BY column_name;