| Câu | Nội dung | Chương | Độ khó | Sai đáp án hay chọn | % Sai |
|---|---|---|---|---|---|
| Câu 12 | Di truyền liên kết giới tính — gen trên NST X lặn | Ch.2 | VD | Đáp án B (sai) — chọn nhiều nhất | 68% |
| Câu 7 | Giai đoạn xảy ra hoán vị gen trong giảm phân | Ch.1 | TH | Đáp án A (sai) | 51% |
| Câu 19 | Đột biến mất đoạn NST — hậu quả | Ch.2 | TH | Đáp án C (sai) | 44% |
Cô đã giao bài: Kiểm tra 15 phút — Chương 1
Môn: Sinh học 12 · 20 câu · 15 phút
Thời gian mở: 20/05/2025 07:00
Hạn nộp: 21/05/2025 23:59
Vào app để làm bài nhé!
| Mức | Số câu | % |
|---|---|---|
| Nhận biết | 40% | |
| Thông hiểu | 40% | |
| Vận dụng | 20% |
| Câu hỏi | Chương | % Sai | |
|---|---|---|---|
| Di truyền liên kết giới tính | Ch.2 | 68% | |
| Phân bào giảm nhiễm | Ch.1 | 51% | |
| Đột biến cấu trúc NST | Ch.2 | 44% | |
| Quy luật Mendel — phân li | Ch.2 | 38% |
Frontend
- Stack: Vanilla JavaScript thuần (không framework). Build bundle 1 file HTML duy nhất
dist/OnThiAI.html(~1.8MB). - Hosting: Cloudflare Worker — domain chính
onthiai.com, backup*.workers.dev. - Domain registrar: Cloudflare Registrar, hết hạn 18/06/2027.
- CDN + SSL: Cloudflare tự cấp SSL Let's Encrypt, auto-renew.
Backend & Database
- Database: Supabase (PostgreSQL 17), region
ap-southeast-1(Singapore). - Project ID:
hyrjtdtqfhhleewjgtil. - Plan hiện tại: Free tier (500MB DB, 2GB egress/tháng). Upgrade Pro ($25/tháng) khi cần PITR backup.
- API: PostgREST auto-gen REST + RPC functions, Realtime websocket cho event kick/notification.
Authentication
- Provider: CHỈ Google OAuth (Email provider đã tắt).
- Cấu hình: Supabase Auth → Site URL =
https://onthiai.com, Redirect URLs gồm cả domain workers.dev backup. - Google OAuth Client: Quản lý tại console.cloud.google.com.
License System
- Payment processor: Gumroad — bán 3 plan (monthly $20, yearly $200, enterprise $500).
- License Worker:
onthi-license.nguyenngochoa-pay.workers.dev— validate key qua Gumroad API + ký HMAC + check KV device limit. - HMAC secret:
SIGN_SECRETtrong Worker =app_secrets.license_hmactrên Supabase. Rotate khi nghi ngờ lộ. - Live pricing: Worker
/productsfetch giá Gumroad + tỉ giá USD/VND live từopen.er-api.com(cache 5 phút / 6 giờ).
AI Features (multi-provider)
- Default provider: OpenAI —
gpt-4o-miniprimary →gpt-4.1-minifallback (rẻ, ít rate-limit). - Provider hỗ trợ: OpenAI · Anthropic Claude · Google Gemini · Groq (Llama) · DeepSeek. User có thể swap qua trang Cấu hình API.
- Hot-swap:
llm_active_provider/llm_primary_model/llm_fallback_modeltrong Admin Settings — đổi provider không cần rebuild. - Quota client: User tự nhập API key cho provider mình chọn → app dùng key đó → chi phí user trả.
- Server quota:
ai_daily_call_limitenforce qua localStorage counter (per user, reset 00:00). - PDF handling: Claude/Gemini nhận PDF binary native; OpenAI/Groq/DeepSeek extract text bằng
pdf.jsclient-side (CDNjsdelivr).
Backup
- Strategy: GitHub Actions cron daily 02:00 UTC (09:00 VN).
- Method:
pg_dump --schema=public→ upload artifact GitHub 30 ngày. - Trigger thủ công: GitHub repo → Actions → "Supabase Daily Backup" → Run workflow.
- Restore: tải artifact → giải nén .sql.gz → paste vào Supabase SQL Editor.
Monitoring
- Worker observability: Cloudflare dash → Worker → Logs (real-time).
- DB monitoring: Supabase Logs Explorer + trang Admin → Giám sát hệ thống.
- Uptime monitoring: chưa setup (cân nhắc UptimeRobot free).
- Error tracking: chưa setup (cân nhắc Sentry free 5k errors/tháng).
Network & Transport
- HTTPS bắt buộc: mọi connection dùng TLS 1.3 (Cloudflare).
- HSTS: max-age 1 năm, includeSubDomains.
- CORS: Worker chỉ cho phép request từ origin
onthiai.com+ workers.dev backup.
HTTP Security Headers (dist/_headers)
Content-Security-Policy:default-src 'self', KHÔNGunsafe-eval,frame-ancestors 'none'.X-Frame-Options: DENY— chống clickjacking.X-Content-Type-Options: nosniffReferrer-Policy: strict-origin-when-cross-originPermissions-Policy: tắt geolocation, microphone, camera, payment.
Database Security
- RLS (Row-Level Security): bật trên 100% bảng public. Mỗi user chỉ SELECT/INSERT/UPDATE/DELETE được data của mình.
- Function: 100%
security definercóset search_path = public(chống search_path attack). - Grant: critical RPC chỉ grant
to authenticated, khôngto anon/public. - FK cascade: mọi reference
profiles(id)/auth.users(id)đều cóon delete cascadehoặcset null— flow xoá account không bị half-deleted. - app_secrets table: RLS deny-all, chỉ security definer function đọc được.
Authentication & Session
- Password: KHÔNG bao giờ lưu trong DB — quản lý bởi Google.
- JWT: Supabase issue, expire sau 1 giờ, auto-refresh.
- Device limit: 1 PC + 1 Mobile / account. Login máy mới = kick máy cũ qua realtime websocket.
- Account deletion: self-service qua RPC
delete_my_account(), cascade hết — guard không cho xoá GV còn lớp / admin còn seat.
DEV Step-up Auth (PIN Lock)
Google OAuth chỉ verify password 1 lần lúc đăng nhập. Sau đó app chỉ giữ JWT token — KHÔNG có cách re-verify password client-side. Đây là giới hạn cố định của OAuth (không phải bug). Pattern industry-standard cho "sensitive operations" là step-up auth qua PIN riêng:
- GitHub Sudo Mode — nhập password tài khoản để unlock 1 giờ
- Vercel Step-up — re-auth qua OAuth/passkey
- Banking apps — PIN riêng khác mật khẩu chính
- DEV login Google → menu "Nhà phát triển" hiển thị section header có icon 🔒 (khoá).
- Bấm header → modal yêu cầu nhập PIN (lần đầu = đặt PIN, lần sau = nhập để verify).
- PIN đúng → sessionStorage lưu timestamp → body.dev-unlocked → CSS hiện các nút DEV (🔓 xanh).
- Idle 30 phút (không click/scroll/keydown/mousemove) → tự khoá lại.
- Đóng tab → mất unlock → session mới phải nhập PIN.
- Quên PIN → reset qua SQL:
delete from app_secrets where key like 'dev_pin_hash:%';
- Hashing: SHA-256 với salt =
user_id(quaextensions.digest). Plaintext PIN KHÔNG bao giờ lưu DB. - Per-user PIN: mỗi DEV có PIN riêng — key trong
app_secrets=dev_pin_hash:<user_id>. - Salt unique per user: chống rainbow table attack — cùng PIN ở 2 user khác nhau cho hash khác nhau.
- Brute force: Supabase rate-limit RPC (~1000 req/giờ/user). Kết hợp PIN ≥ 6 ký tự → không thể brute trong thời gian thực tế.
- Transport: PIN gửi qua HTTPS/TLS 1.3 → không sniff được trên đường truyền.
- RPC:
set_dev_pin(text),verify_dev_pin(text) → boolean,has_dev_pin() → boolean— tất cảsecurity definer, check_is_system_admin().
| Password Google | PIN DEV | |
|---|---|---|
| Khả thi kỹ thuật | ❌ OAuth không cho re-verify | ✅ Có |
| Bảo mật | App lớn (GitHub Sudo) dùng pattern này | Tương đương |
| Tiện | Nhớ 1 mật khẩu | Nhớ 2 (Google + PIN DEV) |
| Reset | Qua Google | Qua SQL (cần access Supabase = chỉ DEV thật làm được) |
Secrets Management
- Supabase anon key: public (by design — chỉ là pre-auth key, gateway tới Auth).
- Supabase service_role: KHÔNG BAO GIỜ xuất hiện ở client/Worker.
- SIGN_SECRET (HMAC): Worker secret, sync với
app_secrets.license_hmac. - DB password: chỉ dùng cho backup workflow, lưu GitHub Secret
SUPABASE_DB_URL. - GitHub PAT: dùng push code, expire 90 ngày, scope tối thiểu (
repo+workflow).
Anti-abuse
- Unique constraints:
exam_assignments(exam_id, class_id)— chống giao đề trùng. - Trial cheat prevention: Trial đếm upload từ
created_atkhông reset theo tháng (chặn bypass). - Billing cycle: 30 ngày từ
license_activated_at, không reset theo lịch dương (chuẩn product). - Bot Fight Mode: chưa bật trên Cloudflare (cân nhắc bật).
- CAPTCHA: chưa bật ở Supabase Auth (cân nhắc bật Turnstile).
| Item | Chi phí | Hạn | Note |
|---|---|---|---|
Domain onthiai.com | ~$10/năm | 18/06/2027 | Cloudflare Registrar at-cost |
| Cloudflare Workers | Free | — | 100k req/ngày free |
| Supabase | Free | — | 500MB DB, 2GB egress. Upgrade Pro $25/tháng khi cần backup PITR |
| GitHub | Free | — | Private repo + Actions 2000 phút/tháng |
| GitHub PAT | Free | 90 ngày | Rotate trước khi hết hạn |
| Gumroad | 10% + $0.30/txn | — | Trừ khi user mua |
| Open.er-api.com (FX) | Free | — | No auth, no limit hiển nhiên |
| OpenAI (mặc định) | Pay-as-you-go | — | User dùng key riêng · gpt-4o-mini ~$0.15/1M in |
| Anthropic Claude | Pay-as-you-go | — | User dùng key riêng · haiku-4-5 rẻ |
| Google Gemini | Free tier + Pay | — | User dùng key riêng · 2.5-flash |
| Groq / DeepSeek | Free tier / Pay | — | Provider phụ · OpenAI-compat endpoint |
- Runbook khi sự cố:
docs/OPERATIONS.md— emergency scenarios, routine, common fixes. - Setup backup:
docs/BACKUP-SETUP.md— step-by-step. - Git/GitHub guide:
docs/GIT-GITHUB-GUIDE.md— workflow 7 bước, lỗi thường gặp. - CLAUDE.md: hướng dẫn AI assistant — đọc trước mỗi session để hiểu project.
- Pre-prod audit:
.claude/skills/preprod-audit/SKILL.md— checklist 8 tầng trước launch.
| Tên đề | Môn | Số câu | Mã đề | Thời gian | Giao cho lớp | Trạng thái | |
|---|---|---|---|---|---|---|---|
| Kiểm tra 15 phút — Chương 1 | Sinh 12 | 20 câu | 132, 209 | 15 phút | 12A1 | Đang mở | |
| Thi học kỳ 1 | Sinh 12 | 40 câu | 132, 209, 315, 418 | 45 phút | 12A1 12A2 | Đang mở | |
| Ôn tập Di truyền liên kết | Sinh 12 | 30 câu | 501 | 30 phút | Chưa giao | Nháp |
- Sau khi đổi, data hiện tại sẽ KHÔNG còn truy cập được qua app này (vẫn còn nguyên trên Supabase cũ).
- Học sinh của bạn cũng phải biết URL mới để đăng nhập — nên báo cho HS biết trước.
- Bạn có thể quay lại Supabase chung bất cứ lúc nào.
- Bấm " Copy SQL setup" bên dưới
- Trong Supabase project mới: SQL Editor (sidebar trái) → New query
- Paste (Ctrl+V) → bấm Run (góc phải dưới hoặc Ctrl+Enter)
- Đợi 30-60s → thấy "Success" = xong
- Project URL — dạng
https://xxxxxxxx.supabase.co - anon public key — chuỗi dài bắt đầu bằng
eyJhbGc...
KIỂM TRA 15 PHÚT — SINH HỌC 12
| Nội dung câu hỏi | Chương | Độ khó | Loại | Số lần dùng | % Sai | ||
|---|---|---|---|---|---|---|---|
| ADN polymerase có chức năng gì trong quá trình nhân đôi ADN? | Ch.1 | Nhận biết | TN | 8 lần | 22% | ||
| Nguyên tắc bổ sung được thể hiện ở giai đoạn nào? | Ch.1 | Thông hiểu | TN | 5 lần | 44% | ||
| Di truyền liên kết giới tính — gen trên NST X, tính trạng lặn biểu hiện ở đời F2? | Ch.2 | Vận dụng | TN | 12 lần | 68% | ||
| Phân tích ý nghĩa của quá trình giảm phân trong tiến hoá | Ch.1 | Vận dụng | TL | 3 lần | 51% |
| Xếp loại | Điều kiện | Số HS | % |
|---|---|---|---|
| Giỏi | ≥ 8.0 | 12 | 28% |
| Khá | 6.5 – 7.9 | 16 | 38% |
| Trung bình | 5.0 – 6.4 | 8 | 19% |
| Yếu | < 5.0 | 6 | 14% |
| STT | Học sinh | Điểm | Đúng/Tổng | Thời gian | Phân loại | Điểm yếu | |
|---|---|---|---|---|---|---|---|
| 1 | NA Nguyễn Văn A |
8.5 | 34/40 | 32 phút | Giỏi | — | |
| 2 | TB Trần Thị B |
6.0 | 24/40 | 40 phút | Trung bình | Phân bào, Đột biến | |
| 3 | LC Lê Minh C |
4.5 | 18/40 | 45 phút | Yếu | Nhiều chương |
Có tệp đã có sẵn Q&A format chuẩn? Vào Ngân hàng câu hỏi → Import từ file.
Tệp này dùng được cho việc gì? Loại nội dung nào phù hợp?
- Có tiêu đề chương / mục rõ (vd
# Chương 1ở .md hoặc Heading 1 ở .docx) - Định nghĩa & khái niệm nêu thẳng, không vòng vo
- Ví dụ minh hoạ kèm kết quả cụ thể (số liệu, công thức rõ ràng)
- Tránh: ảnh chèn rời, bảng quá phức tạp, công thức toán dưới dạng ảnh
| Tên file | Loại | Kích thước | Ngày upload | Trạng thái |
|---|
| Ngày | Bài kiểm tra | Điểm | Đúng/Tổng | Thời gian | |
|---|---|---|---|---|---|
| 20/05 | Kiểm tra 15 phút — Ch.1 | 6.5 | 13/20 | 14 phút | |
| 18/05 | Ôn tập Di truyền — Ch.2 | 8.0 | 24/30 | 28 phút | |
| 15/05 | Thi thử HK1 (lần 1) | 6.0 | 24/40 | 42 phút | |
| 12/05 | Thi thử HK1 (lần 2) | 7.0 | 28/40 | 39 phút |
| File | Trạng thái | Câu hỏi tạo được | |
|---|---|---|---|
| tom-tat-di-truyen.pdf | Xong | 45 câu | |
| chuong2-trang10.jpg | Xong | 12 câu |
OnThiAI (sau đây gọi là "Dịch vụ") tôn trọng quyền riêng tư của người dùng. Tài liệu này giải thích chúng tôi thu thập, sử dụng và bảo vệ dữ liệu cá nhân như thế nào.
1. Dữ liệu chúng tôi thu thập
- Thông tin tài khoản: địa chỉ email và tên hiển thị do người dùng cung cấp khi đăng nhập.
- Thông tin hồ sơ: khối lớp, trường, vai trò (học sinh/giáo viên) do người dùng tự nhập.
- Hoạt động học tập: đề thi, câu hỏi, kết quả làm bài, tài liệu người dùng upload.
- KHÔNG thu thập: số điện thoại, địa chỉ nhà, vị trí GPS, dữ liệu sinh trắc học, danh bạ, ảnh cá nhân.
2. Cách dùng dữ liệu
- Cung cấp tính năng học và luyện thi cho người dùng.
- Phân tích kết quả để gợi ý câu hỏi và bài học phù hợp.
- Liên hệ kỹ thuật khi cần (qua email đăng ký).
- Cải thiện trải nghiệm dịch vụ.
- KHÔNG bán dữ liệu cho bên thứ ba. KHÔNG dùng cho quảng cáo. KHÔNG chia sẻ với mục đích thương mại khác.
3. Quyền của bạn
- Xem: mọi dữ liệu của bạn đều truy cập được trong app (trang Thông tin cá nhân, Lịch sử, Kết quả).
- Sửa: chỉnh sửa thông tin cá nhân qua giao diện app bất cứ lúc nào.
- Xoá: bấm "Xoá vĩnh viễn tài khoản" trong trang Profile — toàn bộ dữ liệu của bạn (đề, kết quả, lịch sử, lớp tham gia) sẽ bị xoá và KHÔNG khôi phục được.
- Xuất: Giáo viên có chức năng Backup/Export dữ liệu của riêng mình tại trang Xuất / Phục hồi dữ liệu.
4. Bảo mật
Chúng tôi áp dụng các biện pháp bảo mật theo tiêu chuẩn ngành để bảo vệ dữ liệu của người dùng. Mật khẩu được quản lý bởi nhà cung cấp dịch vụ đăng nhập (Google) — chúng tôi KHÔNG lưu trữ mật khẩu của bạn.
Mọi truy cập dữ liệu được kiểm soát chặt chẽ: người dùng chỉ xem được dữ liệu của chính mình hoặc của lớp mình tham gia (theo quyền vai trò).
5. Trẻ em dưới 16 tuổi
Nếu người dùng dưới 16 tuổi, cần có sự đồng ý của phụ huynh hoặc giáo viên phụ trách trước khi đăng ký tài khoản. Phụ huynh có thể yêu cầu xoá dữ liệu của con bằng cách email đến địa chỉ hỗ trợ bên dưới.
6. Lưu trữ thông tin trên thiết bị
Một số thông tin cần thiết (vd phiên đăng nhập, cấu hình cá nhân) được lưu trên thiết bị của bạn để app hoạt động mượt. Bạn có thể xoá bằng cách đăng xuất hoặc xoá dữ liệu trình duyệt.
Chúng tôi KHÔNG dùng công nghệ tracking cho quảng cáo hoặc bán thông tin sang bên thứ ba.
7. Liên hệ
Mọi câu hỏi về chính sách bảo mật, gửi email: nguyenngochoa.info@gmail.com
8. Thay đổi chính sách
Chúng tôi có thể cập nhật chính sách này. Thay đổi quan trọng sẽ được thông báo trong app. Tiếp tục sử dụng dịch vụ sau khi cập nhật = đồng ý với chính sách mới.
Bằng việc đăng ký và sử dụng OnThiAI ("Dịch vụ"), bạn đồng ý các điều khoản dưới đây.
1. Đối tượng sử dụng
- Học sinh: ôn tập, làm bài, theo dõi tiến độ. Phải có sự đồng ý của phụ huynh nếu dưới 16 tuổi.
- Giáo viên: tạo lớp, ngân hàng câu hỏi, giao đề, theo dõi kết quả học sinh. Cần đăng ký gói trả phí sau giai đoạn dùng thử.
- Admin trường: quản lý nhiều giáo viên qua gói trường học.
2. Tài khoản
- Đăng nhập qua tài khoản Google — bạn chịu trách nhiệm bảo mật tài khoản của mình.
- 1 tài khoản chỉ được phép đăng nhập trên 1 máy tính + 1 thiết bị di động cùng lúc. Đăng nhập máy mới sẽ tự động đăng xuất máy cũ cùng loại.
- Cấm chia sẻ tài khoản (đặc biệt với vai trò giáo viên — vi phạm có thể bị khoá tài khoản).
- Bạn có thể tự xoá tài khoản qua trang Thông tin cá nhân bất cứ lúc nào.
3. Thanh toán & Gói dịch vụ
- Có sẵn các gói: Dùng thử miễn phí, Gói tháng, Gói năm, Gói trường học.
- Thanh toán qua đối tác thanh toán quốc tế, hỗ trợ thẻ Visa/Mastercard/PayPal.
- Giá hiển thị theo USD và quy đổi sang VND theo tỉ giá tham khảo. Số tiền thực tế thẻ trừ có thể chênh nhẹ theo tỉ giá ngân hàng tại thời điểm thanh toán.
- Không hoàn tiền: sau khi thanh toán thành công, các khoản phí KHÔNG được hoàn lại trong mọi trường hợp. Vui lòng cân nhắc kỹ và sử dụng giai đoạn dùng thử miễn phí để đánh giá dịch vụ trước khi mua gói trả phí.
- Hết hạn gói → tài khoản bị giới hạn (vẫn xem được dữ liệu cũ, không tạo mới được).
4. Nội dung do người dùng tạo
- Câu hỏi, đề thi, tài liệu bạn upload thuộc bản quyền của bạn.
- Bạn cấp cho OnThiAI quyền lưu trữ và xử lý nội dung của bạn để cung cấp dịch vụ.
- Không upload nội dung vi phạm bản quyền, đồi truỵ, kích động, hoặc sai sự thật về kiến thức.
- Chúng tôi có thể xoá nội dung vi phạm mà không cần báo trước.
5. Tính năng AI & tính chính xác
- Dịch vụ cung cấp các tính năng hỗ trợ bằng trí tuệ nhân tạo (sinh câu hỏi, nhận xét học sinh).
- Nội dung do AI sinh ra CÓ THỂ SAI hoặc thiếu chính xác — giáo viên phải kiểm duyệt trước khi giao cho học sinh.
- Chúng tôi không chịu trách nhiệm cho điểm số hay kiến thức sai do AI sinh ra mà chưa được kiểm duyệt.
6. Cấm hành vi
- Phá hoại hệ thống, thu thập trái phép dữ liệu, tấn công làm gián đoạn dịch vụ.
- Tạo nhiều tài khoản dùng thử nhằm né tránh thanh toán.
- Phát tán tài khoản hoặc khoá kích hoạt cho người khác sử dụng (gói cá nhân = 1 người dùng).
- Cố ý gian lận trong quá trình làm bài thi.
7. Trách nhiệm & Giới hạn
- Dịch vụ được cung cấp "đúng theo hiện trạng" (AS IS) — chúng tôi cố gắng giữ chất lượng dịch vụ tốt nhất nhưng không cam kết uptime tuyệt đối.
- Trách nhiệm tối đa của chúng tôi với bạn = số tiền bạn đã thanh toán trong 30 ngày gần nhất.
- Chúng tôi không chịu trách nhiệm cho mất mát dữ liệu do người dùng thao tác nhầm (vd tự xoá tài khoản → không khôi phục được).
- Khuyến nghị: dùng tính năng Backup/Export trong app để tự lưu dữ liệu quan trọng của bạn.
8. Chấm dứt
- Bạn có thể xoá tài khoản bất cứ lúc nào (trang Thông tin cá nhân → Xoá vĩnh viễn).
- Chúng tôi có thể khoá tài khoản nếu vi phạm điều khoản, sau khi cảnh báo qua email.
- Gói đã thanh toán KHÔNG được hoàn tiền khi tài khoản bị khoá do vi phạm.
9. Thay đổi điều khoản
Chúng tôi có thể cập nhật điều khoản này. Thay đổi quan trọng sẽ thông báo qua email và popup khi đăng nhập. Tiếp tục sử dụng dịch vụ = chấp nhận điều khoản mới.
10. Luật áp dụng
Điều khoản này áp dụng theo luật pháp Việt Nam. Tranh chấp được giải quyết tại toà án có thẩm quyền nơi nhà cung cấp dịch vụ đặt trụ sở.
11. Liên hệ
Email hỗ trợ: nguyenngochoa.info@gmail.com