#601 AI 조교 호출 횟수 제한 및 히스토리 영구 저장 기능 구현#611
Merged
Merged
Conversation
- 백엔드: ProblemAIHintLog 모델 추가 및 영구 저장 로직 구현 - 백엔드: 일일 30회, 문제당 5회 횟수 제한 및 관리자(Admin) 우회 로직 적용 - 백엔드: 과거 AI 힌트 내역 및 사용 횟수 조회 API(AIHintHistoryAPI) 추가 - 프론트엔드: BottomDrag.vue에 백엔드 API 연동 및 남은 횟수 UI 렌더링 적용 - 프론트엔드: 기존 localStorage 기반의 임시 저장 로직 제거 - 테스트: 횟수 제한 및 API 관련 백엔드 단위 테스트 추가 및 100% 통과
Contributor
There was a problem hiding this comment.
Pull request overview
AI 조교(LLM 힌트) 기능에 사용 횟수 제한을 도입하고, 기존 스트리밍으로 휘발되던 응답을 DB에 영구 저장/조회할 수 있도록 백엔드·프론트엔드 전반을 확장한 PR입니다.
Changes:
ProblemAIHintLog모델/마이그레이션 추가 및 힌트 스트리밍 완료 시 DB 저장- 사용자별(일 30회) / 문제별(5회) 호출 제한 적용 + 관리자 무제한 우회
- 히스토리 조회 API(
AIHintHistoryAPI) 및 프론트 채팅 UI 연동/표시 개선
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/pages/oj/views/problem/problemSolving/problemSolvingComponent/BottomDrag.vue | 히스토리 API 연동, 잔여 횟수 표시, 메시지 렌더링 변경 |
| frontend/src/pages/oj/api.js | AI 힌트 히스토리 조회 API 래퍼 추가 |
| backend/problem/views/oj.py | 호출 제한 로직, 스트리밍 응답 DB 저장, 히스토리 API 추가 |
| backend/problem/urls/oj.py | 히스토리 API 라우팅 추가 |
| backend/problem/tests.py | 호출 제한/저장/히스토리 API 관련 테스트 케이스 추가 |
| backend/problem/serializers.py | 힌트 로그 직렬화 Serializer 추가 |
| backend/problem/models.py | ProblemAIHintLog 모델 추가 |
| backend/problem/migrations/0002_problemaihintlog.py | ProblemAIHintLog 테이블 생성 마이그레이션 추가 |
| backend/problem/llm_hint.py | 로컬 테스트용 mock 스트리밍 모드 추가 |
- 남은 횟수 UI표기 변경 - 페이지가 열릴 때가 아닌 AI 조교 패널이 열릴 때 history 불러오기로 수정 - streaming chunk 누적 방식 string -> list로 변경 - 날짜 탐색 방식 범위 검색 방식으로 변경 - v-html="renderText" 보안 위협으로 인한 제거
- 사용하지 않는 renderText를 삭제하였습니다.
- 브라우저 탭을 여러개 사용하여 횟수 제한을 우회할 수 있는 버그 수정 - 스트리밍 시작 전 빈 로그를 먼저 생성하여 즉시 횟수 차감 처리 (Transaction 적용) - vLLM 통신 에러 및 스트림 중단 시 생성된 빈 로그를 삭제하여 횟수 롤백 로직 추가 - AI 조교 일일 사용 횟수(30회) 제한 제거, 문제당 5회 제한만 유지 - ProblemAIHintLog 모델 성능 최적화: user, created_at 인덱스 추가
- select_for_update()를 활용하여 원자성 충족 -> 동시 요청 병렬적 처리 방지 (DB락) - daily_count 하드 코딩 제거 - 불필요한 import 삭제 - 일일 제한 테스트 코드 삭제
…ingComponent/BottomDrag.vue Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- 내용이 조금이라도 있으면 저장, 1바이트도 없으면 횟수 환불 - 바깥에서 미리 만들어둔 hint_log 객체의 내용만 바꾼 뒤 저장
- user_id, problem_id, created_at 인덱스 생성
- AI 힌트 스트리밍 빈 응답 시 횟수 차감 방지 로직 추가 - 히스토리 조회 API의 비공개/대회용 문제 접근 차단 및 조인 최적화 - 동시성 제어 중 발생하는 SimpleLazyObject 에러 해결 (get_user_model) - 힌트 생성 및 조회 관련 엣지 케이스 테스트 코드 추가
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changelog
Testing
2026-04-14-155642-1_k9GKwpUi.mp4
problem.tests.ProblemLLMHintAPITest: 정상 저장, 일일 제한 초과 에러(400), 문제당 제한 초과 에러(400), 관리자 제한 우회 동작 등 13개 케이스 통과 (OK)problem.tests.AIHintHistoryAPITest: 비로그인 차단, 로그 데이터 및 카운트 반환 구조(Schema) 정상 동작 확인 (OK)IS_LOCAL_TEST=True모드를 켜고 프론트엔드에서 직접 버튼을 클릭하여, 응답 스트리밍이 끝나면 즉시 DB에 저장되고 남은 횟수가 즉각적으로 UI에서 차감되는 것을 확인했습니다. 창을 닫았다 열어도 이전 대화 내용이 정상적으로 유지됩니다.Ops Impact
problem_ai_hint_log라는 새로운 테이블이 추가되었습니다. 배포 시 백엔드 컨테이너에서 반드시 DB 마이그레이션(python manage.py makemigrations problem,python manage.py migrate)을 실행해야 합니다.Version Compatibility
N/A