학생 초대 개발 명세 (FRD)¶
요지¶
초대 링크로 학생을 스터디룸에 들이는 흐름을 어떻게 구현하는지 정리한다. 핵심은 세 가지다 — 스터디룸마다 초대장을 딱 하나(Opaque Token)만 두고, 링크를 누른 학생을 다섯 갈래로 나눠 처리하며, 가입·로그인·소셜 리다이렉션을 거치는 내내 초대 토큰을 잃지 않게 한다. MVP-C 기능이다.
상위 PRD (링크 · 변경 시 알림)¶
기획은 prd(바뀌면 이 문서도 갱신), 도메인은 studyroom(룸·정원·멤버)과 member(역할·기가입)다.
기술 접근 · 아키텍처¶
초대장 발급·상태¶
스터디룸당 초대장 1개 관리(1:1 테이블). 발급 기준 = 초대 기능 활성화 AND 스터디룸 운영 기간 모두 만족.
| 상태 | 설명 |
|---|---|
| Active | 정상 사용 가능 |
| Expired | 선생님 수동 만료 |
| Disabled | 스터디룸 삭제/비활성 |
- 토큰: Opaque Token(UUID) + 방 고유 식별자, RDB 검증(Stateless 미사용, 무결성 우선).
- 토글: OFF→ON = 새 토큰 생성, ON→OFF = 기존 토큰 삭제.
- 유효성: 토큰 형식 X →
Invalid/ 식별자 미존재 →Expired/ 통과 →Active. (랜덤 UUID 조회 특성상 스터디룸 미존재와 만료는 모두Expired로 처리.) - 수명주기 훅: 스터디룸 생성 시 초대장 생성, 삭제 시 Cascade 삭제.
학생 분기 처리¶
| Case | 처리 |
|---|---|
| 이미 로그인 학생 | 초대장 UI → [수락] → 즉시 입장 |
| 비로그인(기존 회원) | 로그인 페이지 → 로그인 후 초대장 → 수락 → 입장 |
| 미가입 사용자 | 회원가입 유도 → 가입 후 초대장 → 수락 → 입장 |
| 이미 가입한 학생 | 예외 메시지 → 스터디룸 조회(수업노트 탭) |
| 만료/종료/잘못된 링크 | 상황별 메시지 노출 → 홈 이동 |
기존 회원 수락 시 도메인 검증 순서: 역할(학생) → 기가입 여부 → 스터디룸 유효성(존재/활성) → 정원 초과. 통과 시 기존 초대 로직으로 멤버 추가(알림 포함). 보호자 계정은 역할 검증에서 차단.
토큰 유지 (신규 회원)¶
회원가입/로그인 및 소셜 리다이렉션 시 초대 토큰 유지 → 가입 직후 초대장 노출.
- 이메일 회원가입: FE가
inviteToken저장 → 가입/로그인 성공 후 저장 토큰으로 수락 API 자동 호출. - 소셜 로그인: OAuth 시작 시
state=inviteToken:{token}포함 → 콜백에서 BE가state의 토큰 감지 → JWT 쿠키 설정 후 리다이렉트: 기존 회원 →/dashboard?token={inviteToken}, 신규 회원 →/select-role?token={inviteToken}. FE가 URL에서 토큰 읽어 수락 API 자동 호출 → 스터디룸 이동. (소셜 로그인 개발 명세 (FRD) 연계) - 토큰 만료(401): 리프레시 재발급 시도 → 실패 시 비회원 플로우 합류.
- inviteToken 없을 시: 로그인/가입 후 홈 이동.
API · 데이터 모델¶
API는 세 개로 갈린다 — 누구나 볼 수 있는 초대장 조회, 로그인한 학생만 부르는 수락, 그리고 소셜로 들어온 학생을 위한 콜백이다.
| 구분 | 엔드포인트 | 비고 |
|---|---|---|
| 초대장 조회(공개) | GET /api/public/study-rooms/invite/{token} |
인증 불필요, 최소 유효성 검증 |
| 회원 수락 | POST /api/student/study-room-invites/{token}/respond |
역할/기초대/정원 순서 검증 후 멤버 추가 |
| 소셜 콜백 | GET /api/auth/{provider}/callback?state={inviteToken} |
state에 토큰 있을 시 수락 API redirect |
Frontend 라우팅:
- 초대장 /invite?token={inviteToken} · 성공 /invite/success?studyRoomId={studyRoomId} · 에러 /invite/error?reason={ROLE_NOT_MATCH|ALREADY_PARTICIPATED|CLOSED|EXPIRED_LINK|INVALID_LINK}
의존성 · 영향 범위¶
스터디룸(studyroom, 초대장 1:1 테이블·Cascade·정원), 회원(member, 역할·기가입), 소셜 로그인(소셜 로그인 개발 명세 (FRD), state 토큰), 회원가입(회원가입 개발 명세 (FRD), 가입 후 복귀)에 걸쳐 있다.
아직 정하지 못한 건 링크별 만료 기한(TTL)이다. 이걸 넣으려면 토큰을 "링크 복사 시"에 발급하도록 바꾸고 Redis 상태관리를 검토해야 한다. 운영이 끝난 스터디룸의 초대 허용 여부도 미결이다.
테스트 계획¶
공통 케이스·E2E 전략은 qa-playbook을 따른다. 이 기능에서 꼭 볼 것은 토글 ON/OFF(새 토큰 발급·삭제), 토큰 유효성 분기(Active/Expired/Invalid), 학생 다섯 갈래(로그인/비로그인/미가입/기가입/만료·종료), 가입·로그인·소셜을 거치는 내내 초대 토큰이 유지되는지, 역할→기초대→정원 순서 검증, 그리고 보호자 수락 차단이다.
선생님·학생 양쪽의 GA 퍼널도 심는다 — 선생님은 링크 생성·만료·복사를, 학생은 클릭부터 조회·수락까지를 따라간다.
작업 분해 (이슈 링크)¶
진행·완료 상태는 status와 GitHub 이슈에서 확인한다.