apps/recallassess/recallassess-api/src/api/client/assessment/assessment.controller.ts
api/client/assessment
Methods |
|
| Async getAdvancedIndividualPerformance | ||||||
getAdvancedIndividualPerformance(auth: CLAuthData)
|
||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
||||||
|
Get advanced individual performance data for report GET /api/client/assessment/advanced-individual-performance
Parameters :
Returns :
unknown
|
| Async getAssessmentCompletionReport | ||||||
getAssessmentCompletionReport(auth: CLAuthData)
|
||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
||||||
|
Get assessment completion data for report GET /api/client/assessment/completion-report
Parameters :
Returns :
unknown
|
| Async getPostBatAssessment | |||||||||
getPostBatAssessment(learningGroupParticipantId: number, auth: CLAuthData)
|
|||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||
|
Get POST BAT assessment for a course enrollment GET /api/client/assessment/enrollment/:learningGroupParticipantId/post-bat
Parameters :
Returns :
Promise<literal type>
|
| Async getPreBatAssessment | |||||||||
getPreBatAssessment(learningGroupParticipantId: number, auth: CLAuthData)
|
|||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||
|
Get PRE BAT assessment for a course enrollment GET /api/client/assessment/enrollment/:learningGroupParticipantId/pre-bat
Parameters :
Returns :
Promise<literal type>
|
| Async getPrePostBatData | ||||||||||||
getPrePostBatData(learningGroupId: number, participantId: string | undefined, auth: CLAuthData)
|
||||||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
||||||||||||
|
Get formatted pre/post BAT data for AI-CodeRythm integration team GET /api/client/assessment/pre-post-bat-data/:learningGroupId?participant_id=123
Parameters :
Returns :
unknown
|
| Async submitAssessment | |||||||||
submitAssessment(submitDto: SubmitAssessmentDto, auth: CLAuthData)
|
|||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||
|
Submit assessment answers POST /api/client/assessment/submit
Parameters :
Returns :
Promise<literal type>
|
import { CLAuthData, ClientAuth } from "@api/shared/decorators";
import { Body, Controller, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post, Query } from "@nestjs/common";
import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
import { AssessmentType } from "@prisma/client";
import { CLAssessmentService } from "./assessment.service";
import { CLAssessmentDto, CLAssessmentQuestionDto, SubmitAssessmentDto } from "./dto";
@ApiTags("Client - Assessment")
@Controller("api/client/assessment")
// fix/recallassess/hide-data: participant access control for pre-post-bat-data
export class CLAssessmentController {
constructor(private readonly assessmentService: CLAssessmentService) {}
/**
* Get PRE BAT assessment for a course enrollment
* GET /api/client/assessment/enrollment/:learningGroupParticipantId/pre-bat
*/
@HttpCode(HttpStatus.OK)
@Get("enrollment/:learningGroupParticipantId/pre-bat")
@ApiOperation({ summary: "Get PRE BAT assessment for a course enrollment" })
@ApiResponse({
status: 200,
description: "Returns assessment with questions and answers",
})
@ApiResponse({
status: 404,
description: "Course enrollment or assessment not found",
})
async getPreBatAssessment(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@ClientAuth() auth: CLAuthData,
): Promise<{ assessment: CLAssessmentDto; questions: CLAssessmentQuestionDto[]; isCompleted: boolean }> {
return this.assessmentService.getPreBatAssessmentByLearningGroupParticipantId(
learningGroupParticipantId,
auth.participantId,
);
}
/**
* Get POST BAT assessment for a course enrollment
* GET /api/client/assessment/enrollment/:learningGroupParticipantId/post-bat
*/
@HttpCode(HttpStatus.OK)
@Get("enrollment/:learningGroupParticipantId/post-bat")
@ApiOperation({ summary: "Get POST BAT assessment for a course enrollment" })
@ApiResponse({
status: 200,
description: "Returns assessment with questions and answers",
})
@ApiResponse({
status: 404,
description: "Course enrollment or assessment not found",
})
async getPostBatAssessment(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@ClientAuth() auth: CLAuthData,
): Promise<{ assessment: CLAssessmentDto; questions: CLAssessmentQuestionDto[]; isCompleted: boolean }> {
return this.assessmentService.getPostBatAssessmentByLearningGroupParticipantId(
learningGroupParticipantId,
auth.participantId,
);
}
/**
* Submit assessment answers
* POST /api/client/assessment/submit
*/
@HttpCode(HttpStatus.OK)
@Post("submit")
@ApiOperation({ summary: "Submit assessment answers" })
@ApiResponse({
status: 200,
description: "Assessment submitted successfully",
})
@ApiResponse({
status: 404,
description: "Assessment or course not found",
})
async submitAssessment(
@Body() submitDto: SubmitAssessmentDto,
@ClientAuth() auth: CLAuthData,
): Promise<{ success: boolean; assessmentParticipantId: number }> {
// Determine assessment type from request (default to PRE_BAT for backward compatibility)
// For POST BAT, we'll add a type field to the DTO, but for now we'll use a query param or header
// Actually, let's check if it's POST BAT by checking if e-learning is completed
// But for simplicity, let's add assessment_type to the DTO
return this.assessmentService.submitAssessment(
submitDto,
auth.participantId,
submitDto.assessment_type || AssessmentType.PRE_BAT,
);
}
/**
* Get formatted pre/post BAT data for AI-CodeRythm integration team
* GET /api/client/assessment/pre-post-bat-data/:learningGroupId?participant_id=123
* - Access restricted: learning group must belong to caller's company.
* - PARTICIPANT: can only request their own data (participant_id is ignored).
* - PARTICIPANT_ADMIN: can request all participants in the group or filter by participant_id (same company).
*/
@HttpCode(HttpStatus.OK)
@Get("pre-post-bat-data/:learningGroupId")
@ApiOperation({
summary: "Get formatted pre/post BAT data for AI-CodeRythm integration",
description:
"Returns PRE/POST BAT data. Participants can only access their own data; PARTICIPANT_ADMIN can access data for participants in their company.",
})
@ApiResponse({
status: 200,
description: "Returns formatted data ready to send to AI-CodeRythm integration team",
})
@ApiResponse({
status: 401,
description: "Unauthorized - Invalid or missing JWT token",
})
@ApiResponse({
status: 403,
description: "Forbidden - Cannot access this learning group or participant data",
})
@ApiResponse({
status: 404,
description: "Learning group, course, or participant not found",
})
async getPrePostBatData(
@Param("learningGroupId", ParseIntPipe) learningGroupId: number,
@Query("participant_id") participantId: string | undefined,
@ClientAuth() auth: CLAuthData,
) {
const participantIdNumber = participantId ? parseInt(participantId, 10) : undefined;
return this.assessmentService.formatPrePostBatDataForIntegration(learningGroupId, participantIdNumber, {
companyId: auth.companyId,
participantId: auth.participantId,
role: auth.role,
});
}
/**
* Get assessment completion data for report
* GET /api/client/assessment/completion-report
*/
@HttpCode(HttpStatus.OK)
@Get("completion-report")
@ApiOperation({ summary: "Get assessment completion data for report" })
@ApiResponse({
status: 200,
description: "Returns assessment completion data for all assessments",
})
async getAssessmentCompletionReport(@ClientAuth() auth: CLAuthData) {
return this.assessmentService.getAssessmentCompletionReport(auth.participantId, auth.companyId);
}
/**
* Get advanced individual performance data for report
* GET /api/client/assessment/advanced-individual-performance
*/
@HttpCode(HttpStatus.OK)
@Get("advanced-individual-performance")
@ApiOperation({ summary: "Get advanced individual performance analytics data" })
@ApiResponse({
status: 200,
description: "Returns advanced performance data for all participants",
})
async getAdvancedIndividualPerformance(@ClientAuth() auth: CLAuthData) {
return this.assessmentService.getAdvancedIndividualPerformance(auth.companyId);
}
}