학생 초대 디자인 명세¶
요지¶
화면은 두 쪽으로 나뉜다. 선생님 쪽은 링크를 켜고·복사하고·만료하는 단순한 컨트롤이고, 학생 쪽은 /invite로 받는 초대장 카드와 그 뒤로 갈리는 성공·에러 화면이다. 링크를 카카오톡 등으로 주고받는 상황이 대부분이라 모바일 공유 경험을 가장 먼저 챙긴다.
상위 PRD¶
요구사항과 범위는 prd, 라우팅·토큰·API는 frd, 도메인은 studyroom·member.
사용자 플로우¶
- 선생님: 스터디룸 내 초대 링크 토글(ON 생성/OFF 삭제) + 복사 + 수동 만료.
- 학생: 초대장 페이지(
/invite?token=) → 상태별 분기.
링크 클릭 → /invite
├ 로그인 학생 → 초대장 → [수락] → /invite/success
├ 비로그인(기존) → /login → 복귀 → 수락
├ 미가입 → /register → 복귀 → 수락
└ 만료/종료/잘못된 링크 → /invite/error?reason=...
화면 · 컴포넌트 (Figma 링크)¶
- 초대장 카드(raw §5.1): 상단(스터디룸 이름·선생님 이름), 본문("○○ 선생님의 스터디룸에 초대되었어요" + 수락 유도 문구), 하단([수락하기] CTA, 선택 [거절하기] → 홈).
- 성공 페이지 / 에러 페이지(reason: ROLE_NOT_MATCH/ALREADY_PARTICIPATED/CLOSED/EXPIRED_LINK/INVALID_LINK).
- 선생님 측: 초대 링크 활성화 토글(ON/OFF) + 복사 버튼(토스트 "초대 링크가 복사되었어요.") + 상태 표시(활성/만료됨). 보조 문구 — 활성 "링크를 통해 학생이 바로 참여할 수 있어요", 만료 "이 링크는 더 이상 사용할 수 없어요".
- 카드·버튼 토큰은 design-system을 따른다. 화면 실제 에셋은 원본(Notion)에 있다.
인터랙션 · 상태¶
토큰이 만료되면(401) 먼저 리프레시로 재발급을 시도하고, 그래도 안 되면 비회원 흐름으로 넘긴다. 어떤 경우든 상황에 맞는 에러를 보여준 뒤 홈으로 보내고, 가입·로그인을 마치면 끊겼던 초대 흐름으로 자동으로 되돌린다.
문구는 상황마다 미리 잡아 뒀다. 초대받은 학생이 헤매지 않도록, 로그인 유도부터 만료·잘못된 링크·보호자 차단까지 각각 다른 말을 보여준다.
| 맥락 | 문구 |
|---|---|
| 링크 OFF 전환 | "이 링크를 만료하면 더 이상 학생이 링크로 참여할 수 없어요." |
| 링크 ON 전환 | "새 초대 링크가 생성되었어요." |
| 로그인 전 | "스터디룸에 참여하려면 로그인이 필요해요" |
| 회원가입 유도 | "디에듀 회원이 되면 바로 스터디룸에 참여할 수 있어요" |
| 수락 완료 | "스터디룸에 참여했어요!" (+ 활동 동기부여) |
| 수동 만료 링크 | "이 초대 링크는 만료되었어요." → 홈 이동 |
| 스터디룸 종료 | "종료된 스터디룸이에요." → 홈 이동 |
| 잘못된 링크 | "유효하지 않은 링크예요." → 홈 이동 |
| 보호자 계정 | "학생 계정으로만 참여할 수 있어요" |
접근성¶
링크는 모바일에서 주고받는 게 기본이라 반응형을 가장 먼저 지킨다(원칙은 responsive). 에러와 토스트는 aria-live로 읽어 준다.
개발 핸드오프 노트¶
전달 규약은 dev-handoff, 라우팅·토큰·API는 frd를 본다.