o2o-site-AEO/solution
hbyang ecafa19d00 [feat] solution/backend,docs: Threads 계정 연동 — 연결 실패 이유를 남기고, 준비 절차를 적는다
자동 게재가 되려면 사장님이 자기 Threads 계정을 연결해야 한다. 연결 코드(인가 URL·코드 교환·
장기 토큰·암호문 저장·해제)는 이미 있었는데, **실제로 연동하려면 무엇을 해야 하는지**가
어디에도 없었고 실패했을 때 이유를 볼 방법도 없었다.

★ 콜백이 예외를 통째로 삼키고 있었다. 화면에는 `?social=failed` 만 뜨고 우리도 원인을 모른다 —
  키가 틀렸는지 · 쿠키가 안 왔는지 · state 가 만료됐는지 구별이 안 된다. 연결이 안 되는데
  로그에 아무것도 없는 것은 이 레포가 가장 싫어하는 종류다.
  → 서버 로그에는 남기고 화면에는 안 내보낸다(OAuth 응답·state 에 자격증명이 들어 있다).
    남기는 것은 예외 종류와 우리가 만든 사유 문자열뿐 — 토큰·code·state 는 찍지 않는다.
    사장님이 인가를 취소한 경우도 고장과 구별되게 따로 남긴다.

- router/v1/social/oauth: 실패 로그 추가(`[social] 계정 연결 실패: …`)
- tests: 가짜 Threads 서버로 **연결 왕복 전체**를 검증한다(코드 교환 → 장기 토큰 → debug_token
  권한 검증 → 저장 → 해제). 실제 연결은 Meta 앱 등록이 끝나야 시험할 수 있는데, 그때 실패하면
  우리 코드가 틀린 건지 앱 설정이 틀린 건지 구별이 안 된다 — 우리 쪽 왕복은 먼저 못 박는다.
  지키는 것 셋: 저장된 것은 암호문이다 · 권한 검증을 건너뛰지 않는다 · 해제하면 토큰이 지워진다
- docs/SOCIAL.md '연동 준비': Meta 앱 콘솔에서 할 일(제품 추가·리디렉션 URI·권한 둘·
  ★심사 전에는 테스터로 추가된 계정만 인가된다) · 사장님 클릭 흐름 · 실패 시 로그 읽는 법
- .env.example: SOCIAL_*·THREADS_*·ALIMTALK_* 항목과 각각의 "비면 무엇이 꺼지는가"

★ 로컬만으로는 연결을 끝까지 검증할 수 없다 — Meta 는 콜백 URI 를 https 로만 받는다.
  터널로 https 주소를 만들거나 킹서버에서 확인해야 한다. 문서에 적어 뒀다.
★ `SOCIAL_TOKEN_SECRET`(Fernet) 이 없으면 연결 기능 자체가 꺼진다. 이 키를 잃으면 저장된
  토큰을 복호화할 수 없어 전원 재연결이다 — 그 사실도 문서에 적었다.

검증: SNS 테스트 14건 통과(신규 1 — 연결 왕복). 로컬에서 키만 넣고 앱 자격증명이 없는 상태를
확인: connection_enabled=false 로 버튼이 안 뜨고, 강제로 불러도 409 SOCIAL_CONNECTION_DISABLED

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 16:08:22 +09:00
..
backend [feat] solution/backend,docs: Threads 계정 연동 — 연결 실패 이유를 남기고, 준비 절차를 적는다 2026-09-14 16:08:22 +09:00
frontend [feat] solution,postgres-init,docs: SNS 게재 — 사장님이 누르면 쓰고, 승인받아, 사장님 계정으로 올린다 2026-09-14 15:46:44 +09:00
shared [feat] solution,postgres-init,docs: SNS 게재 — 사장님이 누르면 쓰고, 승인받아, 사장님 계정으로 올린다 2026-09-14 15:46:44 +09:00
site [feat] solution,postgres-init,docs: SNS 게재 — 사장님이 누르면 쓰고, 승인받아, 사장님 계정으로 올린다 2026-09-14 15:46:44 +09:00