Skip to content

Latest commit

 

History

History
25 lines (17 loc) · 3.53 KB

spec-alignment.md

File metadata and controls

25 lines (17 loc) · 3.53 KB

감시자 계약 정합화 (2026-09-14)

기준: 공통, 백엔드, 각 최신 API 명세.

변경

  • 감시자 무제한. slots, 무료 한도, 구독 분기, 관계별 PATCH/푸시 컬럼을 제거한다. 초대는 주최자·진행 가능 챌린지·감시자 패널티 ON을 검사하며 201과 status=INVITED를 반환한다.
  • 목록은 watchers만 반환한다. INVITED는 invitationId, ACTIVE는 watcherId와 acceptedAt을 제공한다. 연락처 및 재초대 타이머 필드는 없다.
  • 초대는 AES-256-GCM으로 인증·암호화한 불투명 토큰이다. 챌린지/초대자/7일 만료 클레임은 URL에서 읽을 수 없고, 별도 용도의 JWT 파생 키로 인증한다. DB에는 SHA-256 BINARY(32)만 저장한다. 앱 링크 검사와 공개 미리보기도 같은 검증을 쓴다.
  • 수락은 로그인·본인·현재 사용자 차단·방 상태를 확인하고, 방/관계를 잠가 동시 수락을 직렬화한다. 이미 ACTIVE이면 409. PENDING은 기존 행을 활성화하며 동의 시각과 버전 2026-09-14를 함께 기록한다. 공개 미리보기에 버전을 제공한다.
  • 실패 통지는 이벤트 payload를 신뢰하지 않고 잠근 VerificationDaily의 FAILED·D+2 경계·이의 마감·공유 시각을 재검사한다. 현재 동의와 수락 시각도 확인한다. 관계·인증 UNIQUE로 통지 1회, 통지·감시자 PK로 반응 1회를 보장한다.
  • 사용자 차단은 관계 생성 및 이후 실패 알림에 적용한다. 반응 알림도 수신자의 차단을 존중한다. 관계는 유지한다. 공통 문서의 미결 차단 항목에는 알림 정책의 차단 사용자 미발송 원칙을 적용했다.
  • 푸시는 알림 모듈의 마스터·챌린지 그룹 설정을 따른다. 푸시 OFF도 관계와 알림함 적재는 유지된다.
  • 시간당 누락 보정은 app.watcher.recovery-max-age(기본 PT24H) 안에 확정된 건을 500행씩 조회한다. 누락 보정 유예 상한은 미결이므로 24시간을 기본값으로 택했다. 발송 직전 동일한 검증을 거쳐 오래된 결과·새 감시자에게 과거 실패를 보내지 않는다.
  • 동의/발송/반응/종료/만료 실행 로그는 커밋 후 구조화 필드로 기록한다. 로그 실패는 업무 상태를 롤백하지 않는다. watcher.active.missing.consent, watcher.ended.active, watcher.notices.early를 감시하고 app.watcher.dispatch-enabled=false로 통지를 중단할 수 있다.

배포와 이관

V61은 동의 로그와 관계별 푸시 컬럼을 제거하고 토큰 해시를 바이너리로 바꾼다. 버전 근거가 없는 기존 ACTIVE 관계는 수락 시각을 보존한 PENDING으로 이관한다. 새 초대를 인앱 수락해야 다시 통지 대상이 된다. 기존 관계에서 푸시를 껐던 사용자는 챌린지 그룹 OFF로 보존한다. 구 무서명 토큰은 새 토큰으로 재발급해야 한다.

앱은 생성 201, 새 목록/수락/미리보기 DTO, 알림 설정 경로를 함께 반영해야 한다. 롤백은 구 코드만 되돌려 실행하지 않고, 데이터 보존을 확인한 별도 호환 마이그레이션이 필요하다.

검증

WatcherRelationIT와 AppLinkAndDevTokenIT: 무제한, 관계별 토글 제거, 해시/토큰 검증, 차단·해제, 동시 수락, DB 동의 증적, 잘못된/정정된/조기 실패 이벤트 차단, 푸시 OFF 알림함 유지, 누락 보정 시간 제한, 통지·반응 중복을 검증한다.