feat: phase1 platform upgrade with moderation, dev payments, admin panel and landing updates
This commit is contained in:
@ -1,14 +1,33 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, MaxLength, MinLength } from 'class-validator';
|
||||
import { HomeworkType } from '@coursecraft/database';
|
||||
import { IsEnum, IsOptional, IsString, MaxLength, MinLength } from 'class-validator';
|
||||
|
||||
export class SubmitHomeworkDto {
|
||||
@ApiProperty({
|
||||
description: 'Written homework answer',
|
||||
minLength: 50,
|
||||
minLength: 1,
|
||||
maxLength: 20000,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MinLength(50)
|
||||
@MinLength(1)
|
||||
@MaxLength(20000)
|
||||
content: string;
|
||||
content?: string;
|
||||
|
||||
@ApiProperty({ enum: HomeworkType, default: HomeworkType.TEXT })
|
||||
@IsOptional()
|
||||
@IsEnum(HomeworkType)
|
||||
type?: HomeworkType;
|
||||
|
||||
@ApiProperty({ required: false, description: 'File URL for FILE/PROJECT submission' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(1024)
|
||||
attachmentUrl?: string;
|
||||
|
||||
@ApiProperty({ required: false, description: 'GitHub repository URL' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(1024)
|
||||
githubUrl?: string;
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ export class EnrollmentController {
|
||||
@Body() dto: SubmitHomeworkDto,
|
||||
@CurrentUser() user: User,
|
||||
): Promise<any> {
|
||||
return this.enrollmentService.submitHomework(user.id, courseId, lessonId, dto.content);
|
||||
return this.enrollmentService.submitHomework(user.id, courseId, lessonId, dto);
|
||||
}
|
||||
|
||||
@Post(':courseId/review')
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { PrismaService } from '../common/prisma/prisma.service';
|
||||
import { HomeworkReviewStatus } from '@coursecraft/database';
|
||||
import { HomeworkReviewStatus, HomeworkType } from '@coursecraft/database';
|
||||
|
||||
const QUIZ_PASS_THRESHOLD = 70;
|
||||
|
||||
@ -172,7 +172,12 @@ export class EnrollmentService {
|
||||
return { homework, submission };
|
||||
}
|
||||
|
||||
async submitHomework(userId: string, courseId: string, lessonId: string, content: string): Promise<any> {
|
||||
async submitHomework(
|
||||
userId: string,
|
||||
courseId: string,
|
||||
lessonId: string,
|
||||
dto: { content?: string; type?: HomeworkType; attachmentUrl?: string; githubUrl?: string }
|
||||
): Promise<any> {
|
||||
const enrollment = await this.requireEnrollment(userId, courseId);
|
||||
await this.assertLessonUnlocked(userId, courseId, lessonId);
|
||||
|
||||
@ -184,20 +189,36 @@ export class EnrollmentService {
|
||||
}
|
||||
|
||||
const { homework } = await this.getHomework(userId, courseId, lessonId);
|
||||
const aiResult = this.gradeHomeworkWithAI(content);
|
||||
const submissionType = dto.type || homework.type || HomeworkType.TEXT;
|
||||
const normalizedContent = (dto.content || '').trim();
|
||||
if (!normalizedContent && !dto.attachmentUrl && !dto.githubUrl) {
|
||||
throw new BadRequestException('Provide content, attachment URL, or GitHub URL');
|
||||
}
|
||||
const fallbackContent =
|
||||
normalizedContent ||
|
||||
dto.githubUrl ||
|
||||
dto.attachmentUrl ||
|
||||
`Submission type: ${submissionType}`;
|
||||
const aiResult = this.gradeHomeworkWithAI(fallbackContent);
|
||||
|
||||
const submission = await this.prisma.homeworkSubmission.upsert({
|
||||
where: { homeworkId_userId: { homeworkId: homework.id, userId } },
|
||||
create: {
|
||||
homeworkId: homework.id,
|
||||
userId,
|
||||
content,
|
||||
content: fallbackContent,
|
||||
answerType: submissionType,
|
||||
attachmentUrl: dto.attachmentUrl || null,
|
||||
githubUrl: dto.githubUrl || null,
|
||||
aiScore: aiResult.score,
|
||||
aiFeedback: aiResult.feedback,
|
||||
reviewStatus: HomeworkReviewStatus.AI_REVIEWED,
|
||||
},
|
||||
update: {
|
||||
content,
|
||||
content: fallbackContent,
|
||||
answerType: submissionType,
|
||||
attachmentUrl: dto.attachmentUrl || null,
|
||||
githubUrl: dto.githubUrl || null,
|
||||
aiScore: aiResult.score,
|
||||
aiFeedback: aiResult.feedback,
|
||||
reviewStatus: HomeworkReviewStatus.AI_REVIEWED,
|
||||
|
||||
Reference in New Issue
Block a user