# 검수 대본 실행 지시 — 공개 영상 신고·채널 차단·신고 처리 탭 (uc_a38ca9cc51bb rev 4 · ★2회차)

당신은 맥락 없는 검수 실행자다. 아래 UC 대본을 **순서대로, 하나도 건너뛰지 않고** 실제 화면(브라우저)과 실제 API 를 눌러 밟고, 각 칸에 ✅(밟았고 의도대로) / ❌(밟았는데 의도와 다르다) / ⚠(못 봤다 — 무엇을 못 봤나·무엇이 있어야 볼 수 있나 각 1줄) 를 매긴다.
★규칙: 코드를 읽어 판단하지 마라 — 화면이 부르는 것을 화면이 부르는 순서로 부른다. 막히면 멈추지 말고 나머지 칸을 계속 밟는다. 각 칸에 요청·응답(상태코드·핵심 필드·화면 텍스트)을 그대로 남긴다. 스크린샷을 SHOTS 디렉터리에 칸마다 1장 남긴다(파일명 = UC 번호 접두). 유료 호출(LLM·GPU·영상 생성) 0. prod 무접촉. 코드 수정 0. 발주·task CLI 0. 이전 회차 결과를 모른다고 가정하고 ★전건을 처음부터 잰다.
★「미구현(발주 대기)」로 적을 축(❌ 아님): ⓒ 센서 3종·08:00 감사 행(UC-X4 의 live 큐 route-add·텔레그램 SEV2·감사 표) · ⓓ 플롯 강제 차단 도구 이관(UC-A4) · ⓑ 관리자 결과 ⑵⑶·외형 교체(UC-A2 의 ⑵⑶·외형 교체 · UC-A3). 이 축들은 관측만 적고 판정은 「미구현(발주 대기)」로 쓴다.
★UC-U9 는 폐기 — 밟지 마라(결과표에 「폐기·미실행」로 표기).
★UC-U8 은 rev 3 정정을 따른다: 폼 = 이름·연락처·「본인 또는 정당한 권리자입니다」 체크 3칸이 정본(사진/신분 칸이 없는 것은 ✅). ★체크 없이 「접수」를 누른 경우의 화면 문면을 그대로 적어라(서버 400 `self_declaration_required` 에 대해 화면이 「잠시 후 다시 시도」류 시간 귀책 문구를 내면 ❌).
★UC-U12 는 rev 3/4 로 「검토 중」과 「확정」 두 상태를 잰다: 관리자 ⑴ 확정 전 = 타인 화면 「임시 비공개(검토 중)」 표식만·원인/「위반」 문구 0 · 확정 뒤 = ⓐ 타인 목록에서 빠짐 + 직접 링크 「볼 수 없는 영상입니다」 1줄(원인 0) · ⓑ 제작자 화면 「비공개 처리됨」 표식 1개(원인·「위반」 0) + 누르면 통지 항목(사유·최대 30일·[이의]). 각 상태를 따로 판정한다.

## 환경
- 유저 웹(staging 프리뷰 · 최신 master 번들): WEB=https://staging.yusti.pages.dev  (API https://staging-api.yusti.net · staging DB)
- 관리자 콘솔(검수용 콜드 스타트 · 같은 staging DB): ADM=http://127.0.0.1:3009 · 그 콘솔의 본서버 API=http://127.0.0.1:3012
- 재료(fixture): FIXTURE=/private/tmp/claude-501/-Users-inhohur-work-yusti-review/40b6860a-9641-4bbc-8f2e-fc0c6216f104/scratchpad/fixture.json  JSON — users{maker,maker2,reporter,other,admin}.{id,email} · tokens{…}(Bearer 세션 토큰) · videos[{id,clipId,tag,publicCode}] (tag vMinor/vRights/vKeep/vExtra = maker 것 · vBlock = maker2 것) · charId(maker 가 만든 유스티언·캐릭터) · plotSlug(yd-yuseoa) · plotId
- 브라우저 로그인 방법(앱 로그인이 남기는 그 키 그대로): Playwright(`require("playwright")` · cwd /Users/inhohur/work/yusti-review) 새 context(viewport 420×900) 에 `addInitScript` 로 `localStorage.setItem("yusti_auth", JSON.stringify({mode:"google", token:<그 계정 token>}))` 을 심고 WEB 을 연다.
- API 직접 호출이 필요할 때: `Authorization: Bearer <token>` (staging-api). 단 판정의 1차 근거는 화면이다 — API 는 화면이 부른 것을 확인하는 보조. 화면 대신 API 로 잰 칸은 「대체 측정」이라고 표기한다.
- 관리자 콘솔 로그인(앱 [관리자] 버튼과 같은 핸드셰이크): `API=http://127.0.0.1:3012 ADM=http://127.0.0.1:3009 bash /private/tmp/claude-501/-Users-inhohur-work-yusti-review/40b6860a-9641-4bbc-8f2e-fc0c6216f104/scratchpad/admin-cookie.sh /private/tmp/claude-501/-Users-inhohur-work-yusti-review/40b6860a-9641-4bbc-8f2e-fc0c6216f104/scratchpad/fixture.json > /private/tmp/claude-501/-Users-inhohur-work-yusti-review/40b6860a-9641-4bbc-8f2e-fc0c6216f104/scratchpad/cookie.txt` → Netscape 쿠키 파일. Playwright 에선 그 쿠키(name/value · domain 127.0.0.1 · path /)를 context.addCookies 로 심고 ADM 을 연다. curl 은 `-b /private/tmp/claude-501/-Users-inhohur-work-yusti-review/40b6860a-9641-4bbc-8f2e-fc0c6216f104/scratchpad/cookie.txt`.
- staging DB 읽기(대조용·읽기만): `psql "$(cat /private/tmp/claude-501/-Users-inhohur-work-yusti-review/40b6860a-9641-4bbc-8f2e-fc0c6216f104/scratchpad/stg.url | sed -E 's/uselibpqcompat=[^&]*&?//; s/[?&]$//')" -Atc "<SELECT>"` — 표: content_reports(id,reporter_id,target_kind,target_id,reason,status,resolution,sla_due,legal_due,reporter_contact,resolved_at,routed_task) · user_notices(id,user_id,kind,ref_kind,ref_id,payload,read_at) · channel_blocks(user_id,blocked_user_id) · video_library(id,is_public,hidden_by_company_at,hidden_reason,public_code)
- ★DB 쓰기는 하지 마라(UC-X4 SLA 초과 드릴처럼 시각 조작이 필요한 칸은 ⚠ 로 두고 「무엇이 있어야 볼 수 있나」를 적는다). 예외: 없음.
- SHOTS=/private/tmp/claude-501/-Users-inhohur-work-yusti-review/40b6860a-9641-4bbc-8f2e-fc0c6216f104/scratchpad/shots  (mkdir -p)
- 진입 URL(대본 UC-U0 의 문): 제작자 목록 = `${WEB}/plot/${plotSlug}/videos/${maker.id}` · 플롯 페이지 = `${WEB}/plot/${plotSlug}` · 캐릭터 페이지 = `${WEB}/character/${charId}` · 채널 = `${WEB}/channel/${maker.id}` · 마이 탭 = `${WEB}/my` · 알림 = `${WEB}/my/notices` · 관리자 신고 탭 = `${ADM}/reports`(사이드바 「🛡 신고」)
- 화면 요소는 data-testid 가 있으면 그것을, 없으면 보이는 텍스트로 찾는다. 404·401·빈 화면은 「없다」의 증거가 아니라 「내가 틀렸을 수 있다」의 신호다 — 다른 진입(플롯 페이지 하단 「더보기」 등)을 한 번 더 시도한 뒤 판정한다. 브라우저 pageerror/console error 는 관리자 화면에서 반드시 수집해 결과에 적는다.

## 권장 순서(대본 순서를 지키되 재료 소모가 겹치지 않게)
1. 신고자(reporter)로 UC-U0→U1→U2→U3(vMinor 에 ①) → U12「검토 중」 상태(other 계정으로 vMinor 표식 대조 + 신고 안 된 vKeep 엔 표식 0 + maker 계정 화면) → U6(vMinor 재신고 — 영상 축에서 관측 불가면 캐릭터 축으로도 잰다) → U8(vRights 에 ② — 먼저 체크 없이 접수 눌러 문면 기록 → 체크 후 접수) → U4(vBlock 에 ③ = maker2 채널 차단) → U5(마이 탭 해제) → U7(캐릭터 페이지 신고 → 같은 날 재신고).
2. 관리자: UC-A0→A1(접수 목록에 위 신고들이 사유·대상·접수시각·SLA·상태로 뜨는가 · pageerror 0 인가)→A2(결과 선택지 — 유지/⑴/⑵/⑶/외형 교체 중 실제로 있는 것)→ vMinor 신고에 ⑴ 비공개 확정(사유 입력) · vRights 신고는 「유지」 → A3(⑵ 가 있으면 vExtra 신고를 만들어 실행 · 없으면 미구현 표기) → A5(자동 검사 참고 자료 칸).
3. 교차: X1(접수 즉시 임시 비공개 + ops 큐 task — 큐 task 는 DB `routed_task` 칸과 화면 상태로만 관측·큐 CLI 0) → X2(신고자·만든 사람 통지: reporter 는 U10 「비공개 처리됨」/「기준 충족·유지」+[이 채널 차단] · maker 는 U11 임시 비공개 알림+[이의]) → U12「확정」 상태(other 목록·직접 링크·maker 표식) → X3(maker [이의] → 관리자 목록에 reopen) → X4(미구현 축 표기 + 관측).
4. 유저 잔여: U13(공개 표면에 유저 지정 이름·자유 텍스트 0 — 채널명·제목이 정전 공식 이름인가) · U14(다운로드 버튼 0 · 비로그인 컨텍스트로 공개 영상 URL/목록 열면 로그인 요구) · U15(공개 영상 메타에 고유번호 6~8자 1줄) · U16(플롯 상세 메뉴에 「신고」「차단」 없음 · 마이 탭 1:1 문의 카테고리에 「신고」 없음 · 플롯 상세 owner 「강제 차단」 카드 없음 — owner 카드는 admin 토큰이 owner 가 아니므로 「관측 한계」면 그렇게 적는다).
5. A4 = 미구현(발주 대기) 관측만.

## 결과 형식(그대로 돌려준다)
```
| UC | 판정 | 실측(요청→응답·화면 텍스트) | 비고(결함/미착지/미확정 가르기) |
```
+ 스크린샷 파일 목록 + 건드린 DB 행(신고 id·통지 id·차단 행) + 「못 한 것」과 「안 한 것」 구분 + 한계(픽셀은 못 본다).

## UC 대본(정본 rev 4 전문)
## UC — 공개 영상 신고·채널 차단 (CEO 결정 2026-09-11 20:5x~21:4x · 정본 task t_be815031e5dd body+note 6건)
〔내 실측 2026-09-11 · origin/master〕 신고 진입구 현재 = 플롯 상세 메뉴만(mobile/PlotDetail.tsx:146-165 → server.js:4153 /api/plot/report·block·unblock → plot_reports·plot_blocks 0066). 영상 쪽 신고 진입구 = 0. 영상 공개 행 = video_library(is_public·hidden_by_company_at·hidden_reason, lib/db-client.js:9293). 영상 화면 = mobile/MyVideoLibrary.tsx(현존) + 영상함 S-a~S-e(dev2 t_e0e5df28f668·t_ba7d0c854d57·t_1e09dc0c0d43·t_0c9043c41768·t_0ba3be96bc65 · 미착지 = 「없음·그 발주가 만든다」).

### [유저 창] — 영상을 보는 모든 자리(플롯 영상함·제작자 목록·풀화면 재생·채널 페이지·내 영상집 제외 타인 영상·플롯 하단 스트립)
UC-U0  문 = staging https://staging.yusti.pages.dev 로그인 → 타인이 공개한 영상이 보이는 화면(영상함 S-b/S-c/S-e 착지 뒤 실재)
UC-U1  영상 옆 「⋯」를 누른다 · 전제: 타인 공개 영상 · 기대: 모든 영상 자리에서 같은 위치에 「신고」 1버튼이 보인다
UC-U2  「신고」 → 선택지 · 기대: 정확히 3개 ① 미성년으로 보여요 ② 제 얼굴·이름이에요 ③ 보고 싶지 않아요 (「불법」「기타」 없음)
UC-U3  ① 선택 · 기대: 그 영상이 즉시 내 화면에서 사라지고 「신고한 콘텐츠는 내 화면에서 사라집니다」 1회 표시
UC-U4  ③ 선택 · 기대: 그 제작자(채널)의 공개 영상·유스티언 페이지 노출이 내 화면에서 전부 사라진다(=채널 차단)
UC-U5  마이 탭 차단 목록에서 해제 · 기대: 그 채널 영상이 다시 보인다
UC-U6  같은 영상을 같은 날 다시 신고 · 기대: 버튼 비활성(이미 「검토 중」이면 「검토 중입니다」) · 다음 날부터 가능
UC-U7  유스티언 페이지(유스티언 축)에서 신고 · 기대: 유스티언 1명당 하루 1회 동일 규칙
UC-U8  ② 선택 · 기대: 본인 확인 단계(★이름·연락처·당사자 체크) 입력 후 접수 완료 표시
       ★★[rev 3 정정 2026-09-17 · ★실물 우선 · 검수 1회차 t_7ac0eb411b5b ⚠] 구 문면의 ★「본인 사진 1 또는 신분 확인」은 ★폐기다 —
       ★실물 폼에 ★없고(검수 실측: 이름·연락처·「본인 또는 정당한 권리자입니다」 체크 3칸) ★개인정보 ★최소수집이 ★안전 방향이라 ★되돌릴 이유가 없다.
       ★이 칸을 ★만들지 마라 — ★지금 폼 그대로가 정본이다.
       ★거절 문면 = ★서버 error 코드 ★1:1 사전(체크 없이 접수 = `self_declaration_required` ⇒ ★「잠시 후 다시」류 ★시간 귀책 문구 금지).
UC-U9  ★폐기 2026-09-16(CEO 확정) — 구 문면 *「로그인 없이 「권리침해 신고」 링크 진입 · 기대: 영상 URL 이 자동 첨부된 ② 와 같은 양식」* 은 ★대본이 아니다.
       ★CEO verbatim: *"비로그인자가 권리침해신고를 사이트에서 할리가 있나 유저가 아닌데 이메일주소부터 찾겠지"* + *"클베에서 빼고 백로그로 갈 필요도 없어"*
       ⇒ 슬라이스 발주 t_f3f456c00674 = ★dropped · ★backlog 도 아니다(폐기).
       ★대체 경로 = 운영정책 문면이 같은 회차에 「고객센터 이메일로도 접수」로 낮춰졌다(t_5ccf30487ef5 ⓐ · PR#3071) — ★법문은 그쪽이 든다.
       ★접수 API(server.js:4736 POST /api/content/rights-report)는 ★그대로 산다 — 폐기된 것은 ★비로그인 입구 화면 하나다.
       ★검수 대상 아님(이 칸을 밟지 마라).
UC-U10 신고 24h 안 결과(신고자) · 기대: 「비공개 처리됨」 또는 「기준 충족·유지」+[이 채널 차단] 버튼
UC-U11 내 영상이 임시 비공개됨(만든 사람) · 기대: 즉시 알림(사유·최대 30일·복구/외형 교체·잉크 환급 안내)+[이의] 버튼 1
UC-U12 「검토 중」 영상(모든 유저) · 기대: 「임시 비공개(검토 중)」 표식만·원인 문구 없음·「위반」 문구 없음
       ★★[rev 3 추가 2026-09-17 · pd 판정 t_2b2d356f4158 ⑷ · 검수 1회차에서 ★정본 빈칸이 드러났다]
       ★위 한 줄은 ★「검토 중」 ★한 상태만 적었는데 ★상태는 ★둘이다(검토 중 / ★확정). ⇒ ★확정 뒤를 여기 적는다:
       ⓐ 타인 화면   = ★확정 뒤 ★목록에서 뺀다(「검토 중」 표식은 ★임시 비공개 동안만) · 직접 링크 진입 = 「볼 수 없는 영상입니다」 1줄(★원인 0)
       ⓑ 제작자 화면 = 확정 뒤 「비공개 처리됨」 표식 ★1개(★원인·「위반」 문구 없음 — CEO 제약 그대로) + 누르면 ★통지 목록의 그 항목(사유·최대 30일·[이의])
       ⓒ 서버 술어   = ★한 자리 2값(`lib/media-pass.js` underReviewLocked 옆) — hidden_by_company_at ∧ ★미해소 신고 있음 → reviewing / hidden ∧ 미해소 0 → hidden
                      ★그 미해소 신고 수는 ★확정 경로가 ★이미 센다(`lib/db-client.js:3101~3102`) ⇒ ★새 칸 0
       ★★[rev 4 추가 2026-09-17 · pd 판정 t_96ffa23ab9ac · ★inbox 가 origin/master 에서 좌표 재측정]
       ⓓ ★관리자 ★수동 비공개(★신고 0)도 ★`hidden` 과 ★같은 화면이다 — ★「검토 중」 표식은 ★미해소 신고가 ★있을 때만.
          ★근거 = 화면 상태를 가르는 축은 ★「누가 내렸나」가 아니라 ★「지금 검토가 ★열려 있나」다.
                 ★수동 비공개는 ★사유를 적어야만 내릴 수 있는 ★회사 결정이고(`lib/db-client.js:10555` 「사유를 적어야 내릴 수 있습니다」)
                 ★제작자에겐 ★이미 `source=manual` 통지가 간다 ⇒ ★확정이다. ★신고 확정 경로도 ★같은 함수를 쓴다(`:3084`).
          ★그래서 ★술어는 ★그대로다 — ★「신고 이력」 칸을 ★더하지 않는다(신고가 0이든 해소됐든 ★「검토가 없다」는 ★같은 뜻).
          ★제작자 화면 = 「비공개 처리됨」 + 통지(★`source=manual` · ★사유는 ★관리자 입력 문면을 ★그대로 노출하지 않는다 — ★reason 코드만 · 원인·「위반」 문구 없음 제약 동일).
          ★예외 1 = 관리자가 ★검토 목적으로 잠시 내리려면 ★신고 탭 경로(접수 → 검토 중)를 쓴다 — ★수동 비공개에 ★「검토 중」 뜻을 얹지 마라.
UC-U13 공개 표면(공개 영상·유스티언 페이지·룩북·앨범) · 기대: 유저 지정 이름·자유 텍스트 0 — 정전 공식 이름만(개인 플레이 리네임은 공개 전환 시 벗겨짐)
UC-U14 공개 영상 · 기대: 다운로드 버튼 없음 · 링크는 로그인 필요
UC-U15 공개 영상 메타 · 기대: 영상 고유번호(6~8자) 1줄 노출
UC-U16 플롯 상세 메뉴 · 기대: 「신고」·「차단」 항목 없음 / 마이 탭 1:1 문의 카테고리에 「신고」 없음(기타로 흡수) / 플롯 상세의 owner 「강제 차단」 카드 없음

### [관리자 창] — 「신고」 탭(admin 콘솔 https://macstudio.tailc38d4e.ts.net:8444 · 사이드바 신설 항목)
UC-A0  문 = 관리자 로그인 → 사이드바 「신고」
UC-A1  접수 목록 · 기대: 사유·대상 영상/유스티언·접수 시각·SLA 남은 시간·상태(received/reviewing/resolved)
UC-A2  검토 → 결과 선택 · 기대: 유지 / 비공개 확정 단위 3단 ⑴ 이 영상만 ⑵ 이 유스티언 전부 ⑶ 이 채널 전부 / 외형 교체
UC-A3  ⑵ 선택 · 기대: 그 유스티언 공개 영상 전부 「검토 중」+임시 비공개 · 영상화 잠금 · 만든 사람 전원 알림 · 주연 플롯 신규 노출 중단은 사람 확인 1회 버튼
UC-A4  플롯 강제 차단(구 PlotDetail owner 카드 기능) · 기대: 이 콘솔에서 사유 입력 후 동일 동작
UC-A5  자동 검사 결과 · 기대: ① 신고 행에 외견 미성년 검사 결과가 참고 자료로만 붙는다(게이트 아님)

### [교차]
UC-X1  유저 ① 또는 ② 접수 → 관리자 · 기대: 접수 즉시 그 영상 임시 비공개 + ops 큐 task 1건(dedup = report id) · 반영 = 즉시(다음 조회부터)
UC-X2  관리자 resolved → 유저 · 기대: 신고자·만든 사람 양쪽 통지 자동 · 반영 = 다음 앱 조회(실시간 푸시 아님)
UC-X3  만든 사람 [이의] → 관리자 · 기대: reopen 되어 목록에 다시 뜬다
UC-X4  SLA 24h 초과 또는 ② 접수 · 기대: live 큐 route-add(초과 알람) · ② 는 텔레그램 SEV2 1회
