- Given Cài đặt → Khoá học hoặc Lớp học → Khoá học
- When Tạo một khoá học gồm tên, trình độ, nhóm tuổi, số buổi học, thời lượng buổi học, sĩ số mặc định, giá và cách tính giá
- Then Khoá học được lưu qua endpoint hiện có kèm các trường mở rộng, và xuất hiện trong biểu mẫu tạo lớp.
PRD 03 · Lớp học và lịch học
Khoá học, lớp học, phòng học, lịch học lặp lại để sinh ra các buổi học thực tế, các chế độ xem thời khoá biểu, sĩ số, ghi danh, phân công giáo viên và dạy thay, và các buổi học bù. Mở rộng các đối tượng Class, ClassSchedule và Course đã có sẵn, bổ sung phòng học và các buổi học đã được cụ thể hoá.
Xuất xứ / Prompt / Giới hạn
Tài liệu do trợ lý AI soạn trong một phiên làm việc ngày 10/09/2026, theo yêu cầu gốc được trích nguyên văn ở trang mục lục; mục Thiết kế đề xuất được bổ sung ngày 16/09/2026. Đây là bản đề xuất để đội thảo luận, chưa phải quyết định của đội sản phẩm.
Nguồn
- Nghiên cứu công khai về đối thủ cạnh tranh (PSE ONE, pse4.one), mã nguồn
center-crm-frontendvà đặc tả OpenAPI/v3trên staging (182 endpoint), tính đến ngày 10/09/2026. - Nhãn existing / extend / new trong trang được xác định bằng cách đối chiếu với đặc tả
/v3trên staging tại thời điểm trên.
Giới hạn
- Cần xác minh khi khảo sát trực tiếp trong ứng dụng, vì đăng nhập tự động vào sản phẩm tham chiếu chưa được cấp phép trong phiên soạn:
- Các thông tin đầu vào của "lịch học tự động" ở đối thủ: buổi học có được sinh thành các dòng dữ liệu không và ngày nghỉ lễ được xử lý thế nào.
- Có tồn tại khái niệm phòng học không và trùng lịch có được kiểm tra không.
- "Phân lớp giáo viên" và "xếp lịch giáo viên theo tuần" trông như thế nào (dạng lưới hay dạng danh sách).
- Cách họ xử lý học bù ("học bù") và liệu nó có trừ vào gói buổi không.
- Sĩ số lớp và cách xử lý danh sách chờ.
Thiết kế đề xuất
Mô-đun xoay quanh ba màn hình: danh sách lớp, chi tiết lớp với các buổi học đã được sinh ra thành từng dòng dữ liệu, và thời khoá biểu theo phòng; điều quan trọng nhất người đọc nên thấy là mọi trùng lịch phòng hoặc giáo viên được phát hiện và hiển thị ngay tại chỗ trước khi lưu.









1Mục đích
Một trung tâm sống bằng thời khoá biểu của mình. Lớp học cần được tạo nhanh từ một mẫu khoá học, được xếp vào phòng học không trùng lịch, được dạy bởi một giáo viên được phân công kèm cơ chế dạy thay, và tạo ra một danh sách các buổi học cụ thể để điểm danh, gói học phí và lương giáo viên có thể dựa vào. Backend của FLYER đã có lớp học (tên, mã, loại), một mẫu lặp lại (ClassSchedule với days_of_week, time_local, ngày bắt đầu và ngày kết thúc) dùng để tự động gán bài học FLYER, và một danh mục khoá học kèm giá. PRD này bổ sung những gì một trung tâm vật lý cần: phòng học, các buổi học dưới dạng dòng dữ liệu, sĩ số, ghi danh kèm ngày, học bù và các chế độ xem thời khoá biểu.
Trong phạm vi
- Danh mục khoá học (trình độ, số buổi, thời lượng, liên kết giá tới PRD 05).
- Tạo lớp học kèm mẫu lịch học, phòng học, giáo viên, sĩ số, chỗ học thử.
- Sinh buổi học, chỉnh sửa từng buổi học riêng lẻ, huỷ buổi học, ngày nghỉ lễ.
- Xem thời khoá biểu theo chi nhánh, phòng học, giáo viên, lớp học; phát hiện trùng lịch.
- Ghi danh (học viên vào lớp kèm ngày), danh sách lớp, danh sách chờ, chuyển lớp.
- Buổi học bù và các buổi học phát sinh riêng lẻ.
Ngoài phạm vi
- Tự động tối ưu hoá thời khoá biểu.
- Liên kết lớp học trực tuyến và họp video (tính năng "Dạy trực tuyến" đã có sẵn của FLYER có thể liên kết sau).
- Nội dung chương trình học; việc gán chương trình FLYER vẫn giữ trong ClassSchedule như hiện tại.
2Hiện trạng
| Đối tượng | Trường | Thiếu |
|---|---|---|
Class / SchoolClass (GET /v3/teacher/classes) | id int64, name, code, class_type, student_count, courses[{id, name, price}], created_at | chưa có trình độ, phòng học, sĩ số, ngày, giáo viên, trạng thái |
ClassSchedule (POST/GET/PUT/DELETE /v3/teacher/class-schedules) | class_id, days_of_week[], time_local, timezone, start_date, end_date, is_active, program_type STUDY|BOOK, program ids, delivery_time, deadline_days, lessons[] (rollup with remind status) | mỗi lớp chỉ có một lịch học đang hoạt động; chưa có thời lượng, phòng học, giáo viên; lessons là các đơn vị nội dung, không phải buổi học thực tế |
Course (/v3/teacher/school-finance/course/courses) | name, description, level, number_of_lessons, price, currency, pricing_method ONE_TIME|MONTHLY, split_payment_count, status | chưa có thời lượng buổi học, chưa có nhóm tuổi, chưa có sĩ số mặc định |
POST .../classes/{class_id}/courses | attach course to class | giữ nguyên |
POST /v3/teacher/class-schedules/{id}/remind, preview-remind-time | FLYER lesson reminders | giữ nguyên |
Exam sessions (SessionInput with check_point_id) | exam-only | không dùng lại cho buổi học của lớp |
3Đối tượng sử dụng và vai trò
| Đối tượng | Nhu cầu |
|---|---|
| Giáo vụ | Tạo lớp học, sinh và điều chỉnh buổi học, lấp đầy sĩ số lớp, xử lý chuyển lớp và học bù, in thời khoá biểu. |
| Quản lý chi nhánh | Xem tỷ lệ lấp đầy và tải công việc của giáo viên, phê duyệt việc mở và đóng lớp. |
| Giáo viên | Thời khoá biểu tuần của mình, danh sách lớp kèm ghi chú, yêu cầu dạy thay. |
| Tư vấn tuyển sinh | Tìm lớp còn chỗ theo trình độ và thời gian để phục vụ học thử và chuyển đổi. |
| Phụ huynh | Xem thời khoá biểu của con và các thay đổi (PRD 07). |
4User story và tiêu chí chấp nhận
- Given Một khoá học
- When Nhập tên lớp (tự gợi ý "Movers 2 · T3/T5 18:00"), chi nhánh, khoá học, trình độ, giáo viên, trợ giảng (nếu có), phòng học, sĩ số, chỗ học thử, ngày bắt đầu, ngày kết thúc hoặc số buổi học, mẫu ngày trong tuần kèm giờ học theo từng ngày, và các ngày nghỉ lễ cần bỏ qua
- Then Lớp học được tạo (endpoint hiện có) kèm bản ghi mở rộng, một ClassSchedule được tạo cho các bài học FLYER nếu có chọn chương trình, và N buổi học được sinh ra dưới dạng các dòng dữ liệu gồm ngày, giờ bắt đầu, giờ kết thúc, phòng học, giáo viên; biểu mẫu hiển thị các trùng lịch trước khi lưu.
- Given Một buổi học đang được tạo hoặc di chuyển
- When Có một buổi học khác trùng thời gian trong cùng phòng học, hoặc cùng giáo viên, trong cùng chi nhánh (trùng lịch giáo viên được kiểm tra trên cả các chi nhánh)
- Then API trả về 409
CONFLICTkèm các buổi học bị trùng, và giao diện hiển thị chúng ngay tại chỗ với tuỳ chọn ghi đè "Vẫn lưu" cho quyềnclasses.override_conflict.
- Given Một buổi học đã được sinh ra
- When Thay đổi ngày, giờ, phòng học hoặc giáo viên của buổi học đó
- Then Chỉ buổi học đó thay đổi và được đánh dấu "Đã điều chỉnh"; chọn "Áp dụng cho các buổi sau" sẽ sinh lại các buổi học kế hoạch trong tương lai (các buổi đã học không bị ảnh hưởng); phụ huynh của học viên đã ghi danh nhận được thông báo thay đổi (PRD 07) nếu tính năng này được bật.
- Given Một buổi học đang ở trạng thái kế hoạch
- When Huỷ buổi học kèm lý do và chọn "Thêm buổi bù cuối khoá" hoặc "Không bù"
- Then Trạng thái chuyển thành
cancelled(hoặccancelled_latekhi huỷ trong vòng 24 giờ, liên quan đến lương ở PRD 06); một buổi học bù được thêm vào sau buổi học cuối cùng nếu được chọn; không buổi học nào bị trừ khỏi gói buổi của học viên; phụ huynh được thông báo.
- Given Một buổi học
- When Đặt giáo viên dạy thay
- Then Buổi học hiển thị cả giáo viên chính và giáo viên dạy thay; giáo viên dạy thay thấy buổi học này trong thời khoá biểu của mình và có thể điểm danh; PRD 06 tính lương cho giáo viên dạy thay.
- Given Một lớp học có sĩ số 12 và 11 lượt ghi danh đang hoạt động
- When Thêm một học viên kèm ngày bắt đầu
- Then Lượt ghi danh được tạo; khi đạt 12, lớp hiển thị "Đầy" và các lượt thêm tiếp theo được đưa vào danh sách chờ; chuyển sang lớp khác sẽ kết thúc lượt ghi danh vào ngày D và bắt đầu một lượt ghi danh mới vào ngày D (cho phép cùng ngày); kết thúc một lượt ghi danh trước khi lớp kết thúc sẽ yêu cầu nhập lý do (chu trình trạng thái ở PRD 02).
- Given Một lượt vắng có xin phép (PRD 04) và chính sách tenant "cho phép học bù"
- When Chọn một buổi học của lớp khác cùng trình độ còn chỗ trống, hoặc tạo một buổi học bù riêng lẻ
- Then Một
makeup_bookingđược tạo; học viên xuất hiện trong danh sách của buổi học đó kèm chip Học bù; việc tham dự không trừ vào gói buổi nếu chính sách tenant quy định như vậy.
- Given Trang thời khoá biểu
- When Chuyển đổi giữa Theo phòng học, Theo giáo viên, Theo lớp học, và một khoảng ngày
- Then Một lưới tuần (07:00 đến 22:00, mỗi dòng 30 phút) hiển thị các khối buổi học kèm tên lớp, giáo viên, phòng học và số đã ghi danh/sĩ số; nhấn vào để mở drawer chi tiết buổi học; in ra tạo một tờ A4 nằm ngang cho mỗi phòng học.
- Given Buổi học cuối cùng đã diễn ra hoặc nhân sự chọn Kết thúc lớp
- When Xác nhận
- Then Trạng thái lớp chuyển thành
completed, các lượt ghi danh kết thúc, học viên không còn lượt ghi danh nào khác chuyển thành Hoàn thành (PRD 02), và danh sách lớp chuyển lớp này sang mục Đã kết thúc.
5Màn hình
Các tab: Đang học · Sắp khai giảng · Đầy · Đã kết thúc · Tất cả. Bộ lọc: chi nhánh, khoá học, trình độ, giáo viên, ngày trong tuần, khung giờ (sáng/chiều/tối), còn chỗ. Các nút: + Tạo lớp, Thời khoá biểu.
| Cột | Ghi chú |
|---|---|
| Mã lớp | class.code |
| Tên lớp | liên kết; chip trình độ |
| Lịch | "T3, T5 · 18:00–19:30" |
| Phòng | tên phòng học |
| Giáo viên | ảnh đại diện + tên; trợ giảng hiển thị nhỏ |
| Sĩ số | "11/12" kèm thanh tiến trình; màu đỏ khi đầy; số lượng đang chờ |
| Tiến độ | số buổi đã học / tổng số buổi |
| Khai giảng · Kết thúc | ngày |
| Trạng thái | Sắp mở (exc) · Đang học (ok) · Đầy (late) · Đã kết thúc (grey) |
| Thao tác | Xem lịch · Thêm học viên · Điểm danh hôm nay |
Trạng thái trống: "Chưa có lớp. Tạo khoá học trước, rồi mở lớp từ khoá học."
Phần đầu trang theo khung lop-hoc của Cloud theme: tên lớp, tiêu đề phụ "T3 & T5, 18:00 · 12 học viên · Movers", các nút Sửa · Giao bài (FLYER) · kebab (Nhân bản lớp, Kết thúc lớp). Các tab: Tổng quan · Học viên · Buổi học · Điểm danh · Bài tập (bài kiểm tra FLYER hiện có) · Học phí · Cài đặt. Cột bên phải: Thông tin lớp (mã lớp kèm nút sao chép, giáo viên, phòng học, sĩ số, khoá học, chương trình), tỷ lệ lấp đầy, buổi học kế tiếp.
- Học viên: bảng danh sách lớp (họ tên, số điện thoại phụ huynh, ngày bắt đầu, trạng thái, số buổi đã học/tổng số buổi, số dư, cờ đánh dấu) kèm các thao tác Chuyển lớp, Kết thúc, Gửi tin; phần danh sách chờ; + Thêm học viên (tìm học viên trong chi nhánh, hiển thị mức độ phù hợp trình độ).
- Buổi học: bảng các buổi học (số thứ tự, ngày, giờ, phòng học, giáo viên, giáo viên dạy thay, trạng thái, đã điểm danh, ghi chú) kèm sửa, huỷ, dạy thay theo từng dòng; thanh công cụ Tạo buổi, Tạo lại lịch, Nghỉ lễ.
- Cài đặt: sĩ số, chỗ học thử, cho phép học bù, chương trình FLYER (các trường ClassSchedule hiện có).
| Trường | Kiểu dữ liệu | Ràng buộc |
|---|---|---|
| Chi nhánh | select | bắt buộc |
| Khoá học | select | bắt buộc; tự điền trình độ, thời lượng, sĩ số, số buổi |
| Tên lớp | text | bắt buộc; không trùng trong cùng chi nhánh, tính trên các lớp đang mở |
| Mã lớp | text | tự sinh <LEVEL>-<YYMM>-##, có thể chỉnh sửa |
| Giáo viên chính, Trợ giảng | bộ chọn nhân sự (đang dạy, theo chi nhánh) | giáo viên chính bắt buộc trước buổi học đầu tiên |
| Phòng | chọn phòng học trong chi nhánh | bắt buộc |
| Sĩ số tối đa, Chỗ học thử | int | 1–60; chỗ học thử ≤ 5 |
| Lịch học | chip ngày trong tuần; giờ bắt đầu/kết thúc theo từng ngày; thời lượng mặc định lấy từ khoá học | ≥ 1 ngày trong tuần; giờ bắt đầu < giờ kết thúc |
| Khai giảng | date | bắt buộc |
| Kết thúc | radio: theo số buổi (default course lessons) / theo ngày | |
| Ngày nghỉ | chọn nhiều ngày; nạp sẵn từ danh sách ngày nghỉ lễ của tenant | |
| Chương trình FLYER | bộ chọn chương trình hiện có (không bắt buộc) |
Bước 2 xem trước: danh sách các buổi học được sinh ra kèm chip cảnh báo trùng lịch; nút Tạo lớp và N buổi.
Lưới tuần, các cột là phòng học (hoặc giáo viên, hoặc lớp học), các dòng là 30 phút. Màu khối theo trình độ. Kéo để di chuyển (trên desktop) kèm kiểm tra trùng lịch khi thả. Bộ lọc: chi nhánh, trình độ. Các nút: In, Xuất iCal (chế độ xem của giáo viên). Chế độ xem theo ngày cho di động.
Bảng: tên, chi nhánh, sĩ số, thẻ trang thiết bị, đang hoạt động. Biểu mẫu: tên (không trùng trong cùng chi nhánh), sĩ số, ghi chú.
6Quy tắc nghiệp vụ
- Các buổi học được sinh ra từ mẫu lịch khi tạo lớp và mỗi khi mẫu lịch thay đổi, chỉ áp dụng cho các buổi học ở trạng thái
planned. Các buổi đã học hoặc đã huỷ không bao giờ được sinh lại. - Số thứ tự buổi học được đánh theo thứ tự ngày trong số các buổi chưa bị huỷ; được đánh lại khi sinh lại lịch.
- Trùng phòng học: cùng phòng, thời gian chồng lấn, cả hai buổi học chưa bị huỷ. Trùng giáo viên: cùng một nhân sự là giáo viên chính hoặc dạy thay, thời gian chồng lấn, ở bất kỳ chi nhánh nào. Khoảng đệm giữa các buổi học mặc định là 0 (cài đặt theo tenant, tối đa 30 phút).
- Sĩ số được tính bằng số lượt ghi danh đang hoạt động vào ngày của buổi học cộng với các lượt đặt học thử và học bù cho buổi học đó; chỗ học thử được giữ riêng.
- Một lượt ghi danh có ngày bắt đầu và ngày kết thúc; học viên có mặt trong danh sách của các buổi học nằm trong khoảng [ngày bắt đầu, ngày kết thúc].
- Trạng thái lớp học:
draft(chưa có buổi học),scheduled(ngày bắt đầu ở tương lai),active,completed,cancelled; được suy ra từ ngày và buổi học, trừ trạng thái cancelled. - Ngưỡng huỷ muộn 24 giờ (cài đặt theo tenant) đánh dấu
cancelled_lateđể áp dụng quy tắc tính lương. - Ánh xạ trình độ để gợi ý xếp lớp: bảng level_code → khoảng điểm theo từng tenant; giá trị mặc định lấy từ CEFR (Pre-A1, A1, A2, B1, B2, C1) và Cambridge YLE (Starters, Movers, Flyers, KET, PET).
7Mô hình dữ liệu
| Thực thể | Trường | Ghi chú |
|---|---|---|
| course (Course hiện có) | + session_duration_min int; age_from; age_to; default_capacity; level_code; is_template | mở rộng |
| level (catalog) | id; tenant_id; code; name; framework enum(cefr, cambridge_yle, ielts, custom); score_from; score_to; position | mới |
| room | id uuid; school_id; name; capacity; equipment text[]; is_active | mới; duy nhất theo (school_id, name) |
| class_profile (mở rộng từ Class) | class_id int64 PK; school_id; course_id; level_code; main_staff_id; assistant_staff_id; room_id; capacity; trial_seats; start_date; end_date; planned_sessions; status enum; allow_makeup bool; pattern jsonb [{weekday, start, end}]; holidays date[] | mới |
| class_session | id uuid; class_id; school_id; seq int; date; start_at; end_at (timestamptz); room_id; main_staff_id; substitute_staff_id null; status enum(planned, held, cancelled, cancelled_late); cancel_reason; is_makeup bool; is_adjusted bool; note; attendance_marked_at; created_at; updated_at | mới; index (school_id, date), (room_id, start_at), (main_staff_id, start_at) |
| enrollment | id uuid; student_id; class_id; start_date; end_date null; status enum(active, ended, waiting); end_reason; fee_plan_id null; created_by; created_at | mới; mỗi (student, class) chỉ có một lượt ghi danh đang hoạt động |
| makeup_booking | id; student_id; source_session_id (absence); target_session_id; consumes_package bool; status enum(booked, attended, no_show, cancelled) | mới |
| holiday | id; tenant_id; date; name | mới |
8Hợp đồng API
| Method | Path | Request / response | Status |
|---|---|---|---|
| GET/POST/PUT/DELETE | /v3/teacher/school-finance/course/courses[/{id}] | như hiện tại + các trường mở rộng | extend |
| GET | /v3/teacher/classes | như hiện tại; response bổ sung tổng hợp profile | extend |
| POST | /v3/school/classes | {school_id, course_id, name, code?, level_code, main_staff_id?, assistant_staff_id?, room_id, capacity, trial_seats, start_date, end_by: {sessions: n} | {date}, pattern[], holidays[], program?: CreateClassScheduleRequest fields} → {class, sessions[], conflicts[]}; dry_run=true chỉ trả về bản xem trước | new (tạo Class + ClassSchedule ở nội bộ) |
| GET/PATCH | /v3/school/classes/{id} | chi tiết kèm profile, số lượng trong danh sách lớp, buổi học kế tiếp | new |
| POST | /v3/school/classes/{id}/regenerate | {pattern, holidays, from_date} chỉ áp dụng cho các buổi học ở trạng thái planned | new |
| POST | /v3/school/classes/{id}/close | /cancel | {reason} | new |
| GET | /v3/school/sessions | school_id, from, to, class_id, room_id, staff_id, status → Session[] with class, room, teacher, counts | new |
| POST | /v3/school/classes/{id}/sessions | {date, start, end, room_id, staff_id, is_makeup} phát sinh riêng lẻ | new |
| PATCH | /v3/school/sessions/{id} | {date?, start?, end?, room_id?, main_staff_id?, substitute_staff_id?, note?, apply_to_following?: bool, override_conflict?: bool} → 409 CONFLICT {conflicts[]} | new |
| POST | /v3/school/sessions/{id}/cancel | {reason, add_makeup: bool, notify: bool} | new |
| GET/POST | /v3/school/classes/{id}/enrollments | {student_id, start_date, fee_plan_id?} → 409 CLASS_FULL (đề xuất đưa vào danh sách chờ) | new |
| PATCH | /v3/school/enrollments/{id} | {end_date, end_reason} hoặc {transfer_to_class_id, effective_date} | new |
| GET | /v3/school/sessions/{id}/roster | học viên đã ghi danh + học thử + học bù kèm cờ đánh dấu và số dư | new |
| POST | /v3/school/makeups | {student_id, source_session_id, target_session_id | new_session: {...}, consumes_package} | new |
| GET/POST/PATCH | /v3/school/rooms | new | |
| GET/POST/DELETE | /v3/school/holidays | new | |
| GET/POST/PATCH | /v3/school/levels | danh mục trình độ kèm khoảng điểm | new |
| GET | /v3/school/timetable | school_id, week, view=room|teacher|class → các buổi học được nhóm lại | new |
| GET | /v3/school/staff/{id}/timetable.ics | đường liên kết có chữ ký | new |
| POST/GET/PUT | /v3/teacher/class-schedules[...] | Các bài học chương trình FLYER; không thay đổi | existing |
9Phân quyền
| Mã quyền | owner | branch_manager | academic_admin | admissions | teacher |
|---|---|---|---|---|---|
classes.view | Tất cả | Chi nhánh | Chi nhánh | Xem trong chi nhánh | Của mình |
classes.manage (tạo, sửa, kết thúc) | Có | Có | Có | Không | Không |
sessions.manage (sửa, huỷ, dạy thay) | Có | Có | Có | Không | Chỉ yêu cầu |
classes.override_conflict | Có | Có | Không | Không | Không |
enrollments.manage | Có | Có | Có | Qua chuyển đổi | Không |
makeups.manage | Có | Có | Có | Không | Không |
rooms.manage, courses.manage, levels.manage | Có | Phòng học | Khoá học, phòng học | Không | Không |
timetable.view | Tất cả | Chi nhánh | Chi nhánh | Chi nhánh | Của mình |
10Sự kiện phân tích
| Sự kiện | Thuộc tính |
|---|---|
| class_created | level, weekdays, sessions, capacity, with_program |
| session_conflict_shown / session_conflict_overridden | type (room|teacher) |
| session_edited / session_cancelled | late (bool), makeup_added, notified |
| substitute_assigned | hours_before |
| enrollment_created / ended / transferred | reason, fill_rate_after |
| makeup_booked | consumes_package |
| timetable_viewed | view, printed |
| class_closed | sessions_held, sessions_cancelled |
11Trường hợp biên
- Mẫu lịch có hai buổi học trong cùng một ngày trong tuần (lớp tăng cường sáng và tối): được cho phép; pattern là một danh sách, không phải một map.
- Lớp học kéo dài qua kỳ nghỉ Tết: các ngày nghỉ lễ được bỏ qua và ngày kết thúc được kéo dài thêm; bản xem trước hiển thị ngày kết thúc mới.
- Giáo viên bị gỡ khỏi chi nhánh trong khi vẫn được phân công cho các buổi học trong tương lai: PRD 06 liệt kê các buổi học bị ảnh hưởng để phân công lại; các buổi học giữ nguyên staff id cho đến khi được thay đổi.
- Phòng học bị vô hiệu hoá khi vẫn còn buổi học trong tương lai: chặn việc vô hiệu hoá cho đến khi các buổi học được chuyển sang phòng khác.
- Học viên ghi danh giữa khoá học: các buổi học trước ngày bắt đầu không nằm trong danh sách của học viên và không bị tính là vắng.
- Múi giờ: tất cả buổi học theo múi giờ của tenant; giờ mùa hè (DST) không áp dụng tại Việt Nam nhưng vẫn được lưu dưới dạng timestamptz.
- Hai nhân sự cùng chỉnh sửa một buổi học: xử lý tương tranh lạc quan (optimistic concurrency) dựa trên
updated_at; lần lưu thứ hai nhận 409 STALE.
12Câu hỏi còn mở
- Có nên cho phép một lớp học không có phòng học (trực tuyến hoặc ngoài trung tâm) không? Đề xuất: có, với phòng "Trực tuyến" là một phòng học ảo cho từng chi nhánh.
- Danh sách chờ theo từng lớp đã đủ, hay các trung tâm giữ danh sách chờ theo trình độ và khung giờ?
- Có cần thời lượng khác nhau cho từng buổi học không (ngày thi dài hơn)? Đề xuất: chỉnh sửa theo từng buổi học đã đáp ứng được nhu cầu này.
Trường Số (truongso.net) · Nội bộ FLYER