Tài liệu nội bộ · Đã chốt với client (Option A) · Dùng cho FE / BE / QA handoff

Internal · Knowledge transfer · v2 chi tiết

Deploy & Fork — Sync to LMS

Tổng hợp đầy đủ 2 flow: Save → Deploy (sync roster)Set Up for New Trimester (Fork), kèm timeline LMS, thuật toán lookup, nhánh Perpetual, rule duplicate/lineage, ví dụ end-to-end và checklist QA.

Client confirmed Module code = LMS type 101 Roster = Offering type 3 Cập nhật: 2026-07-21

TL;DR — 8 ý bắt buộc nhớ

1. Thuật ngữ & hierarchy LMS

Định nghĩa

LMS Module (type 101)
Org unit “Module” trên Brightspace (custom type của SIT). Là định nghĩa môn. Một Module có nhiều Offering theo kỳ. Không chứa roster học viên.
Course Offering / Coursesite (type 3)
Instance chạy thực tế dưới Module (thường gắn Semester). Đây là nơi có Students / enrollment để CB sync.
Semester (type 5)
Kỳ học trên LMS. Có thể là mã run 4 số (vd gắn trimester) hoặc Semester_Ongoing (perpetual).
Module code (CB UI)
Field user nhập khi Sync LMS. Map vào code của LMS Module 101. Giữ nguyên khi fork.
MC (Micro-credential)
Catalog do Admin tạo (code + title trống). Editor gắn module vào MC. MC code dùng Priority 2; cũng = Module 101 trên LMS.
Trimester / AY (CB)
Catalog do Admin tạo trong CB (không sync từ LMS). Dùng cho ngày start/end, deploy window, dashboard grouping, và key search Offering.
Perpetual
Sync LMS + trimester trống. Hợp lệ. Không fork. Offering chọn theo semester ≠ 4-digit.
Version lineage
Chuỗi gốc → các bản fork. Cùng lineage = cùng “dòng đời” module (cùng Module code qua các kỳ).
Undeployed fork
Bản fork đã tạo nhưng chưa Deploy thành công. Mỗi lineage chỉ 1 bản như vậy tại một thời điểm.

Hierarchy LMS (đã verify staging)

Organization (1) SIT └─ Semester (5) Ongoing · Code: Semester_Ongoing ← perpetual └─ School (103) … └─ Module (101) Code: INF1001 ← CB Module code └─ Course Template (2) … └─ Course Offering (3) semester 2610 ← roster A └─ Course Offering (3) semester 2620 ← roster B └─ Course Offering (3) under Ongoing ← roster perpetual
Lỗi hiểu phổ biến — tránh Đừng map CB “Module code” = Offering code (type 3). Offering code thường khác Module code, và mỗi Offering chỉ gắn 1 semester — không thể giữ nguyên code khi fork sang kỳ mới.

2. Mô hình Option A (đã chốt)

Client chọn: Module code = LMS Module 101, khóa trên mọi fork; mỗi fork Deploy tìm coursesite mới qua Module code + trimester; roster theo Offering / CB version.

CB v1code INF1001
T = AY 26/27 T1
LMS 101INF1001
Offering2610 → roster A
Fork (Set Up for New Trimester) — cùng Module code
CB v2code INF1001
T = AY 26/27 T2
cùng LMS 101INF1001
Offering mới2620 → roster B

v1 và v2 độc lập về roster. Student enrolled v1 không tự thấy v2.

CB sở hữu

  • Nội dung / version module
  • Catalog trimester + ngày
  • Binding: version ↔ Offering (sau Deploy)
  • Quyền truy cập theo roster đã sync

LMS sở hữu

  • Module 101 (tạo sớm)
  • Offering 3 (thường ~2 tuần trước kỳ)
  • Enrollment thật trên Offering
  • Semester / Ongoing

3. Timeline thực tế (LMS vs CB)

Đây là lý do bắt buộc tách SaveDeploy.

Thời gian ──────────────────────────────────────────────► [Sớm — trước kỳ lâu] LMS: Module 101 đã có (IT/admin) CB: Instructor Save Sync LMS ✓ verify 101 ✗ chưa cần Offering ✗ chưa sync roster [~2 tuần trước start trimester] LMS: Course Offering (3) được tạo + gắn semester 4-digit CB: Cửa sổ Deploy mở (rule 2 weeks) Deploy: tìm Offering + sync roster ✗ không thấy Offering → block + error [Trong kỳ] CB module deployed; roster tiếp tục sync theo cơ chế sync hiện có Instructor có thể Fork chuẩn bị kỳ sau (tạo undeployed fork)
Perpetual Không có “start trimester” → không áp cửa sổ 2 tuần theo cùng cách. Deploy vẫn cần tìm được ≥1 Offering non-4-digit dưới Module 101.

4. Field Deployment + Admin trimester

4.1 Form Module Details → Deployment (Sync LMS)

Field Bắt buộc UI control Lưu / dùng khi nào
Enrolment type Select Doc này = Sync to LMS
Module code Text input Save: verify 101. Deploy: P1 key.
Micro-credential Không Select từ list Admin Save: fallback verify 101. Deploy: P2.
Trimester Không Dropdown label thân thiện Có giá trị = theo kỳ. Trống = Perpetual. Deploy dùng mã 4 số.

4.2 Admin tạo trimester

4.3 Editable sau Deploy (nhắc lại product)

Enrolment typeSau khi Deploy
Sync to LMS Không cho sửa enrolment / LMS mapping (locked).
SIT / Public Vẫn cho đổi settings (ngoài scope chi tiết doc này).

5. Flow Save — chi tiết từng bước

Mục tiêu Save

Lưu cấu hình enrolment + xác nhận Module identity trên LMS. Không bind Offering. Không sync student list.

  1. User điền form & bấm Save Enrolment = Sync LMS; Module code bắt buộc; MC optional; Trimester optional (dropdown).
  2. Validate CB — duplicate code Tìm module khác trong CB có cùng Module code / MC code.
    • Cùng version lineage (gốc + các fork) → không coi là duplicate.
    • Khác lineage → lỗi: “A module with this Module Code already exists.”
  3. Verify LMS Module (101) Search LMS orgstructure / API cho Module type 101 có code = Module code (ưu tiên) hoặc MC code nếu dùng fallback verify.
    • Không tìm thấy → lỗi: “Module Code not found. Please verify the code in the LMS and try again.”
    • Tìm thấy → cho phép Save (có thể trả về title LMS để hiển thị / rename theo feedback UI cũ).
  4. Persist trên CB Lưu enrolment type, moduleCode, mcId/code, trimesterId (nullable), trạng thái “saved / ready to deploy”. Chưa có binding Offering id.
Implication implement Save path phải gọi lookup Module (101), không gọi findCourseOfferingByCode(moduleCode) như model cũ (Offering-as-code).

Decision tree Save

Save Sync LMS ├─ duplicate code ngoài lineage? ──YES──► ERROR duplicate └─ NO ├─ LMS Module 101 (moduleCode)? ──YES──► SAVE OK └─ NO ├─ có MC code & LMS 101 (mcCode)? ──YES──► SAVE OK └─ NO ──► ERROR module not found (Không search Offering. Không check trimester trên LMS.)

6. Flow Deploy — lookup & roster

Mục tiêu Deploy

Resolve đúng Course Offering(s) trên LMS, bind vào CB version, sync enrollment theo role matrix. Nếu 0 Offering → block.

6.1 Điều kiện trước Deploy (có trimester)

6.2 Thuật toán lookup (có trimester)

  1. Chuẩn hóa trimester key Từ dropdown selection → lấy mã 4 số đã store (vd 2610).
  2. Priority 1 — Module code + trimester Tìm Module 101 theo Module code → liệt kê Offering con → giữ Offering có semester code = 2610 (hoặc tương đương mapping đã thống nhất).
  3. Priority 2 — MC code + trimester (fallback) Nếu P1 = 0 Offering: lặp lại với MC code (cũng là Module 101) + cùng trimester.
  4. Xử lý kết quả
    • 0 → block Deploy + error (Offering chưa có / sai code / sai kỳ).
    • 1 → bind Offering đó; sync roster.
    • N → merge roster tất cả Offering khớp; grant theo LMS–CB role mapping matrix.
Deploycó trimester
P1Module code
+ 4-digit
P2MC code
+ 4-digit
Roster1 hoặc merge N

Lookup uniqueness không guarantee → luôn implement nhánh N = merge.

6.3 Sau khi có Offering

Merge N Offerings Client xác nhận: gộp roster mọi Offering khớp. Edge còn mở: cùng user khác role trên 2 Offering → cần rule resolve (priority / union) khi code.

7. Nhánh Perpetual (trimester trống)

Định nghĩa

Dropdown trimester không chọn → CB coi module là Perpetual. Vẫn Sync LMS được. Không hiện / không cho Set Up for New Trimester.

7.1 Save

Giống module có trimester: chỉ cần Module 101 tồn tại.

7.2 Deploy — rule chọn Offering

  1. Tìm Module 101 Theo Module code (rồi MC nếu fallback).
  2. Lọc Offering Giữ Offering có semester code KHÔNG thuộc format 4-digit YY+T+0. Ví dụ ứng viên: Semester_Ongoing, empty, text khác không phải run code kỳ.
  3. 0 / 1 / N Giống Deploy thường: 0 block; 1 sync; N merge roster.

7.3 Ví dụ trực quan

LMS Module 101 · INF1001 ├── Offering A · semester 2610 → BỎ (là run code kỳ) ├── Offering B · semester 2620 → BỎ ├── Offering C · semester Ongoing → LẤY └── Offering D · semester Open → LẤY (cũng ≠ 4-digit) CB: Sync LMS · Module code INF1001 · Trimester = (trống) Deploy → merge roster C + D → grant vào CB perpetual module (User không được UI “chọn enrollment” — hệ thống tự lọc)

OK 1 non-term

Sync đúng 1 Offering Ongoing.

OK N non-term

Merge roster; không picker.

Fail 0 non-term

Block Deploy + error.

Khác biệt với “có trimester” Key không còn là Module + 2610 mà là Module + (semester ∉ 4-digit set). Instructor chỉ để trống dropdown — không nhập free-text semester LMS.

8. MC code & Priority 2

Cách MC hoạt động

  1. Admin tạo MC “rỗng”: MC code + title (chưa gắn module).
  2. Editor gắn module vào MC từ list.
  3. Deploy P1 fail → P2: search LMS Module 101 bằng MC code + trimester (hoặc rule perpetual).
Đổi so với note cũ Trước đây từng hiểu MC = exact-match Offering (3). Client reply mới: MC = Module (101), cùng kiểu Priority 1.

Hệ quả

9. Flow Fork — Set Up for New Trimester

9.1 Ai được fork?

Điều kiệnĐược fork?
Có trimester (không Perpetual)
Perpetual (trimester trống) Không
Enrolment = Sync LMS vs non-LMS Không liên quan — cả hai đều fork được nếu có trimester
Module thuộc / không thuộc MC Không liên quan — fork theo từng module

9.2 Gate: một undeployed fork / lineage

  1. User bấm Set Up for New Trimester
  2. Kiểm tra lineage Đã tồn tại fork cùng lineage ở trạng thái undeployed?
    • → block action; dẫn user tới fork hiện có (không tạo thêm).
    • Không → tiếp tục tạo.
  3. Tạo version mới Clone nội dung theo rule fork product; giữ Module code; gắn trimester mới (user chọn); enrolment/LMS settings kế thừa theo product; trạng thái undeployed cho đến khi Deploy thành công.
Fork không tạo Offering LMS CB chỉ chuẩn bị version nội dung. Offering kỳ mới do IT LMS tạo. Deploy version mới mới đi tìm Offering + sync roster kỳ mới.

9.3 Sau fork — Deploy version mới

Lineage INF1001 ├── v1 T=AY25/26 T1 (2610) DEPLOYED → Offering A · roster cũ └── v2 T=AY26/27 T1 (2610*) UNDEPLOYED (fork mới) Save: OK — cùng Module code, cùng lineage ≠ duplicate Deploy khi tới cửa sổ 2 tuần: P1 INF1001 + trimester mới → Offering B sync roster B vào v2 v1 vẫn giữ roster A

9.4 Những gì fork thay đổi / không đổi

Giữ nguyên

  • Module code (101)
  • Lineage identity
  • (Thường) Sync LMS flag / MC gắn — confirm khi impl nếu product có ngoại lệ

Đổi / tách

  • Trimester mới
  • CB version mới (nội dung clone)
  • Offering + roster riêng sau Deploy
  • Enrollment học viên không mang từ version cũ

Chi tiết “fork clone gì” (collaborator, history, staff copy) theo SRS/discussion cũ — gate undeployed + who-can-fork lấy từ client reply mới nhất.

10. Duplicate & lineage

Tình huống Cùng Module code? Save OK? Lý do
Hai module độc lập (khác lineage) Không Duplicate thật
v1 deployed + v2 fork cùng lineage Có (bắt buộc) Cùng lineage ≠ duplicate
v2 undeployed đã tồn tại, tạo fork nữa Fork blocked Max 1 undeployed / lineage
Module khác dùng lại code sau khi lineage cũ archived? Chưa chốt trong reply — cần Product nếu gặp case

11. Kịch bản end-to-end

S1 Happy path — có trimester

1. Admin tạo trimester “AY 26/27 T1” → BE store 2610 + start/end 2. LMS đã có Module 101 code INF1001 (Offering chưa có) 3. Editor Save: Module code INF1001, T=AY 26/27 T1 → verify 101 OK → saved 4. ~2 tuần trước start: IT tạo Offering semester 2610 dưới INF1001 5. Editor Deploy → P1 khớp 1 Offering → sync roster → deployed 6. Cuối kỳ: Set Up for New Trimester → v2 (undeployed), cùng INF1001, chọn T2 7. Tới cửa sổ T2: Deploy v2 → Offering 2620 → roster mới

S2 Happy path — Perpetual

1. Editor Save: INF1001, trimester trống → verify 101 OK 2. LMS có Offering dưới Ongoing (semester ≠ 4-digit) 3. Deploy → lọc non-4-digit → sync roster Ongoing 4. UI không hiện “Set Up for New Trimester”

S3 Save sớm nhưng Deploy sớm quá / Offering chưa có

1. Save OK (101 có) 2. Deploy trước khi IT tạo Offering HOẶC ngoài cửa sổ 2 tuần 3. → block Deploy (0 Offering hoặc window rule) 4. User đợi Offering / đúng cửa sổ rồi Deploy lại

S4 Module code sai trên LMS

Save → không tìm thấy 101 → “Module Code not found. Please verify the code in the LMS and try again.” → không lưu Sync LMS thành công

S5 Hai Offering cùng Module + trimester

Deploy P1 trả về Offering X và Y (cùng 2610) → merge roster X∪Y → mọi user (sau map role) được access CB module version đó → không hiện UI chọn X hay Y

S6 Fork khi đã có undeployed

v1 deployed, v2 undeployed đã tồn tại User bấm Set Up for New Trimester lần nữa → block + deep-link / chỉ đường tới v2 → phải Deploy (hoặc hủy theo rule product) trước khi fork tiếp

S7 Priority 2 — Module code không ra Offering, MC có

P1: Module code + 2610 → 0 Offering P2: MC code (101) + 2610 → 1 Offering → Deploy OK bằng P2 (Lưu ý: nhiều CB module cùng MC có thể share roster Offering đó)

12. Gợi ý UI / state

Trước Deploy (Sync LMS)

  • Form Module code / MC / Trimester editable
  • Save riêng với Deploy
  • Trimester = dropdown + option trống (Perpetual)
  • CTA Deploy disabled nếu ngoài window / chưa Save

Sau Deploy (Sync LMS)

  • LMS mapping locked (Change Settings không mở lại Sync fields)
  • Hiện trạng thái linked / last sync nếu có
  • Fork CTA chỉ khi có trimester
Copy / UX đã từng request Đổi “Edit” → “Change Settings”; success Save có thể show Module code + LMS module name (và rename CB title theo LMS) — thuộc feedback UI riêng, không contradict model này.

13. Bảng lỗi & message

Bước Điều kiện Message / hành vi (client)
Save Duplicate code ngoài lineage “A module with this Module Code already exists.”
Save Không có LMS Module 101 “Module Code not found. Please verify the code in the LMS and try again.”
Fork Đã có undeployed fork Block + điều hướng tới fork hiện có
Deploy 0 Offering (term hoặc perpetual) Block + error (Offering missing / mismatch)
Deploy Ngoài cửa sổ 2 tuần (có trimester) Block theo deploy-window rule

14. FE / BE / QA — ai làm gì

Frontend

  • Dropdown trimester + empty = perpetual
  • Ẩn fork khi perpetual
  • Message lỗi Save/Deploy/Fork
  • Deep-link undeployed fork
  • Lock fields sau Deploy Sync LMS

Backend

  • Trimester: label ↔ 4-digit
  • Save: lookup Module 101
  • Deploy: P1/P2 + perpetual filter
  • Merge roster N
  • Lineage duplicate + undeployed gate
  • Bind Offering id(s) per version

QA

  • Chạy S1–S7
  • Staging: 101 vs Offering code
  • Ongoing / 4-digit filter
  • Fork gate + same code Save
  • Deploy window 2 weeks

15. Checklist QA (copy nhanh)

16. Edge còn mở (không chặn bắt đầu impl)

EdgeCâu hỏiWorkaround tạm
Perpetual semester shape Field nào? Exact value Ongoing / Semester_Ongoing / empty? Implement “không match regex 4-digit YY+T+0”; refine sau khi probe LMS
Merge role conflict Cùng user 2 role trên 2 Offering? Follow role matrix; nếu conflict → chọn role “cao hơn” (cần Product confirm)
Duplicate wording Check Module code, MC code, hay cả hai? Message chỉ nói Module Code Validate cả hai; message theo field đang conflict
Archived lineage reuse code Module mới được dùng lại code cũ? Hỏi Product khi gặp
Kết luận cho team Model Save / Deploy / Fork / Perpetual đã đủ để bắt đầu design kỹ thuật & ticket. Các edge trên tinh chỉnh lúc implement + probe LMS, không đảo Option A.

So sánh một trang

Save Deploy Fork
Input chính Module/MC code (±T) Đã save + T hoặc perpetual rule Module có T; lineage gate
LMS 101? Bắt buộc (Sync) Dùng để tìm Offering Không bắt buộc lúc tạo fork
LMS Offering 3? Không Bắt buộc (≥1) Không (Deploy sau mới cần)
Sync roster? Không Có (1 hoặc merge N) Không
Perpetual Cho phép Cho phép Cấm
Module code Set / verify Giữ Giữ nguyên