챌린지식 풀이 개발 명세 (FRD)¶
요지¶
챌린지 풀이를 "왜·어떻게 동작하는가" 수준에서 정리한다. 엔티티 필드나 SQL, 서비스 클래스명처럼 자주 바뀌는 코드 세부는 코드 옆 spec 문서(mvp-back:docs/frd/챌린지식-풀이/spec·mvp-front:docs/frd/챌린지식-풀이/spec)에 두기로 했다(ADR-0004·ADR-0005). 엔티티 자체의 단일 기준은 challenge 도메인이다.
상위 PRD¶
기획(풀이 루프, 막힘 시 AI 위임, 채점 분기, 운영자 시드)은 prd v0.2이며, 바뀌면 이 문서도 갱신한다.
기술 접근 · 아키텍처¶
구현 요약¶
- 신규 도메인
challenge(Challenge, ChallengeProblem, ChallengeRubric, ChallengeAttempt, ChallengeProblemAttempt, ChallengeScore — 엔티티 SSOT는 challenge). - API 9개: 공개 리스트/상세 2 + 학생 attempts·submit·hint·give-up 5 + 선생님 모니터링 2.
- Flyway V35~V39 (사고력-답변구조 V29~V34 뒤).
상태머신¶
두 단계로 분리: - Attempt: IN_PROGRESS → COMPLETED(모든 ProblemAttempt PASSED/GIVEN_UP) / ABANDONED(무활동 배치). - ProblemAttempt: PENDING → PASSED(답 일치/rubric 통과) / FAILED(오답, 재시도) / GIVEN_UP(포기).
채점 분기·답 선택¶
- 객관식·단답: 서버 채점(단일 진실원천). 정답을 클라이언트로 보내지 않음(부정행위 방지).
- open-ended: LLM 채점 (rubric 기반,
ChallengeRubricScoringService). - 답 선택: AI는 답을 대신 고르지 않음 — 학생 직접 선택해야 제출 가능(미선택→제출 disabled).
공개 엔드포인트·멱등성¶
/api/public/**permitAll — 비로그인 학생 유입 (Spring Security 정책 ADR 예정).- 학생당 동일 챌린지 진행 중 시도 1개만(POST attempts 멱등성). 다시 풀기는 새 attempt.
막힘 → AI 위임¶
풀이 중 막힘 → ChallengeProblemAttempt.qnaContextId lazy 생성 후 사고력-답변구조 대화형 코치 위임. qna 도메인(QnaContext/QnaMessage) 재사용. 힌트 사용 기록(페널티 없음), 힌트 없이 정답 시 '혼자 해결' 뱃지.
선생님 모니터링¶
- 본인 운영 스터디룸 학생 한정 — 풀이 여부·AI 사용·AI 로그·정답 여부 조회.
- 화면흐름 설계안(ST1/ST2)은 전체 대화 로그 대신 AI 요약 + 힌트 단계 진행 바만 노출.
API · 데이터 모델¶
엔티티는 challenge가 기준이고, 여기서는 풀이 흐름에 필요한 API만 정리한다.
| 동작 | 경로 |
|---|---|
| 공개 리스트·상세 | GET /api/public/challenges{,/{id}} |
| 시도 시작(멱등) | POST /api/student/challenges/{id}/attempts |
| 진행도 | GET /api/student/attempts/{attemptId} |
| 답 제출·힌트·포기 | POST /api/student/attempts/{id}/problems/{problemId}/{submit,hint,give-up} |
| 선생님 모니터링 | GET /api/teacher/studyrooms/{id}/challenge-attempts |
| 학생 AI 로그 | GET /api/teacher/attempts/{attemptId}/log |
공개 유입 관점의 결과·랭킹·풀이·만족도 API(
/challenge-review·/challenge-feedback·/challenge-ranking등)는 오픈챌린지 frd §API.
의존성 · 영향 범위¶
챌린지 도메인(challenge)을 기반으로, 막힘 위임에 qna를 재사용하고 AI 코치로 사고력-답변구조를 부른다. 공개 유입 쪽 API는 오픈챌린지와 공유하며 visibility만 다르다(PUBLIC vs STUDYROOM).
성능 면에서는 공개 챌린지 리스트를 200ms, 상세를 300ms 안에 돌려주는 걸 목표로 한다(Redis 캐시 후보). 6월 모의고사 시즌 spike에 대비해 1차 MVP는 단일 인스턴스 + 모니터링 임계로 버티고, 부정행위 방지는 정답을 클라이언트로 보내지 않는 선까지만 다룬다.
테스트 계획¶
공통 전략은 qa-playbook을 따른다. 이 기능에서 꼭 볼 것은 attempt 멱등성(진행 중 시도가 중복 생성되지 않는지), 객관식·단답의 서버 채점 정확성과 서술형 rubric 채점 호출, 막혔을 때 qnaContextId가 lazy 생성되며 AI로 잘 위임되는지, 그리고 비로그인 공개 리스트·상세 허용과 attempt 401이다.
작업 분해¶
완료 추적은 GitHub 이슈에서 한다. 핵심 결정은 ADR-0009(위임 대상을 v0.2 대화형으로, 챌린지를 1차 MVP 핵심 채널로)이며, 챌린지와 과제의 경계, 비로그인 공개 엔드포인트의 Security 정책은 별도 ADR로 정할 예정이다.