Skip to content

PRD: Tokyo Live Learning Workspace ​

Sản phẩm: tokyo.conan.school · Tính năng: Live Learning Workspace · Trạng thái: Draft v1.0 Người dùng: Host, Learner · Nền tảng video: Zoom (Tokyo không làm video/audio)

1. Một câu định nghĩa ​

Tokyo Live Learning là lớp tương tác học tập cho workshop Zoom. Nó cho host một Live Stage và một bộ nhỏ hoạt động học, Quiz, Poll, Reflection, Questions, Tasks, đồng thời biến mọi tương tác của người tham dự thành learning evidence dùng lại được sau buổi học.

Zoom lo video + audio + meeting. Tokyo lo learning interaction + participation + evidence. Learner không phải nhảy qua Kahoot → Google Form → Padlet → Docs.

2. Bốn nguyên tắc ​

  1. Few things, done well, không dựng LMS thứ hai. Chỉ những tương tác cần trong một buổi live.
  2. Host controls the flow, host quyết activity nào đang mở, cái gì lên Stage, khi nào đóng.
  3. Everything happens in context, mọi tương tác nằm trong một workspace duy nhất.
  4. Interaction produces evidence, quiz/reflection/question/task đều để lại dấu vết học tập.

3. Kiến trúc thông tin ​

Về dữ liệu, có 7 khối; về giao diện, chỉ 4 mục + Stage luôn hiện diện.

text
Event
└── Live Learning Workspace
    ├── Resources
    ├── Activity        (Quiz · Poll · Reflection · Task, một họ, bốn kind)
    ├── Live Stage      (component trung tâm, không phải tab)
    ├── Questions       (+ Vote)
    ├── Participants
    └── Session Record

Giao diện learner (Stage là trung tâm, đây là UX signature):

text
┌──────────────────────────────────────────────┐
│                  LIVE STAGE                  │
│        What is the customer's problem?       │
├──────────────────────────────────────────────┤
│ Resources │ Activities │ Questions │ People  │
└──────────────────────────────────────────────┘

Learner luôn trả lời được câu "bây giờ đang làm gì?" mà không cần hỏi.

4. Vai trò ​

LearnerHost
Resourcesxemthêm/sửa/xoá/sắp xếp/ẩn-hiện
Quiz · Polltrả lời, bầutạo, start/pause/close, xem kết quả
Reflectionnộptạo (chọn framework), xem
Questionshỏi, upvote / bỏ upvoteduyệt, ẩn, đóng vote, đưa lên Stage
Tasksnộp, nhận đánh giá AItạo, chấm bằng AI, đưa bài lên Stage
Participantsxem hồ sơ rút gọnxem hồ sơ đầy đủ
Live Stagexemshow / remove

5. Module 1: Resources ​

V1: chỉ URL + PDF. Không xây document viewer riêng; PDF mở bằng embedded viewer của trình duyệt. PPTX/DOCX/ảnh để sau. Host: thêm, sửa, xoá, đổi thứ tự, ẩn/hiện.

Đã có tiền lệ trong repo: bảng workshop_resources (migration 0065) với đúng các cột title/url/type/sort_order/is_active, Resources của workspace nên tái dùng hình dạng này, không phát minh lại.

6. Module 2: Activities (một họ, bốn kind) ​

Đây là đề xuất 1 đã chốt về mặt kiến trúc: Quiz, Poll, Reflection, Task là bốn kind của cùng một bảng activity, không phải bốn module riêng. UI chỉ có một mục "Activities"; host bấm Create Activity rồi chọn loại. Mental model đơn giản hơn hẳn, và thêm loại thứ năm sau này không phải đổi kiến trúc.

Mỗi activity có vòng đời chung:

text
DRAFT → ACTIVE → PAUSED → CLOSED

Quiz ​

Single choice hoặc multiple choice. Sau khi nộp, host quyết định có hiện đáp án / giải thích hay không.

Poll ​

Không có đúng/sai. Kết quả hiển thị theo phần trăm.

Reflection ​

Không phải một loại quiz, là trải nghiệm phản tư có khung. V1 có hai framework:

  • 4F, Facts / Feelings / Findings / Future
  • Start / Continue / Stop

Framework là dữ liệu, không phải mã: thêm What–So What–Now What, Gibbs, Plus/Delta sau này chỉ là thêm một bản ghi framework, không sửa schema.

Task ​

Prompt + thời gian + free text. Sau khi nộp → AI evaluation theo rubric, không phải "Good answer!".

7. Live Stage ​

Live Stage là core component, không phải một activity. Host broadcast cho toàn phòng: câu hỏi, kết quả poll, kết quả quiz, một câu trả lời được chọn, hoặc prompt của một task.

text
EMPTY → ACTIVE → PAUSED → CLOSED

Host có đúng hai hành động: Show on Stage và Remove from Stage. Stage luôn có một nội dung tại một thời điểm, đó là điều làm nó trả lời được câu "đang làm gì".

8. Questions ​

Learner đặt câu hỏi; câu hỏi vào danh sách chung, sắp theo số upvote.

text
↑ 24   Vì sao phải phân biệt triệu chứng với vấn đề?
↑ 17   Cho thêm một ví dụ được không?

Chỉ có Upvote / Remove Upvote, không có downvote. Mục đích là đo bao nhiêu người quan tâm, không phải chấm câu hỏi hay/dở. Host đặt được hạn đóng vote (Voting closes in 05:00); sau hạn, cả upvote lẫn bỏ upvote đều khoá, và khoá phải nằm ở API, không phải ẩn nút ở giao diện.

9. Participants ​

Hồ sơ: Full name · Province/City · Birth year · Occupation · Industry (dropdown).

Đây là dữ liệu cá nhân. Vì có năm trường ghép lại (năm sinh + nơi ở + nghề + ngành), mặc định public toàn bộ là sai. V1 tách hai lớp hiển thị (đề xuất 3 đã chốt):

Learner thấyHost thấy
Nguyễn Văn A · Hà Nội · EducationNguyễn Văn A · Hà Nội · 1987 · Teacher · Education

Learner tự chọn Visible to participants hoặc Visible to host only. Ranh giới vẽ ở API: trường không được phép thấy thì không có mặt trong phản hồi, chứ không phải bị ẩn bằng CSS, cùng luật với nội dung trả phí ở www.

10. Tasks & mô hình chấm ​

text
Task
├── Prompt
├── Response
└── Evaluation
     ├── Criterion 1 … 3
     ├── Overall
     └── Feedback

Ví dụ đầu ra:

CriterionScore
Clarity4/5
Customer focus3/5
Specificity4/5

Host thấy tổng hợp: 98 submissions · Excellent 12 · Good 51 · Needs Work 27 · Incomplete 8, và có thể xem từng bài, xem đánh giá, đưa lên Stage.

Rubric của task đi cùng task và lưu lại theo bản, sau này map được vào Competency / Indicator.

11. Luồng ​

Host: Join → Resources → Poll → Stage(kết quả) → dạy → Quiz → Stage(kết quả) → dạy → Reflection → Questions → Task → AI evaluation → Stage(bài được chọn) → Wrap-up.

Learner: Join → workspace → Resources → tham gia (Quiz/Poll/Reflection/Question/Task) → AI evaluation → Session Record.

12. Session Record ​

Sau buổi học, learner xem lại toàn bộ dấu vết của mình: tài liệu, câu trả lời quiz/poll, bản reflection, câu hỏi đã đặt, bài task + đánh giá AI. Đây là phần biến 90 phút Zoom thành một artifact quay lại được

  • và là lý do tồn tại của nguyên tắc 4.

13. Mô hình dữ liệu (conceptual) ​

text
Event
├── Participant        (+ profile visibility)
├── Resource
├── Activity           kind ∈ {quiz, poll, reflection, task}, state ∈ {draft,active,paused,closed}
│    ├── ActivityItem  (câu hỏi / lựa chọn / prompt của framework)
│    └── Response      (+ Evaluation cho task)
├── Question ── Vote
└── StageState         (một dòng cho mỗi event: đang chiếu gì)

Mọi tương tác gắn event · session · user · timestamp, không có bốn trường đó thì không dựng được learning evidence.

14. V1 KHÔNG làm ​

Whiteboard · breakout room · live reactions · analytics điểm danh phức tạp · chat · ghi hình · LMS đầy đủ · document editor · leaderboard · gamification · AI chatbot.

Zoom đã làm tốt phần lớn những thứ này. Tokyo tập trung vào learning interaction.

15. Quyết định đã chốt (08.09.2026, người soạn duyệt) ​

Câu hỏiChốt
Đồng bộ Live StagePolling 3 giây trên GET /api/events/:slug/live. Mỗi lượt ghi của host nhích revision; client chỉ render lại khi số đó đổi. Không dựng Durable Object cho V1.
Gắn vào họ bảng nàoevents, họ đã có RSVP, event_meetings, email. Không dùng workshops.
Ai vào đượcMember đã đăng nhập và RSVP yes. Gác nằm trong guard() ở API.
Host quản trị ở đâuadmin.conan.school → Events → Live Workspace (/ops/events/live).
Màn hình người họctokyo, cùng gốc URL với event: /online-events/:slug/live.
Chấm task bằng AINgay khi learner nộp (lượt sau, Task chưa nằm trong V1).
RubricMỗi task một rubric riêng, host chuẩn bị trước (lượt sau).
Ngôn ngữTiếng Việt.
Hồ sơ participantMặc định chỉ host thấy; learner tự bật cho cả phòng.
Câu hỏiKhông ẩn danh, không duyệt trước. Host chỉ ẩn khi cần.
Phạm vi V1Trọn 7 khối. Lượt 1: Resources, Quiz/Poll, Live Stage, Questions. Lượt 2: Task + AI evaluation. Lượt 3: Reflection. Lượt 4 (09.09.2026): Participants + Session Record.

Vì sao polling chứ không Durable Object ​

PollingDurable Object
Cách hoạt độngTrình duyệt hỏi lại api mỗi 3 giây: "có gì mới không?"Một kết nối WebSocket mở suốt; server đẩy thay đổi xuống ngay
Độ trễ learner cảm nhận0–3 giây~tức thì
Hạ tầng thêmKhông, dùng đúng api hiện cóMột worker + binding DO mới, như play.conan.school
Chi phíMỗi người ~20 request/phút vào D1Một kết nối/người

Với một workshop Zoom vài chục người, 3 giây trễ không ai nhận ra, người nói vẫn đang nói. Đổi sang DO sau này không phải viết lại giao diện: cùng hình dạng dữ liệu, chỉ thay nguồn đẩy.

16. Đã dựng những gì ​

LớpChỗ
Lược đồapi.conan.school/migrations/20260916d_live_learning_workspace.sql, 6 bảng live_*
API người họcapi.conan.school/src/domains/events/live.ts → /api/events/:slug/live/*
API hostapi.conan.school/src/domains/admin/live_workspace.ts → /api/admin/live-workspace/:eventId/*
Màn hình người họccom.conan.school/app/routes/online-events.$slug.live.tsx
Bàn điều khiển hostadmin.conan.school/legacy/admin-marcom/src/pages/LiveWorkspacePage.tsx (/ops/events/live)
Task + rubricapi.conan.school/migrations/20260916e_live_workspace_tasks.sql
Chấm bằng AIapi.conan.school/src/domains/events/task-evaluation.ts
Reflectionapi.conan.school/migrations/20260916f_live_workspace_reflection.sql · src/domains/events/reflection-frameworks.ts
Participantsapi.conan.school/migrations/20260916g_live_workspace_participants.sql

Ba ranh giới vẽ ở API, không ở giao diện, đây là phần dễ làm sai nhất:

  1. Activity còn draft không có mặt trong phản hồi của learner.
  2. Đáp án đúng (is_correct) và explanation chỉ rời server khi activity đã đóng và host bật reveal_answer. Trước đó chúng là null, không phải bị ẩn bằng CSS.
  3. Hạn đóng vote kiểm ở endpoint vote. Nút mờ đi ở giao diện không phải là khoá.

16b. Task và AI evaluation (lượt 2) ​

Task là kind thứ ba của live_activities. Ba luật:

  1. Không có rubric thì không tạo được task (422 ở API). Rubric là điều kiện, không phải tuỳ chọn: thiếu nó, model chỉ còn cách khen chung chung, đúng thứ mô hình chấm này sinh ra để tránh. Tối đa 6 tiêu chí, mỗi tiêu chí một thang điểm riêng do host đặt.
  2. Rubric hiện cho người học TRƯỚC khi làm bài. Bị chấm theo tiêu chí mình không được biết là một cách chấm tồi.
  3. Chấm ngay trong request nộp bài, nhưng bài luôn được ghi vào D1 TRƯỚC khi gọi model. Model hỏng thì mất bản chấm, không mất bài.

Điểm do model trả về được neo lại vào rubric thật trước khi lưu: khớp theo nhãn tiêu chí, cắt về [0, max_score], làm tròn. Model trả nhãn lệch hay điểm 8/5 là chuyện xảy ra thường xuyên, và điểm hiển thị cho người học phải nằm trên thang mà host đã đặt.

live_task_evaluations.status có ba giá trị vì failed không được lẫn với "điểm thấp": learner thấy "Chưa chấm được bài này, bài của bạn đã được lưu", host thấy số bài chưa chấm được và có nút Chấm lại (POST /api/admin/live-workspace/:eventId/responses/:id/evaluate). Không có nút đó thì một lượt model hỏng là bài đó vĩnh viễn không có đánh giá, và không ai biết vì sao.

Model: @cf/meta/llama-3.1-8b-instruct-fast qua binding AI, response_format: json_schema, đi qua AI Gateway với metadata.engine = 'live-task-evaluation', cùng khuôn với learner-model-ai.

Sửa rubric của task đã có người nộp bị chặn 409, cùng lý do với sửa phương án của quiz đã có người trả lời.

16c. Reflection (lượt 3) ​

Reflection không phải một loại quiz, nó là trải nghiệm phản tư có khung. V1 có hai khung: 4F (Facts / Feelings / Findings / Future) và Start / Continue / Stop.

Điều quan trọng nhất về kiến trúc: khung là dữ liệu, không phải mã. Host chọn một khung, server đổ các ô của khung đó thành các dòng live_reflection_prompts gắn với activity. Từ giây phút đó, khung của activity này sống trong D1, sửa nhãn hay gợi ý được, và thêm What / So What / Now What, Gibbs, Plus / Delta chỉ là thêm một mục vào REFLECTION_FRAMEWORKS, không đổi lược đồ.

Mỗi ô lưu một dòng live_reflection_answers chứ không phải một khối văn bản. Lý do: câu hỏi "cả phòng học được gì" là câu hỏi về ô Findings, không phải về cả bài, gộp làm một khối là tự đóng cửa với việc tổng hợp sau này.

Phải điền đủ mọi ô mới nộp được (mỗi ô ≥ 5 ký tự): một khung phản tư điền dở dang thì không còn là khung nữa. Kiểm ở API.

Bài phản tư không ai đọc được ngoài chính người viết và host, snapshot của learner chỉ trả về ô của chính họ. Trừ một trường hợp: host chiếu một bài lên Live Stage, và khi đó cả phòng thấy đủ các ô.

16d. Participants và Session Record (lượt 4) ​

Participants: không thêm cột hồ sơ nào ​

users đã có đủ năm trường: full_name, location, birth_year, job_title, industry. Dựng một bảng hồ sơ riêng cho workspace là tạo ra một nguồn sự thật thứ hai cho cùng một con người. Thứ duy nhất thiếu là mức hiển thị, và nó thuộc về từng sự kiện chứ không phải về tài khoản: người ta có thể muốn lộ diện ở workshop nội bộ mà kín ở workshop mở. Nên bảng mới chỉ có đúng ba cột nghĩa: event_id, user_id, profile_visibility.

Hai lớp hiển thị, vẽ ở API:

Learner thấyHost thấy
Họ tên✓✓
Nơi ở · Ngànhchỉ với người đã tự bật✓
Năm sinh · Nghề nghiệpkhông bao giờ✓

Mặc định là host_only. Hai trường năm sinh và nghề nghiệp không có mặt trong câu truy vấn của endpoint learner, không phải bị lọc ở tầng hiển thị. Đó là khác biệt giữa "learner không thấy" và "learner không nhận được".

Session Record ​

GET /api/events/:slug/live/me trả về dấu vết của chính người gọi: tài liệu, mọi hoạt động đã tham gia (lựa chọn quiz/poll đã đổi từ id sang nhãn, bài task + bản chấm, các ô phản tư) và câu hỏi đã đặt.

Nó không phụ thuộc trạng thái Stage hay việc phòng còn mở, đây đúng là thứ biến 90 phút Zoom thành một artefact quay lại được. Cửa vào vẫn là RSVP yes, nên record vẫn đọc được sau khi buổi học kết thúc.

Luật đúng/sai giữ nguyên như snapshot: is_correct chỉ có giá trị khi activity đã đóng và host bật reveal_answer. Nếu không, Session Record sẽ là cửa hậu để biết đáp án của một câu đang mở.

17. Ràng buộc kỹ thuật còn hiệu lực ​

  • Lược đồ nằm trong migrations/, CI áp trước bước deploy. Không CREATE TABLE IF NOT EXISTS lúc chạy.
  • Giao diện: shadcn/ui + motion + token của packages/design-system/theme.css. Trang online-events.$slug.tsx cũ hard-code #6f3f75, nó nằm trong tồn đọng của check:colors; màn hình mới viết bằng token, không chép theo trang đó.
  • Sửa phương án của một activity đã có người trả lời bị chặn (409): kết quả sẽ không còn nói về cùng một câu hỏi. Host phải tạo hoạt động mới.

Tài liệu nội bộ nền tảng Conan School.