af-social-scanner — 문서 인덱스

이 프로젝트의 소셜 데이터 수집 파이프라인(Twitter·TikTok·Instagram·Reddit·YouTube·GitHub·Telegram·Website)에 대한 공식 문서가 지금 무엇이고 어디 있는지 답하는 페이지다. 새로 합류한 팀원, 오랜만에 돌아온 자신을 위한 진입점이다.

①문서가 왜 세 곳으로 나뉘는가

이 저장소의 문서는 성격이 다른 세 그룹으로 나뉜다. 이 페이지는 그중 guides/(공식 문서)를 위한 진입점이고, 나머지 둘은 필요할 때만 찾아가면 된다.

🟢 guides/ — 공식 문서
지금 코드의 근거이거나, 코드가 직접 인용하거나, 앞으로도 계속 갱신돼야 하는 문서. 이 페이지가 다루는 대상이다. 새 기능이 기존 설계를 바꾸면 여기부터 고친다.
⚪ docs/features/ — 개발 이력
기능을 만들면서 생긴 착수 문서·작업 로그·초안. 그 작업이 있었다는 기록으로서 가치가 있을 뿐, 더 이상 갱신되지 않는다. "왜 이렇게 됐나"가 궁금할 때만 연다.
🔴 docs/archive/ — 폐기됨
더 최신 문서로 명시적으로 대체된 것들(예: 스키마 v4). 대체 문서 매핑표가 있다. 참고 이상의 용도로 쓰지 않는다.
2026-08-14 문서 정리에서 docs/features/ 200개 문서를 전수 조사해 이 세 그룹으로 나눴다. 물리적으로 폴더를 옮긴 것은 guides/로 이동한 것(공식화)과 archive/로 이동한 것(폐기) 뿐이고, 나머지는 docs/features/에 그대로 있다.

②소셜 레코딩 파이프라인 구조

token.flow 이벤트 하나가 들어와서 소셜 데이터가 DB에 저장되기까지, 실은 시간순으로 쌓인 4개 계층과 4개 서브시스템을 거친다(2026-08-19에 AF 수요 기록이 더해졌다). 이름이 비슷해 헷갈리기 쉬워 관계를 다이어그램으로 남긴다.

flowchart TD
    SP["social-sync-pipeline
전송 계층
token.flow 큐 구독 · DTO 파싱 · 저장 없음"] SCHEMA["social-schema-definition
스키마 계층
contents·accounts·venues·token_links 정의"] RP["social-recording-process
오케스트레이션 계층
dedupe → lock → Generator 라우팅 → 저장"] RC["reconcile-token
배치·복구 계층
/reconcile · /retry(1시간 크론)"] AUDIT["social-url-structure-audit
8소셜 URL 구조 실측 감사"] GEN["social-generator
8소셜별 fetch → 스키마 객체 변환"] E1["social-url-entry
URL 유입 창구 일원화"] E2["social-url-dedupe
재사용 캐시(TTL 14일)"] E3["lock-before-execute-recording
토큰 단위 동시성 락"] REFACTOR["social-recording-refactor
전체 관통 사후 수선"] SP --> RP SCHEMA --> RP RP --> RC AUDIT --> GEN GEN --> RP E1 --> E2 --> E3 E3 --> RP REFACTOR -. 검증·수정 .-> SCHEMA REFACTOR -. 검증·수정 .-> RP classDef layer fill:#3b6cff22,stroke:#3b6cff,stroke-width:1.5px; classDef sub fill:#1a9c5322,stroke:#1a9c53,stroke-width:1.5px; classDef refactor fill:#b8720a22,stroke:#b8720a,stroke-width:1.5px,stroke-dasharray:4 3; class SP,SCHEMA,RP,RC layer; class AUDIT,GEN,E1,E2,E3 sub; class REFACTOR refactor;
4계층은 중복 재설계가 아니라 실제로 쌓인 순서다 — app.module.ts가 셋을 같은 큐(token.flow)에 동시에 물린다 — sync-pipeline · recording-process · demand-metrics(2026-08-19). setHandler가 push라 전부 호출되고, dispatch가 핸들러마다 격리한다. 각 계층의 정본 문서는 §3~④의 표에서 링크된다.

Generator 실행 결과 → URL 상태(FetchStatus) 전이

③의 8개 Generator 중 하나가 URL 하나를 처리한 결과가 이 상태들 중 하나로 떨어진다. 재시도·크론이 그중 어떤 상태를 다시 여는지도 여기서 정해진다 — 정본은 verification-runbook.md §7.

stateDiagram-v2
    [*] --> pending : 신규 토큰의 URL 목록 선생성
    pending --> ok : 객체를 확정했다
    pending --> not_found : 불렀는데 대상이 없다
    pending --> blocked : 대상 쪽 사정(비공개·초대전용·IP차단)
    pending --> invalid : 200을 받았는데 응답이 계약을 깼다
    pending --> error : 외부 호출 실패 · DB 일시 오류
    pending --> unsupported : 담당 Generator가 없다(호출 0회)
    pending --> skipped_paid : 유료라 안 불렀다(호출 0회)

    not_found --> ok : 재시도로 결과가 바뀐다
    blocked --> ok : 차단이 풀린다
    error --> ok : 일시 오류가 지나간다
    error --> exhausted : attempts가 MAX_ATTEMPTS(5)에 닿았다

    ok --> ok : TTL(14일) 만료 후 재수집 — points가 쌓인다
    unsupported --> ok : 담당 Generator가 생기면
    skipped_paid --> ok : 유료 게이트를 켜면

    invalid --> [*] : 100% 같은 실패다 — 배치가 명시적으로 열어야 한다
    exhausted --> [*] : 상한에 닿았다 — 배치가 명시적으로 열어야 한다
    
⚠️ unsupported·skipped_paid는 attempted_at이 없어 재시도 백오프를 원리적으로 통과하고, 다시 처리해도 같은 값이 나온다 — 이 둘이 열리는 조건은 거래가 아니라 배포다(Generator를 새로 만들거나 유료 게이트를 켜는 것).
계층/서브시스템정본 문서한 줄 요약
전송docs/features/social-sync-pipeline/be-system-design.mdtoken.flow 구독 + DTO 파싱. 저장 없음(아직 guides로 옮기지 않음 — §7 참고)
스키마schema.htmlcontents·accounts·venues·token_links·metric_series 필드 명세(v5, 2026-08-14 정정 포함)
오케스트레이션service-overview.mdas-built 요약. 설계 시점 문서(HTML 4종)는 docs/features/social-recording-process/에 이력으로 남음
배치/복구reconcile-token.md/reconcile(과거 토큰 채움) · /retry(실패 URL 재시도, 크론)
발행 이벤트(소비자용 계약)social-recorded-event.md이 서비스가 발행하는 유일한 이벤트 token.social.recorded. 한 토큰의 소셜 기록이 수렴하면 토큰당 1회. exchange 를 우리가 소유하는 첫 사례이고, 큐는 소비자가 만든다. ⚠️ 전이 판정이라 이미 수렴해 있던 토큰은 발행되지 않는다
Generator 8종③ 표소셜별 fetch → Content/Account/Venue 변환
URL 처리 정책url-pipeline.html정규화 → 분류 → fetch 단계별 계약. URL 문자열을 누가 언제 고칠 수 있는지의 정본
URL 3부작url-entry · url-dedupe · lock유입 창구 일원화 → 재사용 캐시(TTL 14일) → 토큰 단위 동시성 락
URL 기록 상태(FetchStatus) state machineverification-runbook.md §7pending→ok/not_found/blocked/invalid/error/unsupported/skipped_paid→exhausted 전이 규칙. tokens.social_urls[].status 어휘의 정본
AF 수요 기록docs/features/af-demand-metrics/ · service-overview.md같은 token.flow를 구독하는 세 번째 핸들러가 tokens.demand(AF 지표 5 + 시가총액 5)를 병합한다. 시가총액은 두 번째 큐(token.price_tracker.update)에서도 들어오고, 두 소스가 부딪히면 가격추적 세션이 이긴다
사후 수선docs/features/social-recording-refactor/런타임 결함 대장(H-*) · 구조 개편(R-*) · 스키마 재확정
횡단 결정 + 인덱스decisions.md · index-audit.html8소셜 공통 규칙(G-1~21) · 인덱스 26개 감사
통합 검증(살아있는 도구)verification-runbook.md · verification-rubric.md실제 소셜 API 응답으로 6개 컬렉션 저장을 검증하는 반복 실행 도구. 스크립트·결과물은 docs/features/recording-integration-verification/(경로 의존이라 그대로 둠)
수동 QA(비개발자용)token-inspector-review-checklist.html백필 전후 token-inspector.html을 사람이 눈으로 훑는 체크리스트. 자동 감사(production-recording-audit)가 원리적으로 못 잡는 의미상 중복·화면 정합성만 다룬다

③소셜별 Generator 스펙 8종

어느 소셜이 어떤 벤더로 뭘 만드는지. 단가는 세션 내 실측 비용분석 근거(apify-cost-model.html) 기준.

소셜문서소스 벤더상태핵심 특징
Xx.md twitterapi.io ($0.15~0.20/1000)완료Creator+Content+Venue 전부 갖는 유일한 소셜. 인용/리트윗 사슬 fan-out(깊이 2)
YouTubeyoutube.md무료 Data API v3완료실호출 15 unit 검증. 구독자 큰 채널은 3자리 유효숫자로 반올림돼 옴
Telegramtelegram.md무료 HTML 파싱완료Venue 전용, Content 없음. 가드 포털 재사용 실측(근거)
GitHubgithub.md무료 GitHub API완료repo/owner. fork·archived 플래그로 스캠 위장 탐지
TikToktiktok.md Apify ($0.0047/건)완료프로필/게시물 응답이 같은 평면 구조라 추가 호출 0회
Instagraminstagram.md Apify ($0.0027~0.0054/건)완료게시물 조회 시 작성자 프로필 보충콜 1회 추가
Websitewebsite.md무료 HTTP GET완료sourceType(호출 전)과 패턴(응답 후) 이중 축. 실호출 검증 완료(23토큰)
Redditreddit.md Apify ($0.022/건, 전체 최고가)완료Content/Account를 의도적으로 안 묶음(V-2) — 작성자가 대개 공용 밈 서브레딧의 일반 유저

④근거자료 — 코드가 직접 인용하는 문서

아래는 social-url-structure-audit(8소셜 URL 구조 실측 감사)에서 나온 산출물 중, 지금도 fetcher/generator 코드 주석이 직접 인용하는 것만 추렸다. 코드를 고치기 전에 먼저 봐야 하는 문서다.

문서플랫폼코드가 인용하는 곳성격
x.htmlXx/x.types.tssourceType·필드 확정 통합뷰
youtube.htmlYouTubeyoutube/youtube.types.ts동일
github.htmlGitHubgithub/github.types.ts동일
instagram.htmlInstagraminstagram/instagram.types.ts동일
tiktok.htmlTikToktiktok/tiktok.types.ts동일
reddit.htmlRedditreddit/reddit.types.ts (직접 인용 — scaffold JSON 없는 유일한 소셜)동일
website-kinds.htmlWebsitewebsite.consts.ts도메인 5종 분류(툴·소셜·디렉터리·참조·사이트)
website-content-mapping.htmlWebsitewebsite.generator.tsContentInput 추출 규격(패턴 7개)
website-pipeline.htmlWebsite워킹트리 diff와 실시간 대조됨파이프라인 15단계 현황(구현/미구현/제안)
website-qna.mdWebsite위 세 문서의 결정 기록지속 갱신되는 Q&A
website-image.htmlWebsitewebsite.fetcher.ts · RDAP · urlscan도메인 지문 17필드 — 각 필드에서 무엇을 추론하나 · 3분할 실측
website-shell-fingerprint.htmlWebsite실험 실측 (2026-09-01)셸 지문 5축(robots·헤더순서·style·TXT·이미지 인코더) — 왜 축이 되나 · 묶임률 39%
apify-cost-model.htmlTikTok·Instagram·RedditApify 실측 usageTotalUsd단가 모델 — Reddit이 비용의 66%
telegram-guard-reuse.htmlTelegramtelegram.fetcher.ts가드 포털 재사용 3종 실측(69채널)
감사 원본 전체(브레인스토밍 과정 포함)는 docs/features/social-url-structure-audit/에 이력으로 남아 있다. 위 12개는 그중 지금도 코드가 참조하는 것만 추린 것이다.

외부 근거 — 우리가 통제하지 않는 시스템의 규칙

위 감사가 「우리 fetcher 가 무엇을 받는가」라면, 이쪽은 「저쪽이 어떻게 동작한다고 문서로 밝혔는가」다. 지문·축 판정이 외부 사업자 정책 위에 서 있는 경우, 그 전제가 조용히 바뀌면 판정이 통째로 무효가 되는데 코드도 데이터도 알려주지 않는다. 그래서 확인일과 함께 따로 적어둔다 — 규칙은 external-facts/README.md.

문서사업자확인일무엇을 떠받치나
dns-provider-axes.md DNS 제공자 7곳2026-09-09 어느 제공자에서 NS 로 운영자를 가를 수 있나. 널 모델로 검정한 결과 Cloudflare 뿐이다. GoDaddy 는 NS 집합이 40종으로 갈리고 묶임률이 94%(Cloudflare 31%)나 되는데도 그 묶임이 운영자와 무관하다 — 등록기관일 뿐이라 DNS 와 배포가 안 묶인다. 새 제공자를 축으로 쓰려 하기 전에 여기부터 볼 것
cloudflare-nameservers.md Cloudflare2026-09-09 NS 쌍을 운영자 식별자로 쓰는 근거. 계정 단위로 일관성을 «의도적으로» 맞추고, 생성 후에는 지원팀도 못 바꾼다 — 사후 세탁이 불가능해 워터마크 조건을 만족한다. 공장 그룹화(F-02·F-03)가 여기 얹혀 있다
vercel-hosting.md Vercel2026-09-09 계정 흔적이 «없다» 는 기록. NS 가 376곳 전 고객 공용이라 Cloudflare 식 코호트가 안 된다 — 안 적어두면 같은 축을 또 시도하게 된다. 대신 canonical 에 남은 프로젝트 이름으로 F-04(20곳). NS·헤더 값·CSP·쿠키·TXT·CNAME 까지 다 봤다는 기록

⑤일반 엔지니어링 가이드

소셜 레코딩 파이프라인에 국한되지 않는, 프로젝트 전반의 규칙.

Generator 루브릭
8소셜 Generator가 공통으로 지켜야 하는 R-1~R-18 · token_links 정책
소셜 생성기 착수 프로세스
새 소셜을 추가할 때 뭘 먼저 판단해야 하는지
OOP Programming Guide
객체지향 설계 원칙
MongoDB Schema & Performance Guide
스키마·인덱스·성능 일반 규칙
NestJS SDK Implementation Guide
외부 SDK 래퍼 작성 규칙
DB 조회 (db-access)
af-db MCP 가 여는 DB 넷과 각각의 안내서, 모집단 고르는 규칙, 훅이 막는 것. 2026-09-15 개명(scanner-db → af-db) 매핑도 여기
Project Mistakes
반복된 실수 패턴 기록
실험 설계 (experiment-design/)
새 실험을 /exp:design으로 열 때 쓰는 것들. 승인받을 때 보는 설계 화면 규격과 샘플 넷, 실행 뒤 파고드는 검증 화면 규칙

⑥개발 이력 — docs/features/

20개 폴더, 252개 문서(2026-08-19 기준 — af-demand-metrics 추가). 전부 완료됐거나 진행 중이던 작업의 기록이고 이제 더 갱신되지 않는다. "왜 지금 이 구조가 됐나"가 궁금할 때만 연다. 폐기된 23개는 docs/archive/에 따로 있다.

fetcher-typing-refactor 24
9개 fetcher를 소셜별 자기 타입으로 분리. Telegram·Website 일부 미결
image-asset-fields 14
Content.media_urls·Account.avatar_url 신설, 완료
lock-before-execute-recording 2
정본은 guides로 이동. signatures 등 이력만 남음
narrative-grouping 1
토큰 소셜 콘텐츠를 내러티브 단위로 묶는 설계, 미착수
reconcile-token 12
배치/복구 계층의 HTML 설계문서 등. 정본은 guides로 이동
recording-integration-verification 5
검증 스크립트·results — 정본(runbook·rubric)은 guides로 이동, 경로 의존 있는 것만 남음
social-generator 7
backlog.md + 8소셜 kickoff.html. 정본은 guides로 이동
social-recording-process 12
오케스트레이션 계층 설계 시점 기록. 정본은 guides/service-overview.md
social-recording-refactor 4
파이프라인 전체 사후 수선(R-*·H-*)
social-schema-definition 10
스키마 v3→v4 이력. 정본(v5)은 guides로 이동
social-sync-pipeline 15
전송 계층 설계(token.flow 큐 구독)
social-url-dedupe 2
정본은 guides로 이동. signatures 등 이력만 남음
social-url-entry 1
backlog.md만 남음. 정본은 guides로 이동
social-url-structure-audit 26
8소셜 URL 구조 감사. 정본 다수는 guides/audit-sources로 이동, 나머지는 브레인스토밍 이력
token-image-fields 10
Token.image 필드 설계·구현, 완료
token-image-url-audit 1
Token.image 4계층 추출가능성 감사

⑦유지관리 — 새 작업이 끝나면

이 페이지는 자동으로 갱신되지 않는다. 수동 관리다.

  1. 새 feature 작업이 "공식 문서" 성격(스키마·운영정책·코드가 인용하는 근거자료)을 만들었다면 — 완료 시점에 그 문서를 guides/(적절한 하위폴더)로 옮기고, 이동 전 상대링크를 원 폴더 기준에서 새 위치 기준으로 고친다. 이 페이지 §2~④ 표에 행을 추가한다.
  2. 기존 공식 문서를 대체하는 새 버전이 나왔다면 — 이전 버전을 docs/archive/로 옮기고 docs/archive/README.md에 대체 사유를 한 줄 추가한다. 이 페이지에서 옛 링크를 새 문서로 바꾼다.
  3. 순수 작업 로그·착수 문서라면 — docs/features/<feature>/에 그대로 둔다. 이 페이지를 고칠 필요는 없다(§⑥은 폴더 단위 요약이라 파일이 늘어도 대개 그대로 맞는다. 폴더 성격 자체가 바뀌면 그때 문구만 수정한다).
  4. 주기적으로 — §④(근거자료) 표의 문서가 실제로 코드에서 아직 인용되는지 가끔 grep으로 확인한다. 인용이 끊겼다면 §⑥ 이력으로 강등하거나 archive로 옮긴다.
아직 guides/로 옮기지 않은 후보: social-sync-pipeline/be-system-design.md(전송 계층 정본), social-recording-refactor/schema-refactor-plan.md(스키마의 "왜"). 스크립트 경로 의존성 때문에 이번 라운드에서는 docs/features/에 남겨뒀다 — 다음 정리 라운드 후보다.

⑧공개 API

외부 서비스가 호출하는 계약. 나머지 엔드포인트는 전부 internal/* 운영 도구이며 계약이 아니다.

Token Social Graph API
GET /api/v1/tokens/{address}/social-graph — 토큰에 걸린 모든 소셜 정보를 URL 단위 묶음으로. 호출하는 쪽이 읽는 레퍼런스(필드·null 조건·함정·레시피). 영문