Skip to content

refactor: improve quiz reliability and maintainability for a smoother learner experience - #1946

Merged
its-gabo merged 12 commits into
stagingfrom
gs_refactor_1805_quiz_engine
Sep 22, 2026
Merged

its-gabo merged 12 commits into
stagingfrom
gs_refactor_1805_quiz_engine

Conversation

@its-gabo

@its-gabo its-gabo commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Issue(s)

Overview

Refactors quizzes onto the new assessment-based data model while preserving the existing API contracts.

This change includes:

  • New assessment, question, answer, blank, attempt, and feedback database structures with RLS and data migrations.
  • Quiz authoring and runtime services split into dedicated services, repositories, mappers, and shared types.
  • Compatibility mapping between the legacy quiz contract and the new assessment model.
  • Quiz evaluation, feedback, localized content, fill-in-the-blank handling, drag-and-drop handling, and learner progress integration.
  • Master-course sharing, course duplication, SCORM export, search indexing, seed data, and statistics updates for the new quiz structure.
  • Course translation extraction into a dedicated service and repository, including empty language-specific quiz records.
  • Base-language placeholders for untranslated chapters, lessons, and quiz content in the authoring UI.
  • Updated learning E2E fixtures to use stable <blank-answer-{uuid}> markers.

Business Value

Provides a semantically clearer and more maintainable foundation for quiz authoring, delivery, evaluation, localization, course sharing, and future quiz-engine versioning without requiring an immediate API contract migration.

It also keeps quiz behavior consistent across copied/shared courses and makes multilingual quiz content easier to manage.

@its-gabo
its-gabo requested a review from Japrolol September 2, 2026 12:29
@its-gabo its-gabo self-assigned this Sep 2, 2026
@its-gabo its-gabo added the review me 👀 PR is ready to be reviewed label Sep 2, 2026

@Japrolol Japrolol left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little feedback, but overall good enough for merge

lessonId: assessments.lessonId,
type: assessmentQuestions.questionType,
prompt: sql<LocalizedText>`${assessmentQuestions.prompt}`,
title: sql<LocalizedText | null>`${assessmentQuestions.title}`,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should type it directly in schema

.select({
id: assessmentQuestionChoiceOptions.id,
questionId: assessmentQuestionChoiceOptions.questionId,
optionText: sql<LocalizedText>`JSONB_BUILD_OBJECT(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cant we use our util for this

target: assessmentQuestionBlanks.id,
set: {
questionId: values.questionId,
textComparisonMode: values.textComparisonMode as never,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why never?


if (!correctAnswers.length) return undefined;

return `Correct answer: ${correctAnswers.join(", ")}`;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please localize

return assessment ?? null;
}

async getQuizLessonForAuthoring(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too much logic in repository

return assessment;
}

private async insertAssessmentQuestions(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also too much logic for repository

}
}

private async replaceQuestionConfiguration(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of this code should be extracted to service.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is too much logic here too, I prefer db operations in service to logic in repository

.filter((answer): answer is string => Boolean(answer)),
];

return correctAnswers.length ? `Correct answer: ${correctAnswers.join(", ")}` : null;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's localize

@its-gabo
its-gabo merged commit facfcfb into staging Sep 22, 2026
13 checks passed
@its-gabo
its-gabo deleted the gs_refactor_1805_quiz_engine branch September 22, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review me 👀 PR is ready to be reviewed run E2E tests ⚙️ Trigger E2E tests run on this branch.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants