apps/recallassess/recallassess-api/src/api/client/learning/learning.controller.ts
api/client/learning
Methods |
|
| Async getAllCoursePages | |||||||||
getAllCoursePages(learningGroupParticipantId: number, auth: CLAuthData)
|
|||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||
|
Parameters :
Returns :
Promise<CourseModulePageDto[]>
|
| Async getCourseModulePages | ||||||||||||
getCourseModulePages(learningGroupParticipantId: number, moduleId: number, auth: CLAuthData)
|
||||||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
||||||||||||
|
Parameters :
Returns :
Promise<CourseModulePageDto[]>
|
| Async getCourseModules | |||||||||
getCourseModules(learningGroupParticipantId: number, auth: CLAuthData)
|
|||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||
|
Parameters :
Returns :
Promise<CourseModuleDto[]>
|
| Async getFirstIncompletePage | |||||||||
getFirstIncompletePage(learningGroupParticipantId: number, auth: CLAuthData)
|
|||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||
|
Parameters :
Returns :
Promise<FirstIncompletePageDto>
|
| Async getPageBySequence | |||||||||||||||
getPageBySequence(learningGroupParticipantId: number, moduleSeq: number, pageSeq: number, auth: CLAuthData)
|
|||||||||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||||||||
|
Parameters :
Returns :
Promise<unknown>
|
| Async getVideoWatchStatus | ||||||||||||
getVideoWatchStatus(learningGroupParticipantId: number, pageId: number, auth: CLAuthData)
|
||||||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
||||||||||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async markPageComplete | |||||||||||||||
markPageComplete(learningGroupParticipantId: number, moduleId: number, pageId: number, auth: CLAuthData)
|
|||||||||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||||||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async startCourse | |||||||||
startCourse(learningGroupParticipantId: number, auth: CLAuthData)
|
|||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async trackPageView | |||||||||||||||
trackPageView(learningGroupParticipantId: number, moduleId: number, pageId: number, auth: CLAuthData)
|
|||||||||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||||||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async trackVideoProgress | ||||||||||||||||||
trackVideoProgress(learningGroupParticipantId: number, pageId: number, mediaId: number, body: VideoProgressDto, auth: CLAuthData)
|
||||||||||||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
||||||||||||||||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async validatePageAccess | |||||||||||||||
validatePageAccess(learningGroupParticipantId: number, moduleSeq: number, pageSeq: number, auth: CLAuthData)
|
|||||||||||||||
Decorators :
@HttpCode(HttpStatus.OK)
|
|||||||||||||||
|
Parameters :
Returns :
Promise<PageAccessValidationDto>
|
import { CLAuthData, ClientAuth } from "@api/shared/decorators";
import { Body, Controller, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post } from "@nestjs/common";
import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
import {
CourseModuleDto,
CourseModulePageDto,
PageSequenceInfoDto,
PageAccessValidationDto,
FirstIncompletePageDto,
VideoProgressDto,
} from "./dto";
import { CLLearningService } from "./learning.service";
@ApiTags("Client - Learning")
@Controller("api/client/learning")
export class CLLearningController {
constructor(private readonly learningService: CLLearningService) {}
@HttpCode(HttpStatus.OK)
@Post("enrollment/:learningGroupParticipantId/start")
@ApiOperation({ summary: "Start e-learning course" })
@ApiResponse({
status: 200,
description: "Course started successfully",
})
@ApiResponse({
status: 404,
description: "Course enrollment not found or PRE BAT not completed",
})
async startCourse(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@ClientAuth() auth: CLAuthData,
): Promise<{ success: boolean; elearningParticipantId: number }> {
return this.learningService.startCourse(learningGroupParticipantId, auth.participantId);
}
@HttpCode(HttpStatus.OK)
@Get("enrollment/:learningGroupParticipantId/modules")
@ApiOperation({ summary: "Get course modules with progress" })
@ApiResponse({
status: 200,
description: "Returns course modules with progress",
type: [CourseModuleDto],
})
async getCourseModules(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@ClientAuth() auth: CLAuthData,
): Promise<CourseModuleDto[]> {
return this.learningService.getCourseModules(learningGroupParticipantId, auth.participantId);
}
@HttpCode(HttpStatus.OK)
@Get("enrollment/:learningGroupParticipantId/module/:moduleId/pages")
@ApiOperation({ summary: "Get e-Learning content" })
@ApiResponse({
status: 200,
description: "Returns e-Learning content",
type: [CourseModulePageDto],
})
async getCourseModulePages(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@Param("moduleId", ParseIntPipe) moduleId: number,
@ClientAuth() auth: CLAuthData,
): Promise<CourseModulePageDto[]> {
return this.learningService.getCourseModulePages(learningGroupParticipantId, moduleId, auth.participantId);
}
@HttpCode(HttpStatus.OK)
@Get("enrollment/:learningGroupParticipantId/pages")
@ApiOperation({ summary: "Get all course pages across all modules (continuous flow)" })
@ApiResponse({
status: 200,
description: "Returns all course pages with module information",
type: [CourseModulePageDto],
})
async getAllCoursePages(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@ClientAuth() auth: CLAuthData,
): Promise<CourseModulePageDto[]> {
return this.learningService.getAllCoursePages(learningGroupParticipantId, auth.participantId);
}
@HttpCode(HttpStatus.OK)
@Post("enrollment/:learningGroupParticipantId/module/:moduleId/page/:pageId/view")
@ApiOperation({ summary: "Track page view (set start_date)" })
@ApiResponse({
status: 200,
description: "Page view tracked",
})
async trackPageView(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@Param("moduleId", ParseIntPipe) moduleId: number,
@Param("pageId", ParseIntPipe) pageId: number,
@ClientAuth() auth: CLAuthData,
): Promise<{ success: boolean }> {
return this.learningService.trackPageView(learningGroupParticipantId, moduleId, pageId, auth.participantId);
}
@HttpCode(HttpStatus.OK)
@Post("enrollment/:learningGroupParticipantId/module/:moduleId/page/:pageId/complete")
@ApiOperation({ summary: "Mark page as completed" })
@ApiResponse({
status: 200,
description: "Page marked as completed",
})
async markPageComplete(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@Param("moduleId", ParseIntPipe) moduleId: number,
@Param("pageId", ParseIntPipe) pageId: number,
@ClientAuth() auth: CLAuthData,
): Promise<{ success: boolean }> {
return this.learningService.markPageComplete(learningGroupParticipantId, moduleId, pageId, auth.participantId);
}
@HttpCode(HttpStatus.OK)
@Get("enrollment/:learningGroupParticipantId/page-by-sequence/module-:moduleSeq/page-:pageSeq")
@ApiOperation({ summary: "Get page by module and page sequence numbers" })
@ApiResponse({
status: 200,
description: "Returns page data with sequence information",
type: CourseModulePageDto,
})
@ApiResponse({
status: 400,
description: "Invalid sequence numbers",
})
@ApiResponse({
status: 404,
description: "Page not found",
})
async getPageBySequence(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@Param("moduleSeq", ParseIntPipe) moduleSeq: number,
@Param("pageSeq", ParseIntPipe) pageSeq: number,
@ClientAuth() auth: CLAuthData,
): Promise<CourseModulePageDto & { sequenceInfo: PageSequenceInfoDto }> {
return this.learningService.getPageBySequence(learningGroupParticipantId, moduleSeq, pageSeq, auth.participantId);
}
@HttpCode(HttpStatus.OK)
@Get("enrollment/:learningGroupParticipantId/validate-page/module-:moduleSeq/page-:pageSeq")
@ApiOperation({ summary: "Validate if a page can be accessed based on completion of previous pages" })
@ApiResponse({
status: 200,
description: "Returns validation result with redirect information if invalid",
type: PageAccessValidationDto,
})
async validatePageAccess(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@Param("moduleSeq", ParseIntPipe) moduleSeq: number,
@Param("pageSeq", ParseIntPipe) pageSeq: number,
@ClientAuth() auth: CLAuthData,
): Promise<PageAccessValidationDto> {
return this.learningService.validatePageAccess(learningGroupParticipantId, moduleSeq, pageSeq, auth.participantId);
}
@HttpCode(HttpStatus.OK)
@Get("enrollment/:learningGroupParticipantId/first-incomplete-page")
@ApiOperation({ summary: "Get first incomplete page URL information" })
@ApiResponse({
status: 200,
description: "Returns first incomplete page sequence and URL",
type: FirstIncompletePageDto,
})
@ApiResponse({
status: 404,
description: "No learning content available",
})
async getFirstIncompletePage(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@ClientAuth() auth: CLAuthData,
): Promise<FirstIncompletePageDto> {
return this.learningService.getFirstIncompletePage(learningGroupParticipantId, auth.participantId);
}
@HttpCode(HttpStatus.OK)
@Post("enrollment/:learningGroupParticipantId/page/:pageId/video/:mediaId/progress")
@ApiOperation({ summary: "Track video watch progress" })
@ApiResponse({
status: 200,
description: "Video progress tracked successfully",
})
@ApiResponse({
status: 404,
description: "Video or enrollment not found",
})
async trackVideoProgress(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@Param("pageId", ParseIntPipe) pageId: number,
@Param("mediaId", ParseIntPipe) mediaId: number,
@Body() body: VideoProgressDto,
@ClientAuth() auth: CLAuthData,
): Promise<{ success: boolean; requirementMet: boolean }> {
return this.learningService.trackVideoProgress(
learningGroupParticipantId,
pageId,
mediaId,
body.watchedSeconds,
auth.participantId,
);
}
@HttpCode(HttpStatus.OK)
@Get("enrollment/:learningGroupParticipantId/page/:pageId/videos-status")
@ApiOperation({ summary: "Get video watch status for all videos on a page" })
@ApiResponse({
status: 200,
description: "Returns video watch status for all videos",
})
async getVideoWatchStatus(
@Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
@Param("pageId", ParseIntPipe) pageId: number,
@ClientAuth() auth: CLAuthData,
): Promise<{
allRequirementsMet: boolean;
videos: Array<{
mediaId: number;
watchedSeconds: number;
requiredSeconds: number;
requirementMet: boolean;
remainingSeconds: number;
}>;
}> {
return this.learningService.getVideoWatchStatus(learningGroupParticipantId, pageId, auth.participantId);
}
}