Call SCORM INTERACTIVE in the interface

Hanabank's users find this name easier to understand. Display text changes in
English and Indonesian, and "1.2" goes with it. The package format, internal
ids and schedule names stay as they are.

The chat's example now says INTERACTIVE, so the parser reads that word as well.
A bare "interactive" only counts when no other kind is named, so "kuis
interaktif" stays a quiz.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Iqbal
2026-11-04 10:32:53 +07:00
parent 6d78476b2b
commit bdc65529bd
4 changed files with 45 additions and 21 deletions

View File

@@ -19,7 +19,7 @@ export const kindLabel = (kind: ContentKind) => t(`kind.${kind}` as Key)
// Checked in order; the first match wins, so multi-word phrases come before their parts.
const KIND_WORDS: [ContentKind, RegExp][] = [
// SCORM first: a SCORM module includes a quiz, so "SCORM module with a quiz" is still SCORM.
['scorm', /\b(scorm|skorm|skong|e-?learning)\b/],
['scorm', /\b(scorm|skorm|skong|e-?learning|interactive modules?|modul(e|es)? interaktif)\b/],
['flashcards', /\b(flash ?cards?|kartu (belajar|hafalan))\b/],
['quiz', /\b(kuis|quiz|quizzes|soal latihan|tes|tests?|ujian|exams?)\b/],
['roleplay', /\b(role ?-?plays?|bermain peran)\b/],
@@ -30,13 +30,18 @@ const KIND_WORDS: [ContentKind, RegExp][] = [
['summary', /\b(summary|summaries|ringkasan|rangkuman|artikel|articles?|teks|texts?)\b/],
]
// The interface calls SCORM "INTERACTIVE", so the bare word means it too, but only when nothing else
// is named: "kuis interaktif" stays a quiz, and "summaries about interactive learning" stay summaries.
const INTERACTIVE = /\b(interactive|interaktif)\b/
/** Every content kind a text names, in the order it names them: "ringkasan dan kuis" → summary, quiz. */
export function kindsIn(text: string): ContentKind[] {
return KIND_WORDS
const kinds = KIND_WORDS
.map(([kind, re]) => [kind, text.search(re)] as const)
.filter(([, at]) => at >= 0)
.sort((a, b) => a[1] - b[1])
.map(([kind]) => kind)
return kinds.length || !INTERACTIVE.test(text) ? kinds : ['scorm']
}
// "10 konten", "5 materi pembelajaran", "10 pdf": content of no particular kind, so the agent asks which.
@@ -208,6 +213,8 @@ function parseClause(clause: string): Rule | null {
const m = re.exec(clause)
if (m) return contentRule(clause, kind, countOf(clause, m.index))
}
const interactive = INTERACTIVE.exec(clause)
if (interactive) return contentRule(clause, 'scorm', countOf(clause, interactive.index))
const g = GENERIC.exec(clause)
if (g) {
const count = countBefore(clause, g.index)