File

apps/recallassess/recallassess-api/src/api/admin/learning-group/learning-group.controller.ts

Prefix

api/admin/learning-group

Description

LearningGroupController

Admin API — Learning Group (Learning Group). HTTP Endpoints for RecallAssess.

Extends

Index

Methods

Methods

Async downloadPostBatHtml
downloadPostBatHtml(id: number, learningGroupParticipantId: number)
Decorators :
@Get(':id/participant/:learningGroupParticipantId/post-bat-download')
@Header('Content-Type', 'text/html; charset=utf-8')

Download post-BAT HTML for a participant in this learning group (admin). Uses LearningGroupParticipant ID (same as portal flow).

Parameters :
Name Type Optional
id number No
learningGroupParticipantId number No
Returns : Promise<string>
Async downloadPreBatHtml
downloadPreBatHtml(id: number, learningGroupParticipantId: number)
Decorators :
@Get(':id/participant/:learningGroupParticipantId/pre-bat-download')
@Header('Content-Type', 'text/html; charset=utf-8')

Download pre-BAT HTML for a participant in this learning group (admin). Uses LearningGroupParticipant ID (same as portal flow).

Parameters :
Name Type Optional
id number No
learningGroupParticipantId number No
Returns : Promise<string>
Async getPostBatPdfUrl
getPostBatPdfUrl(id: number, learningGroupParticipantId: number, regenerate?: string)
Decorators :
@Get(':id/participant/:learningGroupParticipantId/post-bat-pdf-url')
@HttpCode(HttpStatus.OK)

Get post-BAT PDF download URL for a participant in this learning group (admin).

cached S3 file (admin "Regenerate" action).

Parameters :
Name Type Optional Description
id number No
learningGroupParticipantId number No
regenerate string Yes

When true, force a fresh PDF render instead of reusing the cached S3 file (admin "Regenerate" action).

Returns : Promise<literal type>
Async getPreBatHtml
getPreBatHtml(learningGroupId: string, participantId: string)
Decorators :
@Get(':learningGroupId/participant/:participantId/pre-bat-html')
@Header('Content-Type', 'text/html; charset=utf-8')

Get Pre-BAT report HTML for a participant (admin JWT auth). Used by the admin panel "View Pre-BAT report" to open the report in a new window.

Parameters :
Name Type Optional
learningGroupId string No
participantId string No
Returns : Promise<string>
Async getPreBatPdfUrl
getPreBatPdfUrl(id: number, learningGroupParticipantId: number, regenerate?: string)
Decorators :
@Get(':id/participant/:learningGroupParticipantId/pre-bat-pdf-url')
@HttpCode(HttpStatus.OK)

Get pre-BAT PDF download URL for a participant in this learning group (admin).

cached S3 file (admin "Regenerate" action).

Parameters :
Name Type Optional Description
id number No
learningGroupParticipantId number No
regenerate string Yes

When true, force a fresh PDF render instead of reusing the cached S3 file (admin "Regenerate" action).

Returns : Promise<literal type>
Async regeneratePostBatAnalysis
regeneratePostBatAnalysis(id: number, learningGroupParticipantId: number)
Decorators :
@Post(':id/participant/:learningGroupParticipantId/regenerate-post-bat-analysis')
@HttpCode(HttpStatus.OK)

Regenerate a participant's POST-BAT AI analysis by re-submitting their data to the external CR(AI) API (mirrors the participant portal "Regenerate" action).

Parameters :
Name Type Optional
id number No
learningGroupParticipantId number No
Returns : Promise<literal type>
Async regeneratePreBatAnalysis
regeneratePreBatAnalysis(id: number, learningGroupParticipantId: number)
Decorators :
@Post(':id/participant/:learningGroupParticipantId/regenerate-pre-bat-analysis')
@HttpCode(HttpStatus.OK)

Regenerate a participant's PRE-BAT AI analysis by re-submitting their data to the external CR(AI) API (mirrors the participant portal "Regenerate" action).

Parameters :
Name Type Optional
id number No
learningGroupParticipantId number No
Returns : Promise<literal type>
Async resendInvitation
resendInvitation(id: number, participantId: number)
Decorators :
@Post(':id/resend-invitation/:participantId')
@HttpCode(HttpStatus.OK)

Resend invitation to a specific participant (by participant id). POST /api/admin/learning-group/:id/resend-invitation/:participantId

Parameters :
Name Type Optional
id number No
participantId number No
Returns : Promise<literal type>
Async updateKnowledgeReviewEmailDate
updateKnowledgeReviewEmailDate(learningGroupParticipantId: string)
Decorators :
@Patch('participant/:learningGroupParticipantId/knowledge-review-email-date')
@HttpCode(HttpStatus.OK)

Update knowledge_review_email_date to NOW() for a learning group participant. Mirrors the update-knowledge-review-email-date.sh script.

Parameters :
Name Type Optional
learningGroupParticipantId string No
Returns : unknown
Async updatePostBatInviteEmailDate
updatePostBatInviteEmailDate(learningGroupParticipantId: string)
Decorators :
@Patch('participant/:learningGroupParticipantId/post-bat-invite-email-date')
@HttpCode(HttpStatus.OK)

Send post BAT invite email now and ensure post_bat_email_date is set (and not in the future) for a learning group participant. Used from admin UI "Update" (send now) for post BAT invite.

Parameters :
Name Type Optional
learningGroupParticipantId string No
Returns : unknown
import { BaseController } from "@bish-nest/controller";
import {
  Controller,
  Get,
  Header,
  HttpCode,
  HttpStatus,
  Param,
  ParseIntPipe,
  Patch,
  Post,
  Query,
} from "@nestjs/common";
import { IntegrationService } from "@api/integration/integration.service";
import { LearningGroupService } from "./learning-group.service";

/**
 * LearningGroupController
 *
 * Admin API — Learning Group (Learning Group). HTTP Endpoints for RecallAssess.
 */


@Controller("api/admin/learning-group")
export class LearningGroupController extends BaseController<LearningGroupService> {
  constructor(
    service: LearningGroupService,
    private readonly integrationService: IntegrationService,
  ) {
    super(service);
  }

  /**
   * Get Pre-BAT report HTML for a participant (admin JWT auth).
   * Used by the admin panel "View Pre-BAT report" to open the report in a new window.
   */
  @Get(":learningGroupId/participant/:participantId/pre-bat-html")
  @Header("Content-Type", "text/html; charset=utf-8")
  async getPreBatHtml(
    @Param("learningGroupId") learningGroupId: string,
    @Param("participantId") participantId: string,
  ): Promise<string> {
    return this.integrationService.generatePreBatHtml(
      parseInt(learningGroupId, 10),
      parseInt(participantId, 10),
    );
  }

  /**
   * Download pre-BAT HTML for a participant in this learning group (admin).
   * Uses LearningGroupParticipant ID (same as portal flow).
   */
  @Get(":id/participant/:learningGroupParticipantId/pre-bat-download")
  @Header("Content-Type", "text/html; charset=utf-8")
  async downloadPreBatHtml(
    @Param("id", ParseIntPipe) id: number,
    @Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
  ): Promise<string> {
    return this.entityService.generatePreBatHtmlForParticipant(id, learningGroupParticipantId);
  }

  /**
   * Download post-BAT HTML for a participant in this learning group (admin).
   * Uses LearningGroupParticipant ID (same as portal flow).
   */
  @Get(":id/participant/:learningGroupParticipantId/post-bat-download")
  @Header("Content-Type", "text/html; charset=utf-8")
  async downloadPostBatHtml(
    @Param("id", ParseIntPipe) id: number,
    @Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
  ): Promise<string> {
    return this.entityService.generatePostBatHtmlForParticipant(id, learningGroupParticipantId);
  }

  /**
   * Get pre-BAT PDF download URL for a participant in this learning group (admin).
   *
   * @param regenerate When `true`, force a fresh PDF render instead of reusing the
   *   cached S3 file (admin "Regenerate" action).
   */
  @Get(":id/participant/:learningGroupParticipantId/pre-bat-pdf-url")
  @HttpCode(HttpStatus.OK)
  async getPreBatPdfUrl(
    @Param("id", ParseIntPipe) id: number,
    @Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
    @Query("regenerate") regenerate?: string,
  ): Promise<{ url: string }> {
    const forceRegenerate = regenerate === "1" || regenerate === "true";
    const url = await this.entityService.getPreBatPdfUrlForParticipant(
      id,
      learningGroupParticipantId,
      forceRegenerate,
    );
    return { url };
  }

  /**
   * Get post-BAT PDF download URL for a participant in this learning group (admin).
   *
   * @param regenerate When `true`, force a fresh PDF render instead of reusing the
   *   cached S3 file (admin "Regenerate" action).
   */
  @Get(":id/participant/:learningGroupParticipantId/post-bat-pdf-url")
  @HttpCode(HttpStatus.OK)
  async getPostBatPdfUrl(
    @Param("id", ParseIntPipe) id: number,
    @Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
    @Query("regenerate") regenerate?: string,
  ): Promise<{ url: string }> {
    const forceRegenerate = regenerate === "1" || regenerate === "true";
    const url = await this.entityService.getPostBatPdfUrlForParticipant(
      id,
      learningGroupParticipantId,
      forceRegenerate,
    );
    return { url };
  }

  /**
   * Regenerate a participant's PRE-BAT AI analysis by re-submitting their data to the
   * external CR(AI) API (mirrors the participant portal "Regenerate" action).
   */
  @Post(":id/participant/:learningGroupParticipantId/regenerate-pre-bat-analysis")
  @HttpCode(HttpStatus.OK)
  async regeneratePreBatAnalysis(
    @Param("id", ParseIntPipe) id: number,
    @Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
  ): Promise<{ success: boolean; message: string }> {
    return this.entityService.regeneratePreBatAnalysis(id, learningGroupParticipantId);
  }

  /**
   * Regenerate a participant's POST-BAT AI analysis by re-submitting their data to the
   * external CR(AI) API (mirrors the participant portal "Regenerate" action).
   */
  @Post(":id/participant/:learningGroupParticipantId/regenerate-post-bat-analysis")
  @HttpCode(HttpStatus.OK)
  async regeneratePostBatAnalysis(
    @Param("id", ParseIntPipe) id: number,
    @Param("learningGroupParticipantId", ParseIntPipe) learningGroupParticipantId: number,
  ): Promise<{ success: boolean; message: string }> {
    return this.entityService.regeneratePostBatAnalysis(id, learningGroupParticipantId);
  }

  /**
   * Update knowledge_review_email_date to NOW() for a learning group participant.
   * Mirrors the update-knowledge-review-email-date.sh script.
   */
  @Patch("participant/:learningGroupParticipantId/knowledge-review-email-date")
  @HttpCode(HttpStatus.OK)
  async updateKnowledgeReviewEmailDate(
    @Param("learningGroupParticipantId") learningGroupParticipantId: string,
  ) {
    return this.entityService.updateKnowledgeReviewEmailDate(parseInt(learningGroupParticipantId, 10));
  }

  /**
   * Send post BAT invite email now and ensure post_bat_email_date is set (and not in the future)
   * for a learning group participant. Used from admin UI "Update" (send now) for post BAT invite.
   */
  @Patch("participant/:learningGroupParticipantId/post-bat-invite-email-date")
  @HttpCode(HttpStatus.OK)
  async updatePostBatInviteEmailDate(
    @Param("learningGroupParticipantId") learningGroupParticipantId: string,
  ) {
    return this.entityService.updatePostBatInviteEmailDate(parseInt(learningGroupParticipantId, 10));
  }

  /**
   * Resend invitation to a specific participant (by participant id).
   * POST /api/admin/learning-group/:id/resend-invitation/:participantId
   */
  @Post(":id/resend-invitation/:participantId")
  @HttpCode(HttpStatus.OK)
  async resendInvitation(
    @Param("id", ParseIntPipe) id: number,
    @Param("participantId", ParseIntPipe) participantId: number,
  ): Promise<{ message: string }> {
    return this.entityService.resendInvitation(id, participantId);
  }
}


results matching ""

    No results matching ""