diff --git a/apps/server/src/problems/problems.module.ts b/apps/server/src/problems/problems.module.ts index 6aa9c76..60eeb2d 100644 --- a/apps/server/src/problems/problems.module.ts +++ b/apps/server/src/problems/problems.module.ts @@ -1,9 +1,17 @@ import { Module } from '@nestjs/common'; import { ProblemsController } from './problems.controller'; import { ProblemsService } from './problems.service'; +import { ValidationService } from './validation/validation.service'; +import { HandlerResolver } from './validation/handler-resolver'; +import { UnitValidationHandler } from './validation/handlers/unit-validation.handler'; @Module({ controllers: [ProblemsController], - providers: [ProblemsService], + providers: [ + ProblemsService, + ValidationService, + HandlerResolver, + UnitValidationHandler, + ], }) export class ProblemsModule {} diff --git a/apps/server/src/problems/problems.service.ts b/apps/server/src/problems/problems.service.ts index e5868c4..5cff317 100644 --- a/apps/server/src/problems/problems.service.ts +++ b/apps/server/src/problems/problems.service.ts @@ -1,27 +1,26 @@ import { Injectable } from '@nestjs/common'; import { SubmitRequestDto } from './dto/submit-request.dto'; import { SubmitResponseDto } from './dto/submit-response.dto'; +import { ValidationService } from './validation/validation.service'; +import { ProblemType } from './types/problem-type.enum'; @Injectable() export class ProblemsService { + constructor(private readonly validationService: ValidationService) {} + submit(problemId: number, body: SubmitRequestDto): SubmitResponseDto { - const problem_type = body.submitConfig?.[0]; - const answer = (problem_type?.configInfo?.answer ?? '') as string; + // MOCK 문제 데이터 + const problemData = { + problemType: ProblemType.UNIT, + answer: '1234', + }; - // test: 정답이 1234이면 PASS, 아니면 FAIL - const isCorrect = answer === '1234'; + const result = this.validationService.validate( + problemData.problemType, + body.submitConfig[0], + problemData, + ); - return isCorrect - ? { result: 'PASS', feedback: [] } - : { - result: 'FAIL', - feedback: [ - { - field: 'answer', - code: 'WRONG_ANSWER', - message: '틀렸습니다.', - }, - ], - }; + return result; } } diff --git a/apps/server/src/problems/types/problem-type.enum.ts b/apps/server/src/problems/types/problem-type.enum.ts new file mode 100644 index 0000000..1f8183d --- /dev/null +++ b/apps/server/src/problems/types/problem-type.enum.ts @@ -0,0 +1,4 @@ +export enum ProblemType { + UNIT = 'unit', + SCENARIO = 'scenario', +} diff --git a/apps/server/src/problems/validation/handler-resolver.ts b/apps/server/src/problems/validation/handler-resolver.ts new file mode 100644 index 0000000..064f3b0 --- /dev/null +++ b/apps/server/src/problems/validation/handler-resolver.ts @@ -0,0 +1,21 @@ +import { Injectable } from '@nestjs/common'; +import { ValidationHandler } from './handlers/validation.handler'; +import { UnitValidationHandler } from './handlers/unit-validation.handler'; +import { ProblemType } from '../types/problem-type.enum'; + +@Injectable() +export class HandlerResolver { + private handlers: Map; + + constructor(private readonly unitHandler: UnitValidationHandler) { + this.handlers = new Map([[ProblemType.UNIT, this.unitHandler]]); + } + + resolve(problemType: ProblemType): ValidationHandler { + const handler = this.handlers.get(problemType); + if (!handler) { + throw new Error(`${problemType} 에 대한 ValidationHandler가 없습니다.`); + } + return handler; + } +} diff --git a/apps/server/src/problems/validation/handlers/unit-validation.handler.ts b/apps/server/src/problems/validation/handlers/unit-validation.handler.ts new file mode 100644 index 0000000..d19f609 --- /dev/null +++ b/apps/server/src/problems/validation/handlers/unit-validation.handler.ts @@ -0,0 +1,32 @@ +import { ValidationHandler } from './validation.handler'; +import { SubmitResponseDto } from 'src/problems/dto/submit-response.dto'; +import { ConfigDto } from 'src/problems/dto/submit-request.dto'; +import { ProblemType } from 'src/problems/types/problem-type.enum'; + +export class UnitValidationHandler implements ValidationHandler { + support(problemType: ProblemType): boolean { + return problemType === ProblemType.UNIT; + } + + validate(submitConfig: ConfigDto, problemData: any): SubmitResponseDto { + // test 용 검증 로직: 제출한 풀이가 problemData.answer와 일치하는지 확인 + const answer = (submitConfig.configInfo?.answer ?? '') as string; + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const expectedAnswer = problemData.answer as string; + + if (answer === expectedAnswer) { + return { result: 'PASS', feedback: [] }; + } + + return { + result: 'FAIL', + feedback: [ + { + field: 'answer', + code: 'WRONG_ANSWER', + message: '틀렸습니다.', + }, + ], + }; + } +} diff --git a/apps/server/src/problems/validation/handlers/validation.handler.ts b/apps/server/src/problems/validation/handlers/validation.handler.ts new file mode 100644 index 0000000..44633f5 --- /dev/null +++ b/apps/server/src/problems/validation/handlers/validation.handler.ts @@ -0,0 +1,20 @@ +import { ConfigDto } from 'src/problems/dto/submit-request.dto'; +import { SubmitResponseDto } from 'src/problems/dto/submit-response.dto'; +import { ProblemType } from 'src/problems/types/problem-type.enum'; + +export interface ValidationHandler { + /** + * 문제 타입(ex. unit)에 대해 핸들러가 지원되는지 여부를 반환하는 메서드 + * @param problemType 문제 타입 + * @returns 지원 여부 (true/false) + */ + support(problemType: ProblemType): boolean; + + /** + * 제출된 풀이를 검증하고 결과를 반환하는 메서드 + * @param submitConfig 제출된 풀이 객체 + * @param problemData 문제의 메타데이터 (우선은 이렇게 둠) + * @returns 검증 결과 객체 + */ + validate(submitConfig: ConfigDto, problemData: any): SubmitResponseDto; +} diff --git a/apps/server/src/problems/validation/validation.service.ts b/apps/server/src/problems/validation/validation.service.ts new file mode 100644 index 0000000..6371638 --- /dev/null +++ b/apps/server/src/problems/validation/validation.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@nestjs/common'; +import { ConfigDto } from '../dto/submit-request.dto'; +import { HandlerResolver } from './handler-resolver'; +import { ProblemType } from '../types/problem-type.enum'; + +@Injectable() +export class ValidationService { + constructor(private readonly handlerResolver: HandlerResolver) {} + + validate( + problemType: ProblemType, + submitConfig: ConfigDto, + problemData: any, + ) { + const handler = this.handlerResolver.resolve(problemType); + return handler.validate(submitConfig, problemData); + } +}