File

apps/recallassess/recallassess-api/src/api/client/reports/reports.controller.ts

Prefix

api/client/reports

Description

Unified Reports Controller

All reports follow the pattern: GET /api/client/reports/{report-name}

This makes it easy to add new reports in the future - just add a new route handler.

Index

Methods

Methods

Async getAdvancedGroupPerformanceReport
getAdvancedGroupPerformanceReport(auth: CLAuthData, group?: string, learningGroup?: string, course?: string, period?: string, status?: string)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('advanced-group-performance')

Get advanced group performance report GET /api/client/reports/advanced-group-performance

Parameters :
Name Type Optional
auth CLAuthData No
group string Yes
learningGroup string Yes
course string Yes
period string Yes
status string Yes
Returns : unknown
Async getAdvancedIndividualPerformanceReport
getAdvancedIndividualPerformanceReport(auth: CLAuthData, accountType?: string, course?: string, stage?: string, performanceLevel?: string, lastActivePeriod?: string, search?: string)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('advanced-individual-performance')

Get advanced individual performance report GET /api/client/reports/advanced-individual-performance

Parameters :
Name Type Optional
auth CLAuthData No
accountType string Yes
course string Yes
stage string Yes
performanceLevel string Yes
lastActivePeriod string Yes
search string Yes
Returns : unknown
Async getAssessmentCompletionReport
getAssessmentCompletionReport(auth: CLAuthData, assessmentType?: string, completionStatus?: string, period?: string, course?: string, learningGroup?: string, search?: string)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('assessment-completion')

Get assessment completion report GET /api/client/reports/assessment-completion

Parameters :
Name Type Optional
auth CLAuthData No
assessmentType string Yes
completionStatus string Yes
period string Yes
course string Yes
learningGroup string Yes
search string Yes
Returns : unknown
Async getBehaviouralAssessmentAnalysisReport
getBehaviouralAssessmentAnalysisReport(auth: CLAuthData, group?: string, assessmentType?: string, course?: string, scoreRange?: string, period?: string, assessmentPeriod?: string)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('behavioural-assessment-analysis')

Get behavioural assessment analysis report GET /api/client/reports/behavioural-assessment-analysis

Parameters :
Name Type Optional
auth CLAuthData No
group string Yes
assessmentType string Yes
course string Yes
scoreRange string Yes
period string Yes
assessmentPeriod string Yes
Returns : unknown
Async getCourseLicenseUtilizationReport
getCourseLicenseUtilizationReport(auth: CLAuthData, course?: string, learningGroup?: string, period?: string, utilizationStatus?: string)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('course-license-utilization')

Get course license utilization report GET /api/client/reports/course-license-utilization

Parameters :
Name Type Optional
auth CLAuthData No
course string Yes
learningGroup string Yes
period string Yes
utilizationStatus string Yes
Async getParticipantRosterReport
getParticipantRosterReport(auth: CLAuthData, status?: string, participantGroup?: string, sq?: string, period?: string)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('participant-roster')

Get participant roster report GET /api/client/reports/participant-roster

Parameters :
Name Type Optional
auth CLAuthData No
status string Yes
participantGroup string Yes
sq string Yes
period string Yes
Returns : unknown
Async getPostBatAnalysis
getPostBatAnalysis(auth: CLAuthData)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('post-bat-analysis')

Get post-BAT analysis (placeholder participant list) GET /api/client/reports/post-bat-analysis

NOTE:

  • Currently reuses participant list data as a placeholder, so the frontend can be wired end-to-end.
  • Replace with real post-BAT aggregation logic when ready.
Parameters :
Name Type Optional
auth CLAuthData No
Returns : unknown
Async getPreBatAnalysis
getPreBatAnalysis(auth: CLAuthData)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('pre-bat-analysis')

Get pre-BAT analysis (placeholder participant list) GET /api/client/reports/pre-bat-analysis

NOTE:

  • Currently reuses participant list data as a placeholder, so the frontend can be wired end-to-end.
  • Replace with real pre-BAT aggregation logic when ready.
Parameters :
Name Type Optional
auth CLAuthData No
Returns : unknown
Async getStandardGroupPerformanceReport
getStandardGroupPerformanceReport(auth: CLAuthData, group?: string, learningGroup?: string, course?: string, period?: string, status?: string)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('standard-group-performance')

Get standard group performance report GET /api/client/reports/standard-group-performance

Parameters :
Name Type Optional
auth CLAuthData No
group string Yes
learningGroup string Yes
course string Yes
period string Yes
status string Yes
Returns : unknown
Async getStandardIndividualPerformanceReport
getStandardIndividualPerformanceReport(auth: CLAuthData, accountType?: string, course?: string, stage?: string, performanceLevel?: string, lastActivePeriod?: string, search?: string)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('standard-individual-performance')

Get standard individual performance report GET /api/client/reports/standard-individual-performance

Parameters :
Name Type Optional
auth CLAuthData No
accountType string Yes
course string Yes
stage string Yes
performanceLevel string Yes
lastActivePeriod string Yes
search string Yes
Returns : unknown
Async getTrainingImpactReport
getTrainingImpactReport(auth: CLAuthData, course?: string, accountType?: string, period?: string, impactLevel?: string, learningGroup?: string)
Decorators :
@HttpCode(HttpStatus.OK)
@Get('training-impact')

Get training impact report GET /api/client/reports/training-impact

Parameters :
Name Type Optional
auth CLAuthData No
course string Yes
accountType string Yes
period string Yes
impactLevel string Yes
learningGroup string Yes
Returns : unknown
import { CLAuthData, ClientAuth } from "@api/shared/decorators";
import { Controller, Get, HttpCode, HttpStatus, Query } from "@nestjs/common";
import { CLAssessmentService } from "../assessment/assessment.service";
import { CLParticipantService } from "../participant/participant.service";
import { CourseLicenseUtilizationRowDto } from "../learning-group/dto";
import { CLLearningGroupService } from "../learning-group/learning-group.service";

/**
 * Unified Reports Controller
 *
 * All reports follow the pattern: GET /api/client/reports/{report-name}
 *
 * This makes it easy to add new reports in the future - just add a new route handler.
 */
@Controller("api/client/reports")
export class CLReportsController {
  constructor(
    private readonly assessmentService: CLAssessmentService,
    private readonly participantService: CLParticipantService,
    private readonly learningGroupService: CLLearningGroupService,
  ) {}

  /**
   * Get participant roster report
   * GET /api/client/reports/participant-roster
   */
  @HttpCode(HttpStatus.OK)
  @Get("participant-roster")
  async getParticipantRosterReport(
    @ClientAuth() auth: CLAuthData,
    @Query("status") status?: string,
    @Query("participantGroup") participantGroup?: string,
    @Query("sq") sq?: string,
    @Query("period") period?: string,
  ) {
    const result = await this.participantService.getFilteredParticipants(
      auth.companyId,
      1,
      1000, // Get up to 1000 participants for the report
      sq,
      status,
      participantGroup,
      auth.participantId,
      auth.role,
    );

    // Explicitly return the data array - CLParticipantListResponse has a 'data' property
    if (result && result.data && Array.isArray(result.data)) {
      // Ensure each item has required fields
      const validData = result.data.filter((item: any) => {
        return item && (item.id || item.participant_id) && (item.full_name || (item.first_name || item.last_name));
      });
      return validData;
    }
    // Fallback: if result is already an array, return it
    if (Array.isArray(result)) {
      return result;
    }
    // If no data, return empty array
    return [];
  }

  /**
   * Get pre-BAT analysis (placeholder participant list)
   * GET /api/client/reports/pre-bat-analysis
   *
   * NOTE:
   *  - Currently reuses participant list data as a placeholder,
   *    so the frontend can be wired end-to-end.
   *  - Replace with real pre-BAT aggregation logic when ready.
   */
  @HttpCode(HttpStatus.OK)
  @Get("pre-bat-analysis")
  async getPreBatAnalysis(@ClientAuth() auth: CLAuthData) {
    return this.participantService.getFilteredParticipants(
      auth.companyId,
      1,
      100, // TODO: adjust pagination/filters for real pre-BAT report
      undefined,
      undefined,
      undefined,
      auth.participantId,
      auth.role,
    );
  }

  /**
   * Get post-BAT analysis (placeholder participant list)
   * GET /api/client/reports/post-bat-analysis
   *
   * NOTE:
   *  - Currently reuses participant list data as a placeholder,
   *    so the frontend can be wired end-to-end.
   *  - Replace with real post-BAT aggregation logic when ready.
   */
  @HttpCode(HttpStatus.OK)
  @Get("post-bat-analysis")
  async getPostBatAnalysis(@ClientAuth() auth: CLAuthData) {
    return this.participantService.getFilteredParticipants(
      auth.companyId,
      1,
      100, // TODO: adjust pagination/filters for real post-BAT report
      undefined,
      undefined,
      undefined,
      auth.participantId,
      auth.role,
    );
  }

  /**
   * Get course license utilization report
   * GET /api/client/reports/course-license-utilization
   */
  @HttpCode(HttpStatus.OK)
  @Get("course-license-utilization")
  async getCourseLicenseUtilizationReport(
    @ClientAuth() auth: CLAuthData,
    @Query("course") course?: string,
    @Query("learningGroup") learningGroup?: string,
    @Query("period") period?: string,
    @Query("utilizationStatus") utilizationStatus?: string,
  ): Promise<CourseLicenseUtilizationRowDto[]> {
    return this.learningGroupService.getCourseLicenseUtilization(auth.companyId, {
      course,
      learningGroup,
      period,
      utilizationStatus,
    });
  }

  /**
   * Get assessment completion report
   * GET /api/client/reports/assessment-completion
   */
  @HttpCode(HttpStatus.OK)
  @Get("assessment-completion")
  async getAssessmentCompletionReport(
    @ClientAuth() auth: CLAuthData,
    @Query("assessmentType") assessmentType?: string,
    @Query("completionStatus") completionStatus?: string,
    @Query("period") period?: string,
    @Query("course") course?: string,
    @Query("learningGroup") learningGroup?: string,
    @Query("search") search?: string,
  ) {
    return this.assessmentService.getAssessmentCompletionReport(auth.participantId, auth.companyId, {
      assessmentType,
      completionStatus,
      period,
      course,
      learningGroup,
      search,
    });
  }

  /**
   * Get standard individual performance report
   * GET /api/client/reports/standard-individual-performance
   */
  @HttpCode(HttpStatus.OK)
  @Get("standard-individual-performance")
  async getStandardIndividualPerformanceReport(
    @ClientAuth() auth: CLAuthData,
    @Query("accountType") accountType?: string,
    @Query("course") course?: string,
    @Query("stage") stage?: string,
    @Query("performanceLevel") performanceLevel?: string,
    @Query("lastActivePeriod") lastActivePeriod?: string,
    @Query("search") search?: string,
  ) {
    return this.assessmentService.getStandardIndividualPerformanceReport(auth.companyId, {
      accountType,
      course,
      stage,
      performanceLevel,
      lastActivePeriod,
      search,
    });
  }

  /**
   * Get advanced individual performance report
   * GET /api/client/reports/advanced-individual-performance
   */
  @HttpCode(HttpStatus.OK)
  @Get("advanced-individual-performance")
  async getAdvancedIndividualPerformanceReport(
    @ClientAuth() auth: CLAuthData,
    @Query("accountType") accountType?: string,
    @Query("course") course?: string,
    @Query("stage") stage?: string,
    @Query("performanceLevel") performanceLevel?: string,
    @Query("lastActivePeriod") lastActivePeriod?: string,
    @Query("search") search?: string,
  ) {
    // Get base data (this method doesn't accept filters yet)
    const result = await this.assessmentService.getAdvancedIndividualPerformance(auth.companyId);

    // Apply filters manually
    let filtered = result;

    if (course && course !== "all") {
      filtered = filtered.filter((item) => String(item.courseId) === course);
    }

    if (search) {
      const searchLower = search.toLowerCase();
      filtered = filtered.filter(
        (item) =>
          item.participantName.toLowerCase().includes(searchLower) ||
          (item.learningGroup && item.learningGroup.toLowerCase().includes(searchLower)) ||
          item.courseTitle.toLowerCase().includes(searchLower),
      );
    }

    // Note: accountType, stage, performanceLevel, and lastActivePeriod filters
    // would require additional data from participants table, so they're not applied here
    // but can be added if needed

    return filtered;
  }

  /**
   * Get standard group performance report
   * GET /api/client/reports/standard-group-performance
   */
  @HttpCode(HttpStatus.OK)
  @Get("standard-group-performance")
  async getStandardGroupPerformanceReport(
    @ClientAuth() auth: CLAuthData,
    @Query("group") group?: string,
    @Query("learningGroup") learningGroup?: string,
    @Query("course") course?: string,
    @Query("period") period?: string,
    @Query("status") status?: string,
  ) {
    return this.assessmentService.getStandardGroupPerformanceReport(auth.companyId, {
      group,
      learningGroup,
      course,
      period,
      status,
    });
  }

  /**
   * Get advanced group performance report
   * GET /api/client/reports/advanced-group-performance
   */
  @HttpCode(HttpStatus.OK)
  @Get("advanced-group-performance")
  async getAdvancedGroupPerformanceReport(
    @ClientAuth() auth: CLAuthData,
    @Query("group") group?: string,
    @Query("learningGroup") learningGroup?: string,
    @Query("course") course?: string,
    @Query("period") period?: string,
    @Query("status") status?: string,
  ) {
    return this.assessmentService.getAdvancedGroupPerformanceReport(auth.companyId, {
      group,
      learningGroup,
      course,
      period,
      status,
    });
  }

  /**
   * Get behavioural assessment analysis report
   * GET /api/client/reports/behavioural-assessment-analysis
   */
  @HttpCode(HttpStatus.OK)
  @Get("behavioural-assessment-analysis")
  async getBehaviouralAssessmentAnalysisReport(
    @ClientAuth() auth: CLAuthData,
    @Query("group") group?: string,
    @Query("assessmentType") assessmentType?: string,
    @Query("course") course?: string,
    @Query("scoreRange") scoreRange?: string,
    @Query("period") period?: string,
    @Query("assessmentPeriod") assessmentPeriod?: string,
  ) {
    return this.assessmentService.getBehaviouralAssessmentAnalysisReport(auth.companyId, {
      group,
      assessmentType,
      course,
      scoreRange,
      period,
      assessmentPeriod,
    });
  }

  /**
   * Get training impact report
   * GET /api/client/reports/training-impact
   */
  @HttpCode(HttpStatus.OK)
  @Get("training-impact")
  async getTrainingImpactReport(
    @ClientAuth() auth: CLAuthData,
    @Query("course") course?: string,
    @Query("accountType") accountType?: string,
    @Query("period") period?: string,
    @Query("impactLevel") impactLevel?: string,
    @Query("learningGroup") learningGroup?: string,
  ) {
    return this.assessmentService.getTrainingImpactReport(auth.companyId, {
      course,
      accountType,
      period,
      impactLevel,
      learningGroup,
    });
  }
}

results matching ""

    No results matching ""