질문답변 도메인 (QnA)¶
1. 한 줄 정의¶
학생 질문 ↔ 선생님 답변 스레드. 스터디룸 안에서 학생이 질문 컨텍스트(QnaContext)를 만들고, 선생님과 학생이 메시지를 누적한다. (AI 코칭은 현재 QnA가 아니라 challenge의 ai_coaching_* 서브시스템에 구현돼 있음.) 사고력 답변 구조 통합은 미구현 기획 — Q&A 개발 명세 (FRD) 참조.
2. 핵심 개념 (실제 코드)¶
- QnaContext (
qna_context) — 질문 스레드.title,status(QnaStatus),visibility(QnaVisibility),viewCount, FK:study_room_id·student_id·related_teaching_note_id(nullable, 연결 수업노트) - QnaMessage (
qna_message) — 스레드 내 메시지.content(≤1000자),authorId,authorType은Roleenum(STUDENT/TEACHER/PARENT/… —actor가 아님), FKcontext_id(@OnDelete CASCADE) - 둘 다
@SQLDelete+@SQLRestriction로 soft delete
미구현(FRD 기획):
aiStatus·selectedAnswer·turnIndex·StudentContext·AiTokenUsage·TeacherFeedback·AiPromptTemplate·AiSatisfactionRating는 현재 QnA 코드에 없다. 사고력 답변 구조 v0.2 명세에만 존재 → Q&A 개발 명세 (FRD).
3. 관련 코드¶
mvp-back:domain/qna—QnaContext,QnaMessage,QnaStatus,QnaVisibility,QnaSortType,QnaContextView,QnaEvents,QnaRepositorymvp-back:application/service/qna—QnaServicemvp-back:presentation/controller/qna—QnaController+ DTOs 10개mvp-back:infrastructure/persistence/repository/qnamvp-front:src/app/(private)/qna
주요 API (실제 구현 — QnaController, prefix /api)¶
QnA 경로는 role prefix가 아니라 /api/study-rooms/...(공통, 인증만 요구) 형태가 다수다. 선생 전용만 /teacher prefix.
| Method | Path | 설명 |
|---|---|---|
| POST | /study-rooms/{studyRoomId}/qna |
질문(컨텍스트) 생성 |
| POST | /study-rooms/{studyRoomId}/qna/{contextId}/messages |
학생 추가 질문 메시지 |
| POST | /teacher/study-rooms/{studyRoomId}/qna/{contextId}/answers |
선생 답변 |
| GET | /study-rooms/{studyRoomId}/qna[/{contextId}] |
학생 목록·상세 |
| GET | /teacher/study-rooms/{studyRoomId}/qna[/{contextId}] |
선생 목록·상세 |
| GET | /parent/student/{studentId}/study-rooms/{studyRoomId}/qna/{contextId} |
보호자 상세 |
| PATCH | /teacher/study-rooms/{studyRoomId}/qna/{contextId}/status |
상태 변경(PENDING↔COMPLETED) |
| PATCH/DELETE | /study-rooms/{studyRoomId}/qna/{contextId} |
제목 수정·삭제 |
| PATCH/DELETE | /study-rooms/{studyRoomId}/qna/{contextId}/messages/{messageId} |
메시지 수정·삭제 |
ai-hint·me/context·ai-inbox·ai-log·feedback 엔드포인트는 QnA 컨트롤러에 없다(미구현, FRD 기획) → Q&A 개발 명세 (FRD).
4. 상태/생명주기¶
QnaContext.status (QnaStatus): PENDING ⇄ COMPLETED (soft delete 가능)
QnaMessage.authorType (Role): STUDENT | TEACHER | PARENT | …
status는 PENDING/COMPLETED 2값만 존재. 선생님이 /qna/{contextId}/status로 전환(학생 추가 질문 → PENDING, 선생 답변 → COMPLETED 운영). aiStatus(NONE/IN_PROGRESS/RESOLVED)와 actor=AI는 코드에 없는 FRD 기획.
5. 외부 의존¶
- S3 / MediaAsset (첨부)
member/studyroom관계 (권한 경계) → member · studyroom- (FRD 기획) LLM provider — 사고력 답변 구조 통합 시 → Q&A 개발 명세 (FRD)
6. UI 노출¶
- QnA 리스트 / 상세 —
mvp-front:src/app/(private)/qna - (FRD 기획) AI 힌트 버튼·학생 컨텍스트 입력·선생님 AI Inbox·메시지 인라인 피드백은 사고력 답변 구조 명세에서 다룸 → Q&A 개발 명세 (FRD)
7. 권한 / 정책 요약¶
| visibility | 열람 |
|---|---|
STUDENT_ONLY (기본) |
학생 본인 + 선생님 |
STUDENT_AND_PARENT |
위 + 연결된 보호자(자녀 QNA 조회) |
학생은 자기 QNA를 생성할 수 있는 유일한 콘텐츠. 역할별 접근 권한 SSOT는 member §7.
8. 결정 이력 / TODO¶
- 사고력 답변 구조 v0.1 단계형 힌트 채택 (2026-05-20)
- ADR-0009 (2026-05-21) — v0.2 채택, 단계형 → 대화형 사고 유도 + 학생 직접 답 선택 + 만족도 수집
- AI 답변 첫 토큰 < 3초 목표 — 스트리밍 1차 vs 2차 (현재 2차)
- (FRD 기획)
aiStatus도입 시 자동 전환 규칙 — 현재 QnA 코드엔aiStatus없음 - (FRD 기획) 분당 10건 레이트 리밋 적용 위치 (API gateway vs 컨트롤러 어노테이션)
- 막힘 코칭은 현재 challenge의
ai_coaching_*서브시스템에 구현됨 (QnA↔챌린지 직접 FK 연결은 미구현)