스터디룸 FRD¶
스터디룸(StudyRoom)의 생성·초대·조회·대시보드 진입을 어떻게 구현하는지 정리한다. 교사가 개설해 수업 로그를 모아보는 공간이고, 접근은 인증 사용자로 제한한다(미인증은 /login, 강사가 아니면 /dashboard로 리디렉션). 상위 기획은 prd에 있으며, 거기서 구성요소·정책이 바뀌면 아래 API·데이터 절을 맞춰야 한다. 추후 상호작용 공간으로 넓혀갈 여지를 남겨둔다.
기술 접근 · 아키텍처¶
도메인 구성요소¶
| 구성요소(* 생성 필수) | 제약 |
|---|---|
| 스터디룸 이름* | 30자(공백 포함), 수정 가능, ph "삼각함수 1-1 수업" |
| 설명 | 90자(공백 포함), TipTap 에디터, 수정 가능 |
| 공개 범위* | PUBLIC(default, 비회원 포함) / PRIVATE(초대자만) |
| 참여 학생 수 | 보호자 제외, 학생만 카운트 |
| 시작/종료날짜 | 시작=생성시점 default, 종료=없음. MVP1 프론트 미노출 |
CRUD 권한: 교사 전부 O. 학생/보호자/전체(비회원) = R만 △(교사 권한 부여).
생성 (Step-by-step Wizard)¶
진행률 UI(스텝퍼) 필수. API 호출은 Step 2 제출 시 1회(Step1+Step2 병합). 임시저장은 Spec-Out(새로고침 데이터 유지 미보장).
- Step 1 — 기본 정보: 이름/공개범위(필수)+설명(선택). 로컬 검증·상태저장만, 서버 호출 없음. 검증
V-SR-01(이름 EMPTY)V-SR-02(이름 MAX 50)V-SR-03(공개범위 필수)V-SR-04(설명 MAX 300 plaintext)V-SR-05(미지원 마크). - Step 2 — 수업 정보(필수): 온/오프라인 · 1:1/1:N · 과목(국/영/수/기타) · 대상학년(RadioGroup/Select).
생성하기또는건너뛰기로 활성.V-SR-11(미선택). - 완료 모달: 버튼 A
학생 초대하기→/studyrooms/{id}/invite-member, 버튼 B스터디룸으로 이동→/studyrooms/{id}. Radix Dialog, 포커스 트랩.
초대¶
- 경로
/studyrooms/{id}/invite-member(URL 직접 접근 시/dashboard리디렉션). 권한: 인증+해당 룸 강사. 진입 시invitees=[]초기화. - 이메일 검색(Combobox/Popover, Enter 실행) → option 클릭→칩 추가(1명+ 시 CTA 활성) →
초대하기(전송 중 "초대 중…"). 연결된 보호자 자동 입장. - 검증
V-INV-01(EMPTY)V-INV-02(NOT_FOUND)V-INV-03(DUPLICATE).
라우팅 개편 (Revision Notes §5)¶
- 홈 라우트
/studyrooms/{id}/studynotes→/r/{publicId}/dashboard교체. 기존 경로는 301 리디렉션. - publicId(ULID/nanoid) 컬럼 추가 — 외부 URL에 내부 numeric ID 미노출(ex
/r/01HZY8BFC3K4F/dashboard). - 학생–보호자 연동 구조 도입(§5.2)은 Pending(취소선) 처리.
API · 데이터 모델¶
| 구분 | Method | Endpoint |
|---|---|---|
| 스터디룸 생성(최종) | POST |
/api/teacher/study-rooms |
| 사용자 검색(초대) | GET |
/api/teacher/study-rooms/{studyRoomId}/search |
| 초대 발송 | POST |
/api/teacher/study-rooms/{studyRoomId}/members |
| 대시보드 요약 | GET |
/study-rooms/{publicId}/dashboard-summary |
Status Code
- 생성: 201(완료 모달) / 400(형식·정합성) / 401·403(인증·권한) / 500(서버).
- 초대: 202(성공·이동) / 400 / 401 / 403(강사 외 차단) / 404 / 409(중복) / 429(과다) / 500(AlertDialog). 초대 성공 → /studyrooms/{id}/studynotes(라우팅 개편 후 /dashboard).
Request/Response 예시는 원본 미작성 — 구현 시 확정.
트래킹 이벤트
| 이벤트 | 시점 |
|---|---|
room_create_submit |
생성하기 클릭(Step1+2 제출) |
room_create_success |
201 수신 |
room_create_complete_modal_view |
완료 모달 표시 |
room_create_complete_click_invite/gotoroom |
모달 버튼 클릭 |
invite_open/search/add_candidate/submit/success/fail_4xx/fail_5xx |
초대 플로우(검색 PII는 해시/마스킹 권장) |
초대 정책¶
- 초대 권한: 스터디룸 Owner(= 생성 교사). 대상: 학생만(보호자 직접 초대 불가).
- 생성 시 학생 연결 필수 아님(생성이 초대보다 선행, 최소 0). 학생↔보호자 연결 각 4명. 미연결 보호자는 입장 불가 + 전체공개 외 게시글 열람 불가.
- 초대 발송 시 LNB 빨간점·GNB 알림 생성(Sprint5). 수락 시 학생 프론트 노출.
- 초기 룸당 학생 9명 제한(학원 기준 10명 미만). 추후 BM 정책화.
목록 조회¶
- 정렬: 생성순(default) / 가나다순(스터디룸명). 조회 사용자 플로우는 원본 §6(이미지) 참조.
대시보드 진입 (권한 매트릭스)¶
대시보드 자체의 위젯·집계는 스터디룸 대시보드 FRD가 다루고, 여기서는 진입 라우팅과 역할별 권한만 짚는다.
| 항목 | 강사(LEADER) | 학생(MEMBER) | 보호자(GUARDIAN) |
|---|---|---|---|
| 진도율 | 전체 평균·개별 | 개인 | 자녀 |
| 출석/과제/성취도 | 전체·개별 | 본인 | 자녀 |
| 공지 작성·학생 리스트 | 가능·전체 | 불가·비노출 | 불가·읽기전용 |
경로 /studyrooms/{publicId}/dashboard. 보호자는 StudentGuardianLink.status = ACTIVE만 접근.
의존성 · 영향 범위¶
- 도메인 studyroom(엔티티·공개범위·publicId)·member(학생·보호자·
StudentGuardianLink). 대시보드 위젯 집계는 스터디룸 대시보드 FRD. - 레거시(대치온라인) 클래스 명세(클래스 개설관리·클래스·클래스 상세)는 현 스터디룸의 전신 개념(참조용).
- 라우팅 개편(publicId·301 리디렉션)은 기존
/studyrooms/{id}/studynotes경유 전 화면에 영향.
테스트 계획¶
- 위저드 Step1 로컬 검증·Step2 제출 1회 API 단언, 완료 모달 분기(201/4xx/5xx).
- 초대 권한(강사만 403 경계)·중복(409)·연결 보호자 자동 입장·미연결 보호자 차단.
- 라우팅 301 리디렉션·publicId URL 노출, 대시보드 권한 매트릭스 → qa-playbook.
작업 분해 (이슈 링크)¶
- 생성 위저드(FE)·생성 API·publicId 컬럼/라우팅 개편·초대 검색/발송 API·보호자 자동 입장 로직·목록 정렬·대시보드 진입 권한 게이트.
- 팔로우업: 활성화/비활성화 토글(TBD), 휴지통, 커스텀 정렬, 타 교사 권한 초대. (성진) 육성 기능(학업 행위→점수·랭킹), 프리미엄 유료 기능. UX 아이데이션(Forest 공동 숲·지식 도감·실험노트)도 검토 대상이다. 이슈 링크는 status.