-
Notifications
You must be signed in to change notification settings - Fork 1
1) Requirements & Specifications
- 1. Document Revision History
- 2. Project Abstract
- 3. Customer
- 4. Competitive Landscape
- 5. Adaptive Feedback Buckets
- 6. Functional Requirements
- 7. Non-Functional Requirements
- 8. User Interface Requirements
- 9. Data Governance & Ethics
- 10. Release & QA Checklist
| Version | Date | Message |
|---|---|---|
| 0.1 | 2025-09-24 | Initial draft created |
| 0.2 | 2025-09-30 | Added login, roles, class & assignment flows |
| 0.3 | 2025-10-01 | Revised user stories, added user acceptance criteria |
| 0.4 | 2025-10-03 | Updated customer (persona) |
| 0.5 | 2025-10-04 | Updated competitive landscape |
| 1.1 | 2025-10-14 | Revised project abstract |
| 1.2 | 2025-10-14 | Add table of contents |
| 2.1 | 2025-10-30 | Minor revisions |
| 2.2 | 2025-11-01 | Revised project abstract & Non-functional requirements |
| 2.3 | 2025-11-02 | Added failure cases & Updated Wireframe |
| 3.0 | 2025-11-09 | Expanded detailed requirements, KPIs, and compliance criteria |
| 3.1 | 2025-11-11 | Updated User Stories, Release & QA Checklist |
| 3.2 | 2025-11-15 | Updated Failure case & WireFrame |
| 4.1 | 2025-11-26 | Updated User Acceptance Criteria |
| 4.2 | 2025-11-29 | Updated Adaptive Feedback Buckets |
| 4.3 | 2025-11-30 | Updated Failure Cases |
This platform is an AI-powered learning and assignment management system.
Users (students and teachers) can register with role-based accounts, manage courses and assignments, and interact with AI-driven personalized assessments. The AI-driven personalized assessments are conducted in a conversational format. The AI generates open-ended questions, analyzes students’ verbal responses, and then creates adaptive follow-up quizzes as part of the review process. The system integrates a Jetpack Compose frontend, Django backend. Key features include AI-generated continuous question-answer quizzes, STT (Speech-to-Text) based student responses, and detailed performance reports aligned with Korean national curriculum.
- Who they are: Elementary and middle school students in after-school academies or private tutoring programs.
- Current pain: Lessons are often one-directional; students memorize procedures but struggle to explain concepts, making it unclear if they truly understand.
- Why VoiceTutor: Encourages verbal explanation with AI feedback, helping students strengthen comprehension, build confidence, and close knowledge gaps.
- Who they are: Instructors at academies or schools managing large groups with diverse comprehension levels.
- Current pain: Difficult to individually assess conceptual understanding; most evaluation relies only on written tests.
- Why VoiceTutor: Provides structured insights into verbal explanations, making it easier to identify weak areas and adapt teaching strategies.
- Who they are: Academies, schools, or edu-tech providers seeking to improve learning outcomes with innovative tools.
- Current pain: Lack standardized methods to evaluate comprehension and communication skills across students.
- Why VoiceTutor: Delivers AI-enhanced comprehension and evaluation tools that integrate with existing programs for scalable, consistent measurement.
| Feature | Kahoot! | Vocal Image | Quizlet | Google Classroom | VoiceTutor |
|---|---|---|---|---|---|
| Role-based sign-up (student/teacher) | O | X | O | O | O |
| STT-based voice submission | X | O | X | X | O |
| AI-based comprehension feedback | X | △ | X | X | O |
| PDF & curriculum-based quiz generation | O | X | O | X | O |
-
Kahoot!, Quizlet
They are known for their quiz platforms, offering students a flexible way to practice and review materials.
However, they mainly focus on multiple-choice answers, not verbal explanations. -
Vocal Image
It specializes in voice-based analysis for communication skills, particularly pronunciation and emotional tone detection.
It provides only surface-level analysis of voice without linking to academic content or structured curriculum. -
Google Classroom
It is strong in logistics and assignment management.
However, it lacks advanced assessment tools, AI-driven feedback, and voice-based evaluation. -
VoiceTutor
VoiceTutor uniquely combines the strengths of existing solutions while addressing their limitations.
Unlike Kahoot! and Quizlet, it goes beyond memorization and competition, focusing on students’ verbal explanations to measure true comprehension.
Unlike Vocal Image, it doesn’t stop at voice analytics. It connects voice responses directly to curriculum content, generating AI-based follow-up questions.
To provide more meaningful and pedagogically grounded feedback, we classify each student response using a two-dimensional rubric: semantic correctness and predicted confidence. This results in four rule-based feedback buckets:
-
A: correct & confident -
B: correct but unconfident -
C: incorrect but confident -
D: incorrect & unconfident
This design acknowledges that binary correctness alone is insufficient to capture a learner’s actual understanding or affective state. Confidence is inferred from acoustic and semantic features—such as silence ratio, pitch dynamics, and topic coherence—using a lightweight regression model. Correctness is evaluated via a robust LLM-based judgment function.
Each of the four cases triggers a distinct follow-up strategy:
-
Aencourages deeper or more challenging extensions, -
Bfocuses on affirming knowledge and reinforcing self-efficacy, -
Caddresses potential misconceptions through guided reflection, -
Doffers gentle re-teaching of foundational ideas.
By structuring feedback in this way, the system aligns with principles from affective tutoring and scaffolding theory—without overengineering complexity. This helps ensure that learners receive not only reactive corrections, but adaptive, confidence-aware prompts that are sensitive to both what they know and how sure they are about their understanding.
We focus on voice-based features not only for convenience, but because speech naturally encodes metacognitive signals. A body of research—including work on prosodic markers of confidence and uncertainty (e.g., pitch slope, silence ratio, RMS intensity)—shows that hesitation, final intonation, and timing patterns reliably correlate with a speaker's internal confidence state. For example, rising terminal contours or extended silent pauses often reflect uncertainty, while clear falling intonation and steady pacing indicate stronger conviction. Such signals are especially salient around key content words and sentence endings, providing fine-grained cues that surface-level correctness cannot reveal.
Moreover, recent findings on pausing behavior suggest that unplanned pauses—particularly within clauses—often stem from cognitive or emotional load, such as lexical retrieval difficulty, conceptual confusion, or performance anxiety. In contrast, brief clause-final pauses can be strategic and communicative. By analyzing not just what was said but how it was delivered, our system captures these subtle yet pedagogically meaningful aspects of learner state.
In short, integrating prosodic and temporal speech features allows us to infer learner confidence more holistically, supporting feedback that respects both knowledge and fluency under uncertainty.
We adopt a four-bucket framework—rather than a continuous scale or binary feedback—for both conceptual clarity and practical instructional value. This quadrant-based design allows the system to distinguish not only between correct and incorrect responses, but also between confident and unconfident delivery. These distinctions enable more targeted feedback strategies that reflect both cognitive understanding and metacognitive awareness.
For example, a confident but incorrect response (C) may indicate a misconception worth addressing directly, while an unconfident but correct response (B) may call for encouragement to strengthen self-efficacy. In contrast, learners who are both unconfident and incorrect (D) often require foundational support, whereas those who are correct and confident (A) benefit more from extension or challenge.
The four-category scheme also improves interpretability and actionability. Rather than relying on abstract or opaque model outputs, it provides discrete, pedagogically meaningful labels that simplify downstream decisions and make the system's behavior more transparent to both developers and educators. Educational research supports this kind of alignment between learner performance, confidence, and adaptive feedback—leading to better calibration, reflection, and long-term learning gains.
As a registered teacher user, I can create a new class with a title, subject, and description, and enroll students into the class, so that I can organize enrolled students and assignments separately by class.
Acceptance Criteria
Step 1: Navigate to class creation screen
- Given: Teacher is on home screen or class screen (수업 탭)
- When: Teacher touches "+수업 생성하기" or "+수업 생성" button
- Then: Teacher moves to "수업 생성" screen
Step 2: Fill in class information
-
Given: Teacher is on "수업 생성" screen
-
When: Required fields (class name, subject) are empty
-
Then: "수업 생성" button is disabled
-
Given: Teacher is on "수업 생성" screen
-
When: All required fields (class name and subject) are filled in properly (description field is optional)
-
Then: "수업 생성" button is enabled
Step 3: Create the class
- Given: Teacher is on "수업 생성" screen and "수업 생성" button is enabled
- When: Teacher clicks "수업 생성" button
- Then: Teacher moves to class screen (수업 탭) and a new class card matching the entered information is displayed
Step 4: Access student management
- Given: Teacher is on class screen (수업 탭)
- When: Teacher touches "학생 상세" button on the newly created class card
- Then: Teacher moves to "학생 관리" screen, "학생 등록" and "학생 삭제" buttons are displayed
Step 5: Open student enrollment
-
Given: Teacher is on "학생 관리" screen
-
When: Teacher touches "학생 등록" button
-
Then: Bottom sheet appears and it shows student users not yet enrolled in that class
-
Given: Teacher is on bottom sheet
-
When: Teacher enters non-existent student name or email on the search field
-
Then: No student matches, list is empty
-
Given: Teacher is on bottom sheet
-
When: Teacher enters existing student name or email (or part of that string) on the search field
-
Then: Student matches, list showing matched student(s)
Step 6: Enroll students
-
Given: Teacher is on the bottom sheet, list is not empty
-
When: Teacher clicks one of the checkboxes to the right of the student name and touches "등록" button
-
Then: Bottom sheet is closed and student card with the selected name appears, the number of students displayed on the screen increases by one
-
Given: Teacher is on the bottom sheet, at least two students are on the list
-
When: Teacher clicks multiple checkboxes and touches "등록" button
-
Then: Bottom sheet is closed and student cards with selected names appear, the number of students displayed on the screen increases by number of selected students
-
Given: Teacher is on the bottom sheet
-
When: Teacher touches "취소" button
-
Then: Bottom sheet is closed and nothing changes
-
Given: Teacher is on the bottom sheet
-
When: Teacher selects no students on the list
-
Then: "등록" button is disabled
As a registered teacher user who manages a class, I can upload a PDF learning material and generate a quiz assignment from it, so that enrolled students can view and take the quiz.
Acceptance Criteria
Step 1: Fill in assignment basic information
-
Given: Teacher is on the "과제 생성" screen. At least one class with enrolled students exists.
-
When: Teacher selects a class with enrolled students, chooses a valid grade and subject, and enters a non-empty title and description.
-
Then: Selected class, grade, and subject are displayed in their fields. The title and description are displayed as entered. No error messages are shown for these fields.
-
Given: Teacher is on the "과제 생성" screen.
-
When: Teacher types an assignment title that includes the character "/" in the "과제 제목" field.
-
Then: An error message "'/' 문자는 사용할 수 없어요." appears below the "과제 제목" field, and the "/" character is automatically removed from the input.
Step 2: Set due date
-
Given: Teacher is on the "과제 생성" screen. Due date field is empty. Other required fields (title, class, grade, subject, description, PDF, question count, assignment target) are already valid.
-
When: Teacher taps the "마감일" field, selects valid date in the date picker, then selects valid time in the time picker and taps "확인". Note that "마감일" should be future.
-
Then: The date/time pickers close. The "마감일" field shows the selected value in YYYY-MM-DD HH:MM format.
-
Given: Teacher has opened the due date picker (date picker and/or time picker).
-
When: Teacher tries to select a past date (e.g., yesterday) or selects a time earlier than the current time for today and taps "확인".
-
Then: Past dates (e.g., yesterday) are disabled and cannot be selected. Past times are not accepted: the value is not saved and either the confirm action is blocked or an error is shown so that only a future time can be set.
-
Given: All other required fields (title, class, grade, subject, description, PDF, question count, assignment target) are valid. The due date field is still empty.
-
When: Teacher closes the date/time picker without selecting a valid date and time, leaving the "마감일" field empty.
-
Then: The "마감일" field continues to show the placeholder "날짜와 시간을 선택하세요." The "과제 생성" button remains disabled, and the assignment cannot be created until a due date is set.
Step 3: Upload PDF material
-
Given: Teacher is on the "과제 생성" screen. No PDF is selected yet.
-
When: Teacher taps the "파일 선택" button in the "PDF 자료 업로드 (필수)" section and selects a valid PDF from the file picker.
-
Then: The file picker closes. Under "선택된 파일 (1개)" the file name and size are displayed. This file is stored as the PDF to upload for the assignment.
-
Given: Teacher has opened the file picker from the "파일 선택" button.
-
When: Teacher selects a PDF file whose size exceeds the maximum allowed upload limit (10MB).
-
Then: The file picker closes. A red warning box appears under the button with the message "파일 용량이 너무 큽니다. 최대 10MB까지 업로드 가능합니다." The file is not selected, and the PDF field remains empty/invalid.
-
Given: Teacher has opened the file picker.
-
When: Teacher selects a file that is not in PDF format (e.g., a Word document, image file) from the file picker.
-
Then: The non-PDF file either does not appear as a selectable PDF option or, if selected, does not get added to the "선택된 파일" list. Only PDF files are effectively accepted.
-
Given: Title, class, grade, subject, description, due date, question count, assignment target are all valid. No PDF is selected.
-
When: Teacher leaves the PDF upload section without choosing any file, or removes any previously selected file so that no file remains selected.
-
Then: The "PDF 자료 업로드 (필수)" section shows only the "파일 선택" button and no "선택된 파일" entry. The "과제 생성" button stays disabled because the required PDF has not been selected.
Step 4: Set question count
-
Given: A valid PDF is selected. The "문제 개수" field currently contains a valid positive integer (e.g., 5).
-
When: Teacher keeps the default value or edits the "문제 개수" field so that it contains a positive integer.
-
Then: The "문제 개수" field shows a positive integer (e.g., 5).
-
Given: A valid PDF is selected. The "문제 개수" field has a default value or is empty.
-
When: Teacher enters 0 or a negative number, or attempts to enter non-numeric characters into the "문제 개수" field.
-
Then: Non-numeric characters are blocked or ignored so that only digits remain. If the resulting value is 0 and the teacher tries to create the assignment, validation fails and an error such as "문제 개수는 1 이상이어야 합니다" is shown.
Step 5: Assign to students
-
Given: All required fields (title, class, grade, subject, description, due date, PDF, question count) are valid, and the selected class has enrolled students.
-
When: Teacher leaves the assignment target as "전체 학생에게 배정" without changing the radio button selection.
-
Then: "전체 학생에게 배정" remains selected. The assignment will be given to all students in the selected class.
-
Given: All required fields are valid and the selected class has multiple enrolled students. The current selection is "전체 학생에게 배정".
-
When: Teacher switches the radio button to "선택한 학생에게만 배정", then uses the student list to toggle "전체 선택" and to check or uncheck individual students.
-
Then: When "선택한 학생에게만 배정" is selected, a student list for the class is displayed with an "전체 선택" checkbox and individual student checkboxes. "전체 선택" toggles all students; individual checkboxes reflect the teacher's final selection.
-
Given: All required fields are valid. The selected class has no enrolled students.
-
When: Teacher tries to select "선택한 학생에게만 배정".
-
Then: The "선택한 학생에게만 배정" radio button is disabled. Teacher cannot choose that option.
Step 6: Create assignment
-
Given: All required fields listed in Test Data are filled correctly. The PDF content is consistent with the selected grade and subject. The "과제 생성" button is enabled.
-
When: Teacher submits the form by tapping the "과제 생성" button.
-
Then: The "과제 생성" button enters a loading state or becomes disabled. A loading indicator and a progress UI such as "PDF 업로드 중..." are shown. A valid request is sent to the server. On success, the teacher is taken to the assignment detail screen and sees a success message.
-
Given: Class, grade, subject, description, due date, question count, assignment target, and PDF are all valid. Only the title field is empty.
-
When: Teacher attempts to submit the assignment while the title field is empty.
-
Then: The "과제 생성" button stays disabled and cannot be tapped.
As a registered student user enrolled in the class, I can start a conversational quiz sessions and submit my spoken answers, so that my submission is recorded and I can receive AI-generated follow-up questions tailored to my weak areas.
Acceptance Criteria
Step 1: View assignment
- Given: The user logged in as student, and is on main activity. Unstarted assignment with 2 base questions is assigned to the student.
- When: Student touches unstarted assignment.
- Then: Student moves to detailed assignment screen, showing title and corresponding subject, class, end date, and content.
Step 2: Start assignment
- Given: The user is on detailed assignment screen.
- When: Student touches "과제 시작" button.
- Then: Student moves to assignment screen, showing "질문 1" and the question's content.
Step 3: Attempt to submit before recording
- Given: The user is on first base question assignment screen.
- When: Student touches grey colored "음성 답안 제출하기" button.
- Then: Nothing happens, as the button is disabled.
Step 4: Start recording
- Given: The user is on first base question assignment screen. The device's microphone (audio recording) permission is enabled.
- When: Student touches "녹음 시작" button.
- Then: "녹음 시작", "건너뛰기" buttons disappear. "녹음 중지" button and "녹음 중... {time}/01:00" text are shown. {time} is showing the time passed since clicking button.
Step 5: Attempt to submit during recording
- Given: The user is on first base question assignment screen, and the "녹음 시작" button is pressed.
- When: Student touches grey colored icon&text "음성 답안 제출하기" button.
- Then: Nothing happens, as the button is disabled.
Step 6: Stop recording
- Given: The user is on first base question assignment screen, and the "녹음 시작" button is pressed.
- When: Student speaks the test data (speech shorter than 1 min speaking wrong answer, ex "잘 모르겠습니다"), and presses "녹음 중지".
- Then: "녹음 중지" button and "녹음 중... {time}/01:00" text disappear. "다시 녹음하기" button, "다시 듣기" icon and "녹음 완료 {time}" text are shown. "음성 답안 제출하기" button's color is changed to black icon, white text. {time} shows the length of test data speech.
Step 7: Playback recording
- Given: The user is on first base question assignment screen, and the "녹음 중지" button is pressed. Device's media volume is not muted.
- When: Student touches "다시 듣기" icon.
- Then: Recorded speech is played.
Step 8: Submit answer
- Given: The user is on first base question assignment screen, and the "녹음 중지" button is pressed.
- When: Student touches "음성 답안 제출하기" button.
- Then: "채점 중" loading overlay is enabled. After few seconds, it moves to "틀렸습니다" result screen with "꼬리질문으로 넘어가기" button.
Step 9: Move to tail question
- Given: The user is on first base question assignment result screen.
- When: Student touches "꼬리질문으로 넘어가기" button.
- Then: Student moves to assignment screen, showing "꼬리 질문 1-1" and the generated tail question's content.
Step 10: Recording timeout
- Given: The user is on 1-1 tail question assignment screen.
- When: Student touches "녹음 시작" button and waits for 1 minute.
- Then: When 1 minute is passed, the "녹음 중지" button and "녹음 중... {time}/01:00" text disappear. "다시 녹음하기" button, "다시 듣기" icon and "녹음 완료 {time}" text are shown. "음성 답안 제출하기" button's color is changed to black icon, white text. {time} shows the length of test data speech.
Step 11: Skip question
- Given: The user is on 1-1 tail question assignment screen.
- When: Student touches "건너뛰기" button.
- Then: "채점 중" loading overlay is enabled. After few seconds, it moves to "문제를 건너뛰었습니다" result screen with "꼬리질문으로 넘어가기" button.
Step 12: Navigate to home
- Given: The user is on 1-1 tail question assignment result screen.
- When: Student touches "홈" Navigation.
- Then: Student moves to main activity.
Step 13: Resume assignment
- Given: The user is on main activity.
- When: Student touches "이어하기" Navigation.
- Then: Student moves to most recently submitted assignment's detailed assignment screen, which is assignment submitted in this UAT.
Step 14: Continue assignment
- Given: The user is on detailed assignment screen.
- When: Student touches "과제 시작" button.
- Then: Student moves to assignment screen, showing "꼬리 질문 1-2" and the generated tail question's content.
Step 15: Progress through questions
- Given: The user is on 1-2 tail question assignment screen.
- When: Student touches "건너뛰기" button, "꼬리질문으로 넘어가기" button, and "건너뛰기" button again.
- Then: Student moves to "문제를 건너뛰었습니다" result screen with "다음 문제" button. "진행률" progress bar's UI and text is changed to 50%.
Step 16: Move to next base question
- Given: The user is on tail question assignment "문제를 건너뛰었습니다" result screen with "다음 문제" button.
- When: Student touches "다음 문제" button.
- Then: Student moves to assignment screen, showing "질문 2" and the second base question's content. "진행률" progress bar's UI and text is changed to 50%.
As a registered student user enrolled in the class, I can review my completed assignment and view the report, so that I can understand which questions I answered correctly or incorrectly.
Acceptance Criteria
Step 1: View learning report
-
Given: Student is logged in but has no completed assignments.
-
When: Student taps the "학습 리포트" tab at the bottom.
-
Then: The "학습 리포트" screen is displayed. "완료한 과제가 없습니다" message and icon are displayed. Assignment list is empty.
-
Given: Student is logged in and at least one completed assignment exists.
-
When: Student launches the app, logs in, and taps the "학습 리포트" tab in the bottom navigation bar.
-
Then: The "학습 리포트" screen is displayed. Completed assignment list is loaded. Each assignment card displays assignment title, submission date, and number of questions.
Step 2: View detailed results
- Given: On "학습 리포트" screen, there is a completed assignment in the list.
- When: Student taps the "리포트 보기" button on the assignment card.
- Then: Student navigates to the detailed results screen. Assignment title and "리포트" text are displayed in the header.
Step 3: Navigate back and view loading
-
Given: From Step 2, the detailed results screen is displayed.
-
When: Student taps the back button.
-
Then: Student returns to the "학습 리포트" screen. Previous screen state is maintained.
-
Given: From Step 2, the detailed results screen is displayed.
-
When: Student waits until the screen loads.
-
Then: Loading indicator is displayed, and after data loading completes, the following information is shown: "총 문제" card displays the actual number of questions, "점수" card displays the actual score, "문제별 상세 결과" section is displayed.
Step 4: Review question details
- Given: From Step 3, the detailed results by question are displayed.
- When: Student checks each question card.
- Then: Each question card displays the following information: Question number (e.g., "문제 1"), Correct/Incorrect badge (correct: green, incorrect: red), Question content, "내 답변" section (answer entered by student), "정답" section (correct answer content), "해설" section (explanation content, if available).
Step 5: Expand tail questions
- Given: From Step 4, when Question 1 has follow-up questions.
- When: Student taps the "꼬리질문 펼치기" button on Question 1 card.
- Then: Follow-up questions are expanded and displayed. Each follow-up question displays question number, correct/incorrect badge, question content, student answer, correct answer, and explanation. Button text changes to "꼬리질문 접기".
Step 6: Collapse tail questions
- Given: From Step 5, when follow-up questions are expanded.
- When: Student taps the "꼬리질문 접기" button.
- Then: Follow-up questions are collapsed and hidden. Button text changes to "꼬리질문 펼치기".
As a registered teacher user who manages the class, I can access each enrolled student's statistics and reports based on Korean curriculum standards, so that I can assess their understandings and identify weak areas.
Acceptance Criteria
Step 1: Navigate to report screen
- Given: A registered teacher account exists. The user is logged in as teacher. Main(TeacherDashboard) screen is displayed.
- When: Teacher touches the "리포트" button on the bottom navigation bar.
- Then: Teacher moves to report screen. Loading indicator is displayed. The "성취기준 리포트" screen is displayed.
Step 2: View class and student list
- Given: Students are enrolled in the class. The user is on "성취기준 리포트" screen.
- When: Teacher waits until the loading completes on "성취기준 리포트" screen.
- Then: After successful loading, the class dropdown and student list are visible on "성취기준 리포트" screen.
Step 3: View student report
- Given: A student did the assignment of the class. The student is on the student list.
- When: Teacher touches the "리포트 보기" button on student's card.
- Then: Teacher moves to "리포트" screen. Loading indicator is displayed. The summary stats are displayed correctly.
Step 4: View achievement standard analysis
- Given: Teacher is on student's "리포트" screen, who did the assignment of the class. An analysis of the student's assignment performance by achievement standard is performed.
- When: Teacher scrolls down to the "성취기준별 분석" section.
- Then: The specific standard (e.g., 6수02-01) card is displayed with its description, accuracy graph (0.0%), and question count (10). The report count is displayed next to the right of the "성취기준 별 분석" section.
Step 5: Navigate back
- Given: Teacher is on student's "리포트" screen, who did the assignment of the class.
- When: Teacher touches the arrow pointing to the left at the top left of the screen.
- Then: After successful loading, the class dropdown and student list are visible on "성취기준 리포트" screen.
Step 6: View report for student without submissions
- Given: A student is on the student list. The student didn't do the assignment of the class.
- When: Teacher touches the "리포트 보기" button on the student's card.
- Then: Teacher moves to "리포트" screen. Loading indicator is displayed. The summary stats are displayed correctly. The summary stats are all 0. And the message "제출한 과제가 없습니다" is displayed under the "성취기준 별 분석" section.
Step 7: View assignment detail - completed and unstarted
- Given: A registered teacher account exists. The user logged in as teacher. Main(TeacherDashboard) screen is displayed. An assignment card is displayed under the "모든 과제" section. One student did an assignment. Another one didn't do the assignment.
- When: Teacher touches the assignment card.
- Then: Teacher moves to "과제 상세" screen. Loading indicator is displayed under the "학생별 결과" section. After successful loading the student status cards are displayed. On the status card of the student who did the assignment, The status is clearly marked as "완료"(in green). And the submitted time and score are displayed. On the status card of the student who didn't do the assignment The status is clearly marked as "미시작"(in orange). And the submitted time and score are not displayed.
Step 7-2: View assignment detail - in progress and unstarted
- Given: A registered teacher account exists. The user logged in as teacher. Main(TeacherDashboard) screen is displayed. An assignment card is displayed under the "모든 과제" section. One student started an assignment but not finished. Another one didn't do the assignment.
- When: Teacher touches the assignment card.
- Then: Teacher moves to "과제 상세" screen. Loading indicator is displayed under the "학생별 결과" section. After successful loading the student status cards are displayed. On the status card of the student who started the assignment but not finished, The status is clearly marked as "진행 중"(in orange). And the recent examination time(최근 응시) and score are displayed. On the status card of the student who didn't do the assignment, The status is clearly marked as "미시작"(in orange). And the submitted time and score are not displayed.
Step 8-1: View detailed assignment results for completed student
- Given: Teacher is on "과제 상세" screen. One student did an assignment. Another one didn't do the assignment. Student who did the assignment is under the "학생별 결과" section.
- When: Teacher touches the status card of the student who did the assignment. The status card is under the "학생별 결과" section.
- Then: Teacher moves to "과제 결과" screen. Loading indicator is displayed under the "문제별 상세 결과" section. After successful loading the question cards are displayed. On "과제 결과" screen, statistics for the assignment of the student who did it is displayed. Percentage of correct answers, Average score, the time required, and the submission time also are displayed. Under "문제별 상세 결과" section, the question cards are displayed.
Step 8-2: Attempt to view results for unstarted student
- Given: Teacher is on "과제 상세" screen. One student did an assignment. Another one didn't do the assignment. Student who didn't do the assignment is under the "학생별 결과" section.
- When: Teacher touches the status card of the student who didn't do the assignment. The status card is under the "학생별 결과" section.
- Then: The message "아직 과제를 시작하지 않았습니다" appears below in the form of toast.
Step 8-3: View detailed assignment results for in-progress student
- Given: Teacher is on "과제 상세" screen. One student started an assignment but not finished. Another one didn't do the assignment. Student who started the assignment but not finished is under the "학생별 결과" section.
- When: Teacher touches the status card of the student who started the assignment but not finished. The status card is under the "학생별 결과" section.
- Then: Teacher moves to "과제 결과" screen. Loading indicator is displayed under the "문제별 상세 결과" section. After successful loading the question cards are displayed. On "과제 결과" screen, the student's statistics for the assignment "생성 테스트", percentage of correct answers, Average score, and the submission time are displayed. Under "문제별 상세 결과" section, the question cards are displayed. On the question card, the question, correctness, the student's response to it, the model answer, and the explanation is displayed.
Step 9: Expand tail questions
- Given: Teacher is on student's "과제 결과" screen. The student did the assignment. The student answered all the tail questions.
- When: Teacher touches the "꼬리질문 펼치기" toggle button on the question card.
- Then: The question card is expanded including the tail question at the bottom. The tail question, correctness, the student's response to it, the model answer, and the explanation is displayed on the expanded tail question card.
Step 10: Collapse tail questions
- Given: Teacher is on student's "과제 결과" screen. The student did the assignment. The student answered all the tail questions. And the question card is expanded.
- When: Teacher touches the "꼬리질문 접기" button under the expanded question card.
- Then: The question card is compressed to its original size.
User Story: As a registered user (either teacher or student), I can view my profile so that I can confirm I'm logged into the correct account.
Acceptance Criteria:
- Given that a registered user (either teacher or student) is logged into the app
- And the user taps the profile icon in the top-right corner
- When the user is redirected to the account page
- Then the page displays the user's name, email, and role
User Story: As a new user, I can sign up using my email, password, and role (teacher or student), so that I can register my data to the service and start VoiceTutor.
Acceptance Criteria:
- Given the user is on the login screen
- When the user taps the "계정 만들기" (Sign Up) button
- Then the app navigates to the sign-up screen
- And the screen displays input fields for role, email, and password
- When the user fills in all required fields and taps the "회원가입" (Sign Up) button
- Then the user account is created successfully
- And the user is automatically signed in and redirected to the main dashboard screen
User Story: As a registered user, I can sign in using my email and password, so that I can access the app securely and resume my activities based on my role (teacher or student).
Acceptance Criteria:
- Given the user already has a registered account
- And is on the login screen
- When the user enters a valid email and password and taps the "로그인" (Sign In) button
- Then the user is authenticated successfully
- And navigated to the appropriate dashboard based on their role (teacher or student)
User Story: As a registered user (either teacher or student), I can log out of my account so that I can securely end my session and prevent unauthorized access to my information.
Acceptance Criteria:
- Given that a registered user (either teacher or student) is logged into the app
- And the user is on a screen where the logout button is visible in the top-right corner
- When the user taps the logout button
- Then a modal appears with the message "로그아웃하시겠습니까?" and two options: "취소" and "로그아웃"
- When the user selects the "로그아웃" button in the modal
- Then the user is successfully logged out
- And the app clears the user session and returns to the login screen
User Story: As a registered user (either teacher or student), I can delete my account and all associated data, so that I have full control over my personal information and can permanently remove my presence from the app.
Acceptance Criteria:
- Given that a registered user (either teacher or student) is on the account page
- And a "Delete Account" button is visible at the bottom of the page
- When the user taps the "Delete Account" button
- Then a modal appears showing the message "계정을 삭제하시겠습니까? 삭제 후에는 복구할 수 없습니다"
- And the modal contains two options: "취소" and "계정 삭제"
- When the user selects the "계정 삭제" button
- Then the user's account and associated data are permanently deleted
- And the app logs the user out and returns to the login page
User Story: As a newly registered user, I can view an onboarding tutorial, so that I can learn how to use the service for the first time.
Acceptance Criteria:
- Given that a user has just completed registration and logged in for the first time
- When the app loads for the first time
- Then the onboarding tutorial screen appears automatically
- And the user can swipe left or right to navigate through the tutorial
User Story: As a registered user, I can reset and rewatch the tutorial, so that I can revisit the onboarding instructions whenever I need them.
Acceptance Criteria:
- Given that a registered user is on the account page
- And a "Reset Tutorial" option is visible
- When the user taps the "Reset Tutorial" option
- Then a confirmation modal appears with reset options
- When the user confirms by selecting the reset button
- Then the tutorial is reset and the tutorial is shown right away
User Story: As a registered user, I can view information about the app (developer, build number, last update date, platform) and the inquiry email, so that I can verify app details and know how to contact support when needed.
Acceptance Criteria:
- Given that a registered user is on the account page
- And a menu item labeled "App Info" is visible
- When the user taps the "App Info" menu
- Then the user is redirected to the app info page
- And the page displays the developer name, build number, last update date, platform, and the inquiry email
User Story: As a registered teacher, I can view the list of assignments distributed to a class I manage so that I can easily track which tasks have been shared with that class.
Acceptance Criteria:
- Given that a registered teacher is on the class page
- And the teacher can see a list of class cards
- When the teacher taps a class card
- Then the teacher is redirected to the class management page
- And the page displays the list of assignments distributed to that class
User Story: As a registered teacher, I can view the submission rate, average score, number of submitted students, and individual grading results for a specific assignment, so that I can understand the overall class performance and review how each student performed.
Acceptance Criteria:
- Given that a registered teacher is on the home screen or the class management page
- And the teacher can see a list of assignments
- When the teacher selects a specific assignment
- Then the teacher is redirected to the assignment detail page
- And the page displays the submission rate, average score, number of submitted students, and individual grading results for that assignment
User Story: As a registered teacher, I can edit the title, description, and due date of an assignment I previously created, so that I can update or correct the assignment information when necessary.
Acceptance Criteria:
- Given that a registered teacher is on the assignment detail page
- And an "Edit Assignment" button is visible
- When the teacher taps the "Edit Assignment" button
- Then the teacher is redirected to the assignment edit page
- And the page displays a form with editable fields for title, description, and due date
- When the teacher enters the desired information in the form
- And the teacher taps the "Save" button at the bottom of the page
- Then the assignment information is updated
- And the teacher is redirected back to the assignment detail page with the updated information
User Story: As a registered teacher, I can delete an assignment that I previously created, so that I can remove outdated or incorrect assignments from my class.
Acceptance Criteria:
- Given that a registered teacher is on the assignment detail page
- And the teacher taps the "Edit Assignment" button
- Then the teacher is redirected to the assignment edit page
- And a "Delete Assignment" button is visible at the bottom of the page
- When the teacher taps the "Delete Assignment" button
- Then a confirmation modal appears with the message "정말로 이 과제를 삭제하시겠습니까? 삭제된 과제는 복구할 수 없습니다"
- And the modal contains two options: "취소" and "삭제"
- When the teacher selects the "삭제" button
- Then the assignment is permanently deleted
- And the teacher is redirected back to the class management page
User Story: As a registered teacher, I can delete a class I manage so that all assignments and student-related data associated with that class are removed together.
Acceptance Criteria:
- Given that a registered teacher is on the class management page
- And the teacher can see a list of class cards
- And each class card has a red trash icon button in the top-right corner
- When the teacher taps the trash icon button on a class card
- Then a confirmation modal appears with the message "수업을 삭제하시겠습니까? 삭제하면 되돌릴 수 없어요"
- And the modal contains two options: "취소" and "삭제하기"
- When the teacher selects the "삭제하기" button
- Then the class is permanently deleted
- And all assignments and student-related data associated with that class are removed
- And the class card is removed from the class list
User Story: As a registered teacher, I can view the list of students in a class I manage and check the class's assignment submission rate, so that I can understand who is enrolled and how actively students are participating.
Acceptance Criteria:
- Given that a registered teacher is on the class management page
- And the teacher can see a list of class cards
- And each class card has a "Student Detail" button in the bottom-right corner
- When the teacher taps the "Student Detail" button on a class card
- Then the teacher is redirected to the student management page
- And the page displays the assignment submission rate and the list of students enrolled in that class
User Story: As a registered teacher, I can remove a student from a class I manage, so that I can maintain accurate class membership and ensure that only the appropriate students remain assigned to the class.
Acceptance Criteria:
- Given that a registered teacher is on the student management page for a class they manage
- And a "Delete student" button is visible
- When the teacher taps the "Delete student" button
- Then a bottom sheet appears showing the list of students with checkboxes
- When the teacher checks the students they want to remove
- And the teacher taps the "Delete" button in the bottom sheet
- Then the selected students are removed from that class
- And the student list for that class is updated to reflect the removal
User Story: As a registered student, I can view the grading results, score, and submission date for an assignment I submitted, so that I can understand my performance, confirm when I turned in the assignment, and review which questions I got right or wrong.
Acceptance Criteria:
- Given that a registered student is on the home screen
- And the student taps the "Report" tab at the bottom
- Then the student is redirected to the learning report page
- And the page displays a list of completed assignments
- And each assignment in the list shows the submission date
- When the student taps the "View Report" button for a desired assignment
- Then the student is redirected to the assignment report page
- And the page displays the grading results, score, and detailed question-by-question results (correct/incorrect)
User Story: As a registered student, I can view all my assigned assignments categorized by status (all, not started, in progress), so that I can easily understand what tasks I need to start, continue, or complete.
Acceptance Criteria:
- Given that a registered student is on the home screen
- And filter buttons are visible: "전체" (All), "시작 안함" (Not Started), "진행 중" (In Progress)
- When the student taps one of the filter buttons
- Then the assignment list below is filtered to show only assignments matching the selected status
- And the filtered assignments are displayed with their status information
User Story: As a registered student, I can view the progress, total number of questions, and due date of each assignment, so that I can easily track how much work I have completed and plan my time before the deadline.
Acceptance Criteria:
- Given that a registered student is on the home screen
- And the student can see a list of assignment cards
- When the student taps an assignment card
- Then the student is redirected to the assignment detail page
- And the page displays the assignment's progress, total number of questions, and due date
User Story: As a registered student, I can continue an assignment that I previously started, so that I can resume my work without losing progress and complete the assignment at my own pace.
Acceptance Criteria:
- Given that a registered student is on the home screen
- And the student has an in-progress assignment
- When the student taps the "이어하기" (Continue) tab at the bottom
- Then the in-progress assignment information is displayed
- And a "Start Assignment" button is visible at the bottom
- When the student taps the "Start Assignment" button
- Then the student is redirected to the assignment screen
- And the assignment resumes from where the student left off, preserving all previous progress
- Latency: AI feedback (quiz or evaluation) in < 15 seconds.
- Reliability: Ensure submission integrity (voice files, STT transcription, evaluation logs).
- Usability: Simple onboarding for both students and teachers.
- Scalability: Supports multiple concurrent quiz sessions.
- Availability: Single-node deployment (Gunicorn + PostgreSQL); uptime tracked manually, with planned migration to monitored hosting.
-
Security: JWT authentication (30-minute access tokens, 1-day refresh); secrets loaded from
.env; HTTPS termination handled by Nginx. - Privacy & Compliance: Voice and transcript data stored in PostgreSQL/S3; retention window configurable via admin scripts with S3 policy.
- Observability: Django structured logging to stdout; log aggregation/alerting TBD (currently manual tail and Sentry backlog item).
- Accessibility: UI follows Material accessibility guidelines; backend returns localized error messages (KR) where applicable.
- Device Support: Android API 26+ (phones/tablets); handles intermittent connectivity with local caching of assignments.
- Load Capacity: Increase concurrency by running Gunicorn with multiple worker processes.
- Resilience: S3 interactions wrapped in try/except with user-facing fallbacks; no circuit breaker yet.
- Maintainability: Django ORM migrations; OpenAPI (drf-yasg) generated docs.
- Data Store: PostgreSQL 15 for transactional data; AWS S3 for PDFs; Redis not yet in use.
Operational Metrics
- Track request latency and error rates via Django logs (exported weekly).
- STT transcription quality reviewed on sampled submissions.
- Tail-question latency monitored per request to keep total answer submission under 15 seconds.
- Bug reports maintained in Github Issues.
- Onboarding: Role selection (student/teacher), sign-up/login.
- Settings: Notifications, language, help, app info.
-
Teacher:
- Landing & Sign-Up: Teachers register and access their dashboard.
- Dashboard: Overview of classes, quizzes, and student progress.
- Quiz Management: Create, edit, or delete quizzes.
- Student Monitoring: View student details, performance.
- Reports: Check class-wide insights and learning trends.
-
Student:
- Landing & Sign-Up: Users enter the app and create an account as a student.
- Dashboard: Main hub showing quizzes, progress, and quick navigation.
- Quiz Details & Start: View quiz info and begin solving.
- Recording & Results: Answers are recorded and results shown with basic analytics.
- Reports & Profile: Students can track performance trends and edit personal settings.
The application provides user-friendly messages in all error scenarios. Backend APIs return structured error responses with Korean messages. Frontend ViewModels catch exceptions from Repository layers and display error messages to users. When network errors occur, the frontend generally displays "네트워크가 불안정합니다" (Network is unstable) either as a Toast or an in-screen message, distinct from generic error states.
Note that backend error messages are written in clear, user-friendly language to help users understand the situation in a reassuring and helpful manner. They are not raw terminal or stacktrace logs
Database operations are protected using Django's transaction.atomic() decorator/context manager (implemented in backend/questions/views.py). This ensures that multi-step operations either complete entirely or roll back completely, preventing partial saves or inconsistent database states.
Authentication
| Trigger | Displayed copy (original string → English meaning) | Location |
|---|---|---|
| Email field submitted empty | “이메일을 입력해주세요” → “Please enter your email.” |
LoginScreen, SignupScreen, email field error text |
| Password field submitted empty | “비밀번호를 입력해주세요” → “Please enter your password.” |
LoginScreen, SignupScreen, password field error text |
| Name field submitted empty | “이름을 입력해주세요” → “Please enter your name.” |
SignupScreen, name field error text |
| Confirm password field empty | “비밀번호 확인을 입력해주세요” → “Please confirm your password.” |
SignupScreen, confirm password field error text |
| Passwords do not match | “비밀번호가 일치하지 않습니다” → “Passwords do not match.” |
SignupScreen, confirm password field error text |
| Password shorter than 6 chars | “비밀번호는 최소 6자 이상이어야 합니다” → “Password must be at least 6 characters.” |
SignupScreen, password field error text |
| Invalid credentials / General error | Backend message (e.g., "이메일 또는 비밀번호가 올바르지 않습니다") |
LoginScreen, error card |
| Network failure during auth | “네트워크 연결을 확인하고 다시 시도해주세요” (or similar backend msg) |
LoginScreen, SignupScreen, error card |
Teacher Flow
| Trigger | Displayed copy (original string → English meaning) | Location |
|---|---|---|
| Class list fetch fails (Network) | “네트워크가 불안정합니다” → “Network is unstable.” |
TeacherClassesScreen, empty state |
| Class list is empty | “반이 없습니다” → “No classes found.” |
TeacherClassesScreen, empty state |
| Assignment list fetch fails (Network) | “네트워크가 불안정합니다” → “Network is unstable.” |
TeacherAssignmentResultsScreen, empty state |
| Assignment results list is empty | “제출된 과제가 없습니다” → “No submissions yet.” |
TeacherAssignmentResultsScreen, empty state |
| Detailed report fetch fails (Network) | “네트워크가 불안정합니다” → “Network is unstable.” |
AssignmentDetailedResultsScreen, empty state |
| Detailed report fetch fails (General) | “오류가 발생했습니다” + backend message |
AssignmentDetailedResultsScreen, error state card |
| Student report fetch fails (Network) | “네트워크가 불안정합니다” → “Network is unstable.” |
TeacherStudentReportScreen, empty state |
| Student report fetch fails (General) | “리포트를 불러올 수 없습니다” + backend message |
TeacherStudentReportScreen, error state card |
| Student report has no data | “리포트 데이터가 없습니다” → “No report data found.” |
TeacherStudentReportScreen, empty state |
| Student report has no submissions | “제출한 과제가 없습니다” → “No submitted assignments.” |
TeacherStudentReportScreen, empty state |
| Student result fetch fails (Network) | “네트워크가 불안정합니다” → “Network is unstable.” |
TeacherStudentAssignmentDetailScreen, empty state |
| Student result not found | “학생 결과를 찾을 수 없습니다” → “Student result not found.” |
TeacherStudentAssignmentDetailScreen, empty state |
| Class creation success | “수업이 생성되었습니다.” → “Class created.” |
TeacherClassesScreen, Toast |
| Class deletion success | “{ClassName} 수업이 삭제되었어요” → “{ClassName} class deleted.” |
TeacherClassesScreen, Toast |
| Class deletion failure | “수업 삭제에 실패했어요” → “Failed to delete class.” |
TeacherClassesScreen, Toast |
| PDF upload failure | “PDF 업로드 실패: {message}” |
CreateAssignmentScreen, error banner |
| Assignment creation failure | “과제 생성 실패: {message}” |
CreateAssignmentScreen, error banner |
| PDF file too large (>10MB) | “파일 용량이 너무 큽니다. 최대 10MB까지 업로드 가능합니다.” |
CreateAssignmentScreen, file selection error |
| Assignment title invalid char | “'/' 문자는 사용할 수 없어요.” → “'/' character is not allowed.” |
CreateAssignmentScreen, title field error |
| Invalid question count | “문제 개수는 1 이상이어야 합니다” → “Question count must be at least 1.” |
CreateAssignmentScreen, question count error |
| Class not selected warning | “ |
CreateAssignmentScreen, student selection area |
| No students in selected class | “해당 반에 학생이 등록되지 않았습니다.” → “No students enrolled in class.” |
CreateAssignmentScreen, student selection area |
| Edit assignment validation fail | “필수 항목을 모두 입력하고 올바른 형식인지 확인해주세요.” |
EditAssignmentScreen, Alert Dialog |
| Edit assignment missing ID | “수정할 과제 ID를 찾을 수 없습니다.” → “Assignment ID not found.” |
EditAssignmentScreen, Alert Dialog |
| Edit assignment update success | “과제가 성공적으로 수정되었습니다.” |
EditAssignmentScreen, Toast |
| Edit assignment update failure | “과제 수정에 실패했습니다. 인터넷 연결을 확인하세요.” |
EditAssignmentScreen, Toast |
| Assignment deletion success | “과제가 성공적으로 삭제되었습니다.” |
EditAssignmentScreen, Toast |
| Assignment deletion failure | “과제 삭제에 실패했습니다. 인터넷 연결을 확인하세요.” |
EditAssignmentScreen, Toast |
| Network error (general) | “네트워크가 불안정합니다.” |
EditAssignmentScreen, AssignmentDetailScreen, Toast |
Student Flow
| Trigger | Displayed copy (original string → English meaning) | Location |
|---|---|---|
| Dashboard fetch fails (Network) | “네트워크가 불안정합니다” → “Network is unstable.” |
StudentDashboardScreen, empty state |
| Dashboard has no assignments | “과제가 없습니다” → “No assignments available.” |
StudentDashboardScreen, empty state |
| Recent assignment fetch fails (Network) | “네트워크가 불안정합니다” → “Network is unstable.” |
NoRecentAssignmentScreen, empty state |
| No recent assignment | “이어할 과제가 없습니다” → “Nothing to continue.” |
NoRecentAssignmentScreen, empty state |
| Completed assignments fetch fails (Network) | “네트워크가 불안정합니다” → “Network is unstable.” |
ReportScreen, empty state |
| No completed assignments | “완료한 과제가 없습니다” → “No completed assignments.” |
ReportScreen, empty state |
| Assignment detail fetch fails (Network) | “네트워크가 불안정합니다.” (Toast) |
AssignmentDetailScreen, Toast |
| Assignment detail fetch fails (General) | Backend error message |
AssignmentDetailScreen, error card (if no data) |
| Assignment statistics fetch fails | “통계를 확인할 수 없습니다” → “Cannot verify statistics.” |
AssignmentDetailScreen, error card/Toast |
| Incomplete assignment check | “아직 모든 문제를 완료하지 못했습니다.” → “All questions not completed.” |
AssignmentDetailScreen, error card/Toast |
| Submission/Recording error | Backend error message or “오류가 발생했습니다” |
AssignmentDetailScreen, error card |
Notes
- The application uses
ErrorMessageMapperto detect network-related exceptions (timeouts, connection refused, etc.). - When a network error is detected, the UI consistently presents "네트워크가 불안정합니다" (Network is unstable) to the user, distinguishing it from logical or server-side errors.
- For lists (dashboards, results), this message appears in the empty state area.
- For actions (saving, updating), it typically appears as a Toast message.
- Consent Management: Planning to capture explicit guardian consent for minors; persist consent version, timestamp, and policy reference; re-consent triggered after substantive policy updates.
- Data Minimization: Collect only essential PII (name, email, role); redact STT transcripts before downstream analytics to remove sensitive phrases; anonymize aggregated reports.
- Audit Logging: We record key user actions such as account deletion, assignment edits, and role changes in server logs. These logs are preserved for debugging and accountability purposes.
- Incident Response: If something goes wrong, we keep a record and check it manually to fix the problem. Important issues are written down for later improvement.
-
Static & Formatting Checks: GitHub Actions workflow
.github/workflows/precommit.ymlrunspre-commit run --all-fileson every push/PR. Locally, contributors install the same hooks viapre-commit install(DEVELOPMENT.md). -
Backend Test Suite: Pytest is the canonical runner (
requirements.txtincludes pytest/pytest-django). Integration coverage lives underbackend/tests/test_integration.pyand feature modules inassignments/,courses/,submissions/, etc. Command:cd backend && pytest -q. -
Frontend Instrumentation Tests: Android UI and ViewModel tests reside in
frontend/app/src/androidTest/...with a customHiltTestRunner.

