Doubts
A student gets stuck on something, opens the Doubts page, picks a subject, types or records the question, attaches images / PDFs if needed, and routes it to a specific teacher. The teacher gets a notification, opens the doubt, writes the solution (with their own attachments), and replies. The student listens / reads, then marks it resolved.
At a glance
| Who can do this | Students post · Teachers answer · only the assigned teacher and the student see the thread |
| Where it lives | Student app /dashboard/doubt (Ask + History tabs) · Teacher app /dashboard/doubts (list) → /dashboard/doubts/:doubtId (solution view) |
| Triggers notifications? | Yes — teacher gets notified when a doubt is assigned to them; student gets notified when the teacher answers |
| Related features | Notifications · AI Tutor (a separate, instant alternative) · Notice Board & Alerts |
How it flows
Status lifecycle
Pending and Answered are both "open" from the student's point of view — both show a "Mark Resolved" button. Rejected is terminal and no further action is offered.
Step-by-step
1. Student composes the doubt
- App / route: Student app →
/dashboard/doubt, Ask tab (default). - The page loads:
- The student's profile (to know
schoolId+sectionId). - Subjects assigned to the student's section.
- Teachers — initially all teachers in the school; once a subject is picked, the list narrows to teachers who teach that subject in that section.
- The student's profile (to know
- The student fills in:
- Subject — required, single-select chip list.
- Doubt text — typed in the textarea.
- Attachments (optional) — images, PDFs,
.doc/.docx, multi-select via paperclip icon. - Voice note (optional) — record via the mic button. While recording, the mic button turns red, pulses, and shows "Recording... Tap stop to save". The recording becomes a
voice-doubt-<timestamp>.webmfile. Recording requires microphone permission. - Teacher — exactly one teacher must be selected (the chip toggles single-select).
- The summary strip at the bottom always shows: subject name, teachers selected, attachment count.
- Either typed text or a voice note is required. If text is empty and a voice note is attached, the doubt content is recorded as
"Voice Doubt Attached".
2. Send → upload → create
On tapping Send Doubt Request:
- Validates: subject picked, text or voice present, at least one teacher picked.
- Uploads each regular attachment in parallel (S3 via the upload service).
- Uploads the voice note (if any) as a separate attachment.
- Creates the doubt with the uploaded attachment IDs and the picked teacher.
- Toasts "Doubt request sent successfully!" and opens a success modal.
- Resets the form (subject, teacher, attachments, voice note all cleared).
3. Student tracks history
- App / route: Same page, History tab.
- Lists the student's last ~20 doubts, ordered:
- Resolved doubts pushed to the bottom.
- Within each group, latest
updatedAtfirst.
- Each card shows: subject, status badge (Pending / Answered / Resolved / Rejected), the question (italicised quote), assigned teacher chip, and a count of total attachments (student + teacher combined).
- Tapping the attachments chip expands the card and lazy-loads:
- Student's voice doubt (audio with play/pause).
- Student's file attachments (open in new tab).
- Teacher's written solution (if status is Answered or Resolved).
- Teacher's voice solution.
- Teacher's file attachments.
- A Mark Resolved button is shown when status is
PendingorAnswered.
4. Teacher inbox
- App / route: Teacher app →
/dashboard/doubts. - Filter pill bar across the top: All Doubts · Pending · Answered · Resolved · Rejected. Default is All, fetching the latest 50 doubts assigned to the logged-in teacher.
- Each card shows: status icon + colour-coded badge, student name, the question (line-clamp 2), subject pill, and creation date.
- The teacher tracks pending doubts here. Empty filter shows a friendly "You're all caught up!" empty state.
5. Teacher answers
- App / route:
/dashboard/doubts/:doubtId. - The page is split:
- Top card — student info (avatar, name, subject, asked-at), the question in italics, attachments collapsible (expanded by default). Voice doubts have a play button.
- Bottom card — solution textarea + attach button + submit button.
- Teacher workflow:
- Read the question; play the voice note; open file attachments.
- Type a solution (required, non-empty).
- Optionally attach files (images / PDFs) — multiple, previewed as chips with a remove
×. - Tap Submit → uploads attachments → submits the solution.
- On submit: status flips
PENDING → ANSWERED. Toast "Solution submitted successfully" and routes back to the list. - The textarea, attach, and submit buttons are disabled if status is already
ANSWEREDorRESOLVED— the teacher cannot edit a solution after sending.
6. Student closes the loop
- The student opens History → expands the card → reads / plays the teacher's solution.
- Taps Mark Resolved → status flips
ANSWERED → RESOLVED. Toast "Marked as resolved". - After resolved the card stays in history (sorted to the bottom) but the action button disappears.
AI-suggested answers
Doubts is a human teacher-driven feature — there is no AI auto-suggested answer in the doubt flow itself. Students who want an instant AI-generated explanation use AI Tutor, which is a separate route (/dashboard/ai-tutor) and a separate page in the dashboard. The two features are intentionally side-by-side so the student can choose between "ask a real teacher" (slower, no coins) and "ask the AI" (instant, coin-metered).
Edge cases & things to test
- Subject with no teachers: pick a subject that has no teacher mapped to the student's section → list shows "No teacher available for this subject"; Send button blocked.
- No subject + no teachers loaded: arrive at the page with
sectionIdmissing on the profile → toast "Failed to load initial data" + empty teacher list. - Voice-only doubt: leave the textarea empty, attach a voice note → should submit successfully with
content = "Voice Doubt Attached". - Microphone permission denied: tap mic, browser denies permission → toast "Could not access microphone"; no recording state stuck on.
- Recording then leaving page: start recording, navigate away → microphone tracks should be released (no red indicator stays on after leaving).
- Same file twice: pick the same image twice from the file picker — the input is reset on each open so the second pick should still register.
- Large attachment / many attachments: try multiple PDFs > 10 MB combined — confirm upload errors don't leave the form in a half-submitted state.
- Network drop mid-send: kill Wi-Fi after tapping Send → expect "Failed to send doubt request" toast, form values preserved so the student can retry.
- Switching subject mid-flow: pick subject A, pick teacher A, switch to subject B → teacher selection resets to empty (so student doesn't accidentally route to a teacher who doesn't teach the new subject).
- Teacher offline / never opens: doubt sits in
PENDINGindefinitely — student can still mark it resolved themselves at any time. - Teacher tries to re-answer: open an already-
ANSWEREDdoubt as the teacher → solution textarea, attach, and submit must all be disabled. - Empty solution submit: teacher hits Submit with whitespace-only solution → blocked client-side with "Solution cannot be empty".
- Cross-teacher visibility: doubt assigned to Teacher A — does Teacher B see it in their list? Should not.
- Student transferred sections: student moves from Section A to Section B mid-thread — does the existing doubt still show in their history? (Existing doubts should remain — they're tied to the doubt record, not the section.)
- History sorting: post 3 doubts (1 Resolved, 1 Answered, 1 Pending) — Resolved must appear at the bottom; the other two ordered by latest update.
- Attachment expansion lazy-load: expanding a card the first time should fetch attachments; collapsing and re-expanding should not re-fetch.
Related
- Notifications — both directions (assign + answer) fan out push + in-app
- AI Tutor — instant alternative when the student does not want to wait for a teacher
- Notice Board & Alerts — teachers can also broadcast subject-wide clarifications instead of answering one-by-one