feat: widgets and ai chat

This commit is contained in:
Rotimi Best
2026-04-27 11:40:38 +01:00
parent ae1801f85f
commit 5717dd8004
391 changed files with 28177 additions and 22467 deletions
+16 -1
View File
@@ -36,6 +36,7 @@ import { QUESTION_TYPE_ID_TO_KEY } from '@cio/question-types';
import { getDashboardBaseUrl } from '@api/config/dashboard-url';
import { generateDocumentDownloadPresignedUrls } from '@api/utils/s3';
import { syncComplianceProgressFromSubmission } from '@api/services/course/compliance';
type SubmissionGradingState = 'queued' | 'processing' | 'awaiting_manual' | 'completed' | 'failed';
type SubmissionOverallStatus = 'auto_graded' | 'manual_required' | 'hybrid';
@@ -573,7 +574,9 @@ export async function createSubmissionService(
}
const shouldAutoGrade =
course?.type === 'SELF_PACED' && overallStatus === 'auto_graded' && exerciseWithRelations.questions.length > 0;
(course?.type === 'SELF_PACED' || course?.type === 'COMPLIANCE') &&
overallStatus === 'auto_graded' &&
exerciseWithRelations.questions.length > 0;
if (shouldAutoGrade) {
const answeredIds = new Set(answerByQuestionId.keys());
@@ -631,6 +634,8 @@ export async function createSubmissionService(
console.error('Failed to send exercise submission update email:', emailError);
});
await syncComplianceProgressFromSubmission(courseId, submittedBy);
const enrichedAnswers =
answersWithPoints.length > 0 ? await enrichFileUploadAnswersArray(answersWithPoints) : answersWithPoints;
return { ...submission, answers: enrichedAnswers };
@@ -641,6 +646,8 @@ export async function createSubmissionService(
console.error('Failed to send exercise submission update email:', emailError);
});
await syncComplianceProgressFromSubmission(courseId, submittedBy);
return submission;
} catch (error) {
if (error instanceof AppError) {
@@ -695,6 +702,10 @@ export async function updateSubmissionService(submissionId: string, data: TSubmi
});
}
if (updated.gradingState === 'completed' && updated.courseId && updated.submittedBy) {
await syncComplianceProgressFromSubmission(updated.courseId, updated.submittedBy);
}
return updated;
} catch (error) {
if (error instanceof AppError) {
@@ -793,6 +804,10 @@ export async function updateSubmissionGradesBatch(
});
}
if (updated.courseId && updated.submittedBy) {
await syncComplianceProgressFromSubmission(updated.courseId, updated.submittedBy);
}
return updated;
} catch (error) {
if (error instanceof AppError) {