feat: certification rules, content sanitization, handle draft course updates and reset content, better redis logging
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import { CERTIFICATE_THEME_IDS, DEFAULT_CERTIFICATE_THEME_ID, type CertificateThemeId } from './constants';
|
||||
|
||||
const CERTIFICATE_THEME_ID_SET = new Set<string>(CERTIFICATE_THEME_IDS);
|
||||
|
||||
export function parseCertificateThemeId(raw: string | null | undefined): CertificateThemeId {
|
||||
if (raw != null && raw !== '' && CERTIFICATE_THEME_ID_SET.has(raw)) {
|
||||
return raw as CertificateThemeId;
|
||||
}
|
||||
return DEFAULT_CERTIFICATE_THEME_ID;
|
||||
}
|
||||
@@ -37,6 +37,19 @@ export type CourseSortOrder = (typeof CourseSortOrder)[keyof typeof CourseSortOr
|
||||
|
||||
export const DEFAULT_SORT_ORDER: CourseSortOrder = CourseSortOrder.Desc;
|
||||
|
||||
export const CERTIFICATE_THEME_IDS = [
|
||||
'professional',
|
||||
'plain',
|
||||
'purpleProfessionalBadge',
|
||||
'blueProfessionalBadge',
|
||||
'purpleBadgePattern',
|
||||
'blueBadgePattern'
|
||||
] as const;
|
||||
|
||||
export type CertificateThemeId = (typeof CERTIFICATE_THEME_IDS)[number];
|
||||
|
||||
export const DEFAULT_CERTIFICATE_THEME_ID: CertificateThemeId = 'professional';
|
||||
|
||||
const COURSE_SORT_ORDER_VALUES = new Set<string>(Object.values(CourseSortOrder));
|
||||
|
||||
export function parseCourseSortOrder(value: string | null | undefined): CourseSortOrder {
|
||||
|
||||
@@ -71,16 +71,17 @@ export function formatAnswers(data: {
|
||||
answers: SubmissionAnswer[];
|
||||
}): Record<string, AnswerData> {
|
||||
const answers: Record<string, AnswerData> = {};
|
||||
const questionByIdAndName: Record<string, string> = {};
|
||||
const questionKeyById: Record<string, string> = {};
|
||||
|
||||
for (const question of data.questions) {
|
||||
questionByIdAndName[String(question.id)] = question.name ?? '';
|
||||
const key = question.name ? String(question.name) : String(question.id);
|
||||
questionKeyById[String(question.id)] = key;
|
||||
}
|
||||
|
||||
for (const answer of data.answers) {
|
||||
const questionName = questionByIdAndName[String(answer.questionId)];
|
||||
if (questionName && answer.answerData) {
|
||||
answers[questionName] = answer.answerData;
|
||||
const questionKey = questionKeyById[String(answer.questionId)];
|
||||
if (questionKey && answer.answerData) {
|
||||
answers[questionKey] = answer.answerData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -266,6 +266,13 @@ export type DeleteCourseRequest = (typeof classroomio.course)[':courseId']['$del
|
||||
export type UpdateCourseContentRequest = (typeof classroomio.course)[':courseId']['content']['$put'];
|
||||
export type DeleteCourseContentRequest = (typeof classroomio.course)[':courseId']['content']['$delete'];
|
||||
export type GetCourseProgressRequest = (typeof classroomio.course)[':courseId']['progress']['$get'];
|
||||
export type GetCertificationEvaluationRequest =
|
||||
(typeof classroomio.course)[':courseId']['certification-evaluation']['$get'];
|
||||
export type GetCertificationEvaluationSuccess = Extract<
|
||||
InferResponseType<GetCertificationEvaluationRequest>,
|
||||
{ success: true }
|
||||
>;
|
||||
export type CertificationEvaluationData = GetCertificationEvaluationSuccess['data'];
|
||||
export type CloneCourseRequest = (typeof classroomio.course)[':courseId']['clone']['$post'];
|
||||
export type EnrollCourseRequest = (typeof classroomio.course)[':courseId']['enroll']['$post'];
|
||||
|
||||
@@ -280,12 +287,17 @@ export type CourseMetadata = (NonNullable<ApiCourse['metadata']> extends object
|
||||
: Record<string, unknown>) & {
|
||||
isContentGroupingEnabled?: boolean;
|
||||
};
|
||||
export type CourseCertificate =
|
||||
NonNullable<ApiCourse['certificate']> extends object
|
||||
? NonNullable<ApiCourse['certificate']>
|
||||
: Record<string, unknown>;
|
||||
export type CourseContent = NonNullable<ApiCourse['content']>;
|
||||
export type CourseContentSection = CourseContent['sections'][number];
|
||||
export type CourseContentItem = CourseContent['items'][number];
|
||||
|
||||
export type Course = Omit<ApiCourse, 'metadata' | 'lessons' | 'sections' | 'exercises'> & {
|
||||
metadata?: CourseMetadata | null;
|
||||
certificate?: CourseCertificate | null;
|
||||
content: CourseContent;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user