docs(lps): 결과 상태 — 운영자와 실사용자를 나눠 접는 원칙 추가
보는 사람이 둘인데 하나로 뭉뚱그리고 있었다.
lps-admin 운영자 — 목적이 **진단**이다. '왜 그랬나'에 답해야 하므로 7상태를 그대로 보고
차단 마커·ip_request_no·포트까지 붙인다. 특히 blocked(자동 회복)와
env_blocked(사람이 고쳐야 함)를 반드시 갈라야 한다 — 개입 여부가 갈린다.
negodata 실사용자 — 목적이 **행동**이다. 할 수 있는 건 '쓴다/다시 시도/넘어간다' 셋뿐이라,
원인이 달라도 다음 행동이 같으면 같은 표기로 접는다:
no_match·empty → '–' (둘 다 결론은 '이 몰엔 없다')
blocked·env_blocked·unavailable → '확인 못함' (행동은 '나중에 다시' 하나뿐)
핵심 원칙: **상태는 하나로 정의·저장하고, 접는 건 표시 단계에서 한다.**
저장을 단순화하면 관리자가 원인을 못 보고, 표시를 상세화하면 사용자가 못 읽는다.
두 화면 모두 price_history 를 읽으므로(admin_service 확인) 데이터는 공유하고 투영만 달리한다.
예외 하나: '일부 확인 못함'(partial)은 사용자에게도 접지 않는다. 이건 행동을 바꾸기 때문이다 —
'이 가격이 최종인가'의 답이 달라진다. 다만 사용자에게 필요한 건 어느 몰이 왜 막혔는지가 아니라
결과가 완전하지 않다는 사실 하나다.
남은 일도 4단계로 갱신(1 플래그 보존 → 2 저장 자리 → 3 admin 표시 · 4 사용자 표시).
3·4 는 같은 데이터를 다르게 접는 것이라 병행 가능.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
04b697a9eb
commit
1e966f7121
@ -12,6 +12,10 @@
|
|||||||
|
|
||||||
상태는 두 층이다. **몰(소스) 단위**가 근본이고, **상품 단위**는 그것을 합친 결론이다.
|
상태는 두 층이다. **몰(소스) 단위**가 근본이고, **상품 단위**는 그것을 합친 결론이다.
|
||||||
|
|
||||||
|
그리고 보는 사람이 둘이다 — **운영자(lps-admin)는 원인까지** 알아야 하고,
|
||||||
|
**실 사용자(negodata)는 행동에 필요한 만큼만** 알면 된다. 상태는 하나로 정의·저장하고
|
||||||
|
표시 단계에서 각자에 맞게 접는다(3절).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. 몰(소스) 단위 상태
|
## 1. 몰(소스) 단위 상태
|
||||||
@ -98,22 +102,52 @@ per_source[src] = {"error": f"{type(res).__name__}: {res}"} # ← blocked/fata
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. 화면 표기 매핑
|
## 3. 화면 표기 — 보는 사람이 다르면 다르게 접는다
|
||||||
|
|
||||||
| 몰 열 | 조건 |
|
**상태는 하나만 정의하고 상세하게 저장한다. 접는 건 표시 단계에서 한다.**
|
||||||
|
저장을 단순화하면 관리자가 원인을 못 보고, 표시를 상세화하면 사용자가 못 읽는다.
|
||||||
|
두 화면 모두 `price_history` 를 읽으므로(lps-admin: 잡·이력 조회 / negodata: 최저가 모달),
|
||||||
|
데이터는 공유하고 **투영만 달리한다**.
|
||||||
|
|
||||||
|
### 3-1. lps-admin (운영자) — 상세하게
|
||||||
|
|
||||||
|
목적이 **진단**이다. "왜 그랬나"에 답할 수 있어야 하므로 7상태를 그대로 보여주고 근거를 붙인다.
|
||||||
|
|
||||||
|
| 표시 | 내용 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| 가격 | `matched` |
|
| 몰별 상태 | `matched` / `no_match` / `empty` / `blocked` / `env_blocked` / `unavailable` 그대로 |
|
||||||
| `–` | `no_match` / `empty` — **사실로서 없음** |
|
| 근거 | 차단 마커(`wtm_captcha`·`사용권한이 제한된`…), `ip_request_no`, 포트 |
|
||||||
| `확인 못함` | `blocked` / `env_blocked` / `unavailable` — **미확인** |
|
| 조치 힌트 | `env_blocked` → "설정·환경 문제, 회전 무효" / `blocked` → "IP 평판, 자동 회복" |
|
||||||
|
|
||||||
| 결과 열 | 조건 |
|
`env_blocked` 와 `blocked` 를 반드시 갈라야 한다 — **사람이 개입해야 하는가**가 갈리기 때문이다.
|
||||||
|--------|------|
|
이 구분이 없으면 운영자가 자동 회복될 일에 매달리거나, 손봐야 할 설정을 방치한다.
|
||||||
|
|
||||||
|
### 3-2. negodata (실 사용자) — 접어서
|
||||||
|
|
||||||
|
목적이 **행동**이다. 사용자가 할 수 있는 건 '이 가격을 쓴다 / 다시 시도한다 / 넘어간다' 셋뿐이라,
|
||||||
|
그 이상 나눠 보여줄 이유가 없다. 원인이 달라도 **사용자의 다음 행동이 같으면 같은 표기**로 접는다.
|
||||||
|
|
||||||
|
| 내부 상태 | 사용자 표기 | 접는 이유 |
|
||||||
|
|-----------|------------|----------|
|
||||||
|
| `matched` | 가격 | |
|
||||||
|
| `no_match` · `empty` | `–` | 둘 다 "이 몰엔 없다"가 결론. 원인(불일치냐 0건이냐)을 알아도 사용자가 할 일이 안 바뀐다 |
|
||||||
|
| `blocked` · `env_blocked` · `unavailable` | **확인 못함** | 원인이 달라도 사용자 행동은 '나중에 다시' 하나뿐. 차단 종류를 노출하면 불안만 준다 |
|
||||||
|
| `skipped` | 열 숨김 | 안 쓴 소스를 '없음'처럼 보이면 안 된다 |
|
||||||
|
|
||||||
|
결과 열도 같은 원칙으로 접는다.
|
||||||
|
|
||||||
|
| 사용자 표기 | 조건 |
|
||||||
|
|------------|------|
|
||||||
| 탐색 성공 | `found` 이고 기존보다 쌈 |
|
| 탐색 성공 | `found` 이고 기존보다 쌈 |
|
||||||
| 변동 없음 | `found`(더 싸진 않음) 또는 `not_found` |
|
| 변동 없음 | `found`(더 싸진 않음) 또는 `not_found` |
|
||||||
| **일부 확인 못함** | `partial` — 결과가 확정이 아님을 알린다 |
|
| **일부 확인 못함** | `partial` — 결과가 확정이 아님을 알린다 |
|
||||||
| 탐색 실패 | `error` — 전부 미확인 |
|
| 탐색 실패 | `error` — 전부 미확인 |
|
||||||
| 탐색 중 | 아직 결과 행이 없음 |
|
| 탐색 중 | 아직 결과 행이 없음 |
|
||||||
|
|
||||||
|
> **'일부 확인 못함'은 접지 않는다.** 다른 항목과 달리 이건 사용자의 행동을 바꾼다 —
|
||||||
|
> "이 가격이 최종인가"의 답이 달라지고, 다시 시도할 이유가 생긴다. 사용자에게 필요한 건
|
||||||
|
> *어느 몰이 왜 막혔는지*가 아니라 **결과가 완전하지 않다는 사실 하나**다.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. 현재 상태와 남은 일
|
## 4. 현재 상태와 남은 일
|
||||||
@ -125,9 +159,11 @@ per_source[src] = {"error": f"{type(res).__name__}: {res}"} # ← blocked/fata
|
|||||||
|
|
||||||
**안 된 것**
|
**안 된 것**
|
||||||
1. `_search_round` 가 `AdapterError.blocked/fatal` 을 버린다 → 몰별 상태를 못 만든다 *(가장 근본)*
|
1. `_search_round` 가 `AdapterError.blocked/fatal` 을 버린다 → 몰별 상태를 못 만든다 *(가장 근본)*
|
||||||
2. `price_history` 에 몰별 상태·`partial` 을 담을 자리가 없다 → negodata 가 못 읽는다
|
2. `price_history` 에 몰별 상태·`partial` 을 담을 자리가 없다 → 두 화면 모두 못 읽는다
|
||||||
3. 화면이 `–`(사실로서 없음)와 `확인 못함`(미확인)을 구분하지 못한다
|
3. lps-admin 이 몰별 상태·원인을 못 보여준다(잡 목록의 outcome 까지만)
|
||||||
|
4. negodata 가 `–`(없음)와 `확인 못함`(미확인)을 구분하지 못한다
|
||||||
|
|
||||||
1 → 2 → 3 순서로 풀어야 한다. 1을 안 고치면 2·3은 담을 내용이 없다.
|
**1 → 2 → (3, 4)** 순서다. 1을 안 고치면 2가 담을 내용이 없고, 2가 없으면 3·4가 읽을 게 없다.
|
||||||
|
3과 4는 같은 데이터에서 각자 다르게 접는 것이므로 순서가 없다 — 병행 가능하다.
|
||||||
|
|
||||||
> 이 문서는 **정의**다. 구현 전에 용어를 맞추기 위한 것이고, 실제 반영 여부는 위 4절이 소스다.
|
> 이 문서는 **정의**다. 구현 전에 용어를 맞추기 위한 것이고, 실제 반영 여부는 위 4절이 소스다.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user