PRD-010 - NEMO IELTS (app iOS + Android)
Một câu: learner IELTS mở điện thoại và làm ngay việc tiếp theo của mình, không cần mở trình duyệt, không cần đăng nhập lại mỗi tuần. Tiến độ là một: làm trên app hay trên
learn.nemo12.com/ieltsđều ghi vào cùng một hồ sơ.
Trạng thái: draft 0.2. Chủ dự án chốt năm điều ngày 28.09.2026 (§9) và cùng ngày "đồng ý hết" năm đề xuất còn lại (§10), rồi yêu cầu bắt đầu dựng đợt 0. Bảng REQ chép vào PRD-001 §5 nhóm REQ-MOB. Thiết kế: SDD-055.
0. Vì sao cần một app riêng
Sân luyện IELTS đã chạy đủ trên web (SDD-035, SDD-038, Journey Engine SDD-045). Có ba chỗ web làm kém trên điện thoại, và cả ba đều là chỗ learner IELTS dùng nhiều nhất:
- Speaking. Ghi âm trong trình duyệt di động phụ thuộc quyền micro của từng trình duyệt, hay hỏng khi màn hình khoá hoặc chuyển tab. App có quyền micro ổn định.
- Thói quen hằng ngày. Học IELTS là 15-30 phút mỗi ngày trong nhiều tháng. Một biểu tượng trên màn hình chính và một lời nhắc đúng giờ giữ nhịp tốt hơn một tab trình duyệt.
- Phiên đăng nhập. Cookie phiên trên Safari di động bị ITP xoá sau vài ngày không mở, nên learner bị đẩy ra màn đăng nhập đúng lúc định học.
App không là sản phẩm thứ hai. Nó là một lớp giao diện thứ hai trên cùng backend.
1. Người dùng
| Vai | Là ai | Dùng app để |
|---|---|---|
| Learner | Người đã có hoặc sắp có hồ sơ IELTS ở Nemo12 | Làm việc tiếp theo, luyện kỹ năng, ghi âm Speaking, xem tiến độ |
| Phụ huynh | Người trả tiền | Không dùng app ở v1. Vẫn theo dõi qua web (marlins). Xem Q-196 |
| Staff / Dolphin | Vận hành, mentor | Không dùng app. Admin và Dolphin vẫn là web |
Độ tuổi, band đầu vào và band mục tiêu: dùng đúng learner model IELTS đang có (ielts-learner-model.md), không định nghĩa lại ở đây.
2. Việc cần làm (JTBD)
- Mở là học. Khi tôi có 15 phút rảnh, tôi muốn mở app và thấy ngay một việc cần làm, không phải chọn giữa mười thứ.
- Nói to được. Khi luyện Speaking, tôi muốn ghi âm, nghe lại và nộp mà không sợ mất bài.
- Không bị đứt. Khi đang làm dở trên web, tôi muốn mở app thấy đúng chỗ đó, và ngược lại.
- Biết mình tiến không. Sau mỗi tuần, tôi muốn thấy mình đã làm gì và đang ở đâu so với mục tiêu.
3. Phạm vi theo đợt
Chủ dự án yêu cầu lên TestFlight càng sớm càng tốt. Nên phạm vi chia theo đợt, đợt đầu nhỏ nhất có thể mà vẫn học được thật.
| Đợt | Mục tiêu | Gồm |
|---|---|---|
| Đợt 0: TestFlight nội bộ | Chủ dự án cài được bản thật trên iPhone | Đăng nhập, màn Home với việc tiếp theo, luyện Reading + Listening, xem tiến độ |
| Đợt 1: TestFlight mở rộng | 10-20 learner thật dùng hằng ngày | + Speaking ghi âm, Writing nộp bài, nhắc học bằng push, Android bản internal testing |
| Đợt 2: lên store | App Store + Google Play công khai | + tải trước đề để làm offline, chế độ thi thật có đếm giờ, trang thông tin membership |
Không có trong app ở mọi đợt (cố ý): mua gói, onboarding phụ huynh, admin, soạn nội dung.
4. Hành trình learner trong app
Mở app ──► chưa đăng nhập ──► Đăng nhập Google / Apple ──► chưa có hồ sơ IELTS ──► setup (dùng API setup có sẵn)
│
▼
Home: MỘT việc tiếp theo (Journey Engine, SDD-045)
│
┌──────────────┬──────────────┬─────────────┴─┬───────────────┐
▼ ▼ ▼ ▼ ▼
Reading Listening Speaking Writing Progress
(đợt 0) (đợt 0) (đợt 1) (đợt 1) (đợt 0)
└──────────────┴─── kết quả ghi vào cùng API ───┴───────────────┘5. Luật ngôn ngữ
App là sân luyện IELTS nên theo đúng luật của learn.nemo12.com/ielts/** (CLAUDE.md, SRC-834, SRC-953): tên màn, tên kỹ năng, nhãn trạng thái và nội dung đề tiếng Anh; chữ Nemo giải thích bài (giới thiệu, giới hạn của phép đo, dặn dò, câu tóm tắt kết quả, nhãn nút hành động) tiếng Việt. Không có công tắc VI/EN. Hai luật chữ chung vẫn áp dụng: cấm em dash, ngày viết DD.MM.YYYY. Chủ dự án đồng ý 28.09.2026 (Q-199).
Từ 10.10.2026 (SRC-1325) trang bốn kỹ năng và mọi trang dưới chúng, Full tests và Grammar nói tiếng Anh 100%, kể cả chữ hướng dẫn và nhãn nút; luật SRC-953 ở trên chỉ còn áp cho các trang hành trình. Đừng dịch ngược.
6. Yêu cầu (REQ-MOB)
Status: ✔ đã code · 🔵 đang code · ⏳ chưa code hoặc chờ quyết định. Tất cả đang ⏳ vì PRD vừa mở.
| ID | Yêu cầu | Ưu tiên | Đợt |
|---|---|---|---|
| REQ-MOB-01 | Một app tên NEMO IELTS, viết bằng Flutter, một codebase ra cả iOS và Android; bundle id com.nemo12.ielts | M | 0 |
| REQ-MOB-02 | Dùng chung backend api.nemo12.com, chung D1, chung hồ sơ learner. App không có bảng dữ liệu riêng cho nội dung học; mọi bài làm ghi qua API hiện có | M | 0 |
| REQ-MOB-03 | Đăng nhập bằng Google (iOS + Android) và Sign in with Apple (iOS). Người đã học trên web bằng Google chọn Google thì vào đúng tài khoản cũ; không tự gộp tài khoản theo email (RISK-001) | M | 0 |
| REQ-MOB-04 | Phiên đăng nhập dài hạn: learner không phải đăng nhập lại khi còn mở app ít nhất một lần mỗi 30 ngày; token giữ trong Keychain / Keystore, không trong bộ nhớ thường | M | 0 |
| REQ-MOB-05 | Home chỉ hiện một việc tiếp theo lấy từ Journey Engine (SDD-045), đúng luật tối giản SRC-048 | M | 0 |
| REQ-MOB-06 | Luyện Reading và Listening bằng đúng kho đề trong D1; audio phát được khi màn hình khoá | M | 0 |
| REQ-MOB-07 | Màn Progress: bốn kỹ năng, mục tiêu band, hoạt động bảy ngày gần nhất, đọc từ API có sẵn | M | 0 |
| REQ-MOB-08 | Hồ sơ chưa setup IELTS thì đi qua setup ngay trong app, không đẩy ra web | S | 0 |
| REQ-MOB-09 | Speaking: ghi âm bằng micro, nghe lại, nộp; bài ghi dở không mất khi app bị đưa xuống nền | M | 1 |
| REQ-MOB-10 | Writing: soạn bài, tự lưu nháp trên máy, nộp qua API productions có sẵn | M | 1 |
| REQ-MOB-11 | Nhắc học bằng push notification: learner chọn giờ; tối đa một lời nhắc mỗi ngày; tắt được trong app | S | 1 |
| REQ-MOB-12 | Tải trước một đề (nội dung + audio) để làm offline; bài làm offline tự đồng bộ khi có mạng, không tạo bản ghi trùng | S | 2 |
| REQ-MOB-13 | Chế độ thi thật: đếm giờ theo chuẩn IELTS, tự nộp khi hết giờ | S | 2 |
| REQ-MOB-14 | App không bán gì. Membership chỉ hiện trạng thái; không có nút mua, không có link dẫn ra trang thanh toán (App Store Review 3.1.1 / 3.1.3) | M | 0 |
| REQ-MOB-15 | Có trang xoá tài khoản ngay trong app (App Store Review 5.1.1(v)) và link chính sách quyền riêng tư | M | 0 |
| REQ-MOB-16 | Giao diện dựng lại bằng widget Flutter theo token DS-001 (màu, chữ, bo góc, khoảng cách, nhịp chuyển động) để app và web nhìn là một họ | M | 0 |
7. Chỉ số thành công
| Chỉ số | Đo ở đâu | Mốc đợt 1 |
|---|---|---|
| Learner dùng app ≥ 4 ngày/tuần | learning_events theo client = 'ios' / 'android' | ≥ 50% số người cài |
| Bài Speaking nộp thành công / bài bắt đầu | ielts_productions | ≥ 90% |
| Crash-free sessions | Firebase Crashlytics hoặc Sentry (SDD-055 §9) | ≥ 99% |
8. Ràng buộc
- Flutter đứng ngoài bộ ba Motion + shadcn + Tailwind (SRC-650). Đây là chỉ đạo của chủ dự án ngày 28.09.2026: viết lại từ đầu bằng Flutter thay vì bọc React bằng Capacitor. Giống bốn site VitePress, đây là giới hạn kỹ thuật chứ không phải chỗ tuỳ tiện: ba gói ấy là thư viện web và không chạy trong Flutter. Cái giữ lại được là token (REQ-MOB-16).
- Đứng tên cá nhân trên App Store và Google Play: tên người bán hiển thị trên store là tên chủ tài khoản, không phải "Nemo12".
- Google Play với tài khoản cá nhân tạo sau 11.2023 bắt buộc thử nghiệm kín 12 người trong 14 ngày trước khi được lên production. Phải tính vào lịch đợt 2.
9. Chủ dự án đã chốt (28.09.2026)
| # | Câu hỏi | Trả lời |
|---|---|---|
| 1 | Quan hệ với sân luyện web | Chung backend |
| 2 | Công nghệ hybrid | Flutter, viết lại từ đầu |
| 4 | Đăng nhập | Để phiên soạn chọn cách dễ nhất → Google + Sign in with Apple (lý do: SDD-055 §4) |
| 10a | Tên app | NEMO IELTS |
| 10b | Phát hành | TestFlight trước, càng sớm càng tốt; đứng tên cá nhân |
10. Đề xuất đã được đồng ý (28.09.2026)
| Q | Câu hỏi | Đã chốt |
|---|---|---|
| Q-196 | Phụ huynh có dùng app không? | Không ở v1, vẫn dùng web |
| Q-197 | Kỹ năng trong phạm vi | Đủ bốn kỹ năng; Speaking/Writing nộp và nhận phản hồi như web, không thêm chấm AI mới |
| Q-198 | Thu tiền trong app | Không bán trong app; chỉ hiện trạng thái membership |
| Q-199 | Ngôn ngữ giao diện | Theo luật sân luyện SRC-834/953 (§5) |
| Q-200 | Offline, push, chế độ thi thật | Có, nhưng để đợt 1-2, không chặn TestFlight |