File

apps/recallassess/recallassess-api/src/api/client/participant-group/participant-group.service.ts

Index

Methods

Constructor

constructor(prisma: BNestPrismaService)
Parameters :
Name Type Optional
prisma BNestPrismaService No

Methods

Async createGroup
createGroup(data: AddParticipantGroupDto, companyId: number, participantId: number)

Create a new participant group

Parameters :
Name Type Optional Description
data AddParticipantGroupDto No

Participant group data

companyId number No

Company ID from context

participantId number No

Participant ID from context (who created it)

Created participant group

Async deleteGroup
deleteGroup(id: number, companyId: number)

Delete a participant group

Parameters :
Name Type Optional Description
id number No

Participant group ID

companyId number No

Company ID to ensure group belongs to the company

Returns : Promise<void>
Private enrichGroupData
enrichGroupData(group: Record<string | unknown>)

Enrich participant group data with additional fields for frontend

Parameters :
Name Type Optional Description
group Record<string | unknown> No

Database participant group object

Enriched participant group DTO

Async getFilteredGroups
getFilteredGroups(sq?: string, companyId?: number)

Get filtered participant groups for client consumption

Parameters :
Name Type Optional Description
sq string Yes
  • Search query to filter by name or description
companyId number Yes
  • Company ID to filter groups by (required)

Array of filtered participant groups

Async getGroupById
getGroupById(id: number, companyId: number)

Get a single participant group by ID

Parameters :
Name Type Optional Description
id number No

Participant group ID

companyId number No

Company ID to ensure group belongs to the company

Enriched participant group data

Async updateGroup
updateGroup(id: number, data: UpdateParticipantGroupDto, companyId: number)

Update a participant group

Parameters :
Name Type Optional Description
id number No

Participant group ID

data UpdateParticipantGroupDto No

Updated participant group data

companyId number No

Company ID to ensure group belongs to the company

Updated participant group

import { bnestPlainToDto } from "@bish-nest/core";
import { BNestPrismaService } from "@bish-nest/core/services";
import { Injectable, NotFoundException } from "@nestjs/common";
import { AddParticipantGroupDto, CLParticipantGroupDto, UpdateParticipantGroupDto } from "./dto";

@Injectable()
export class CLParticipantGroupService {
  constructor(private prisma: BNestPrismaService) {}

  /**
   * Get filtered participant groups for client consumption
   * @param sq - Search query to filter by name or description
   * @param companyId - Company ID to filter groups by (required)
   * @returns Array of filtered participant groups
   */
  async getFilteredGroups(sq?: string, companyId?: number): Promise<CLParticipantGroupDto[]> {
    // Build where clause based on filters
    const where: Record<string, unknown> = {};

    // Always filter by company_id - groups belong to a specific company
    if (companyId) {
      where["company_id"] = companyId;
    }

    // Search query filter (name or description)
    if (sq?.trim()) {
      where["OR"] = [
        { name: { contains: sq, mode: "insensitive" } },
        { description: { contains: sq, mode: "insensitive" } },
      ];
    }

    // Fetch participant groups from database
    const groups = await this.prisma.client.participantGroup.findMany({
      where,
      orderBy: [
        { created_at: "desc" }, // Newest first
      ],
    });

    // Transform database groups to client-facing format
    return groups.map((group) => this.enrichGroupData(group));
  }

  /**
   * Get a single participant group by ID
   * @param id Participant group ID
   * @param companyId Company ID to ensure group belongs to the company
   * @returns Enriched participant group data
   */
  async getGroupById(id: number, companyId: number): Promise<CLParticipantGroupDto | null> {
    const group = await this.prisma.client.participantGroup.findFirst({
      where: {
        id,
        company_id: companyId, // Ensure group belongs to the company
      },
    });

    if (!group) {
      return null;
    }

    return this.enrichGroupData(group);
  }

  /**
   * Create a new participant group
   * @param data Participant group data
   * @param companyId Company ID from context
   * @param participantId Participant ID from context (who created it)
   * @returns Created participant group
   */
  async createGroup(
    data: AddParticipantGroupDto,
    companyId: number,
    participantId: number,
  ): Promise<CLParticipantGroupDto> {
    const group = await this.prisma.client.participantGroup.create({
      data: {
        company_id: companyId,
        participant_id_created_by: participantId,
        name: data.name.trim(),
        description: data.description?.trim() || null,
        color_code: data.color_code?.trim() || null,
        participant_count: 0,
      },
    });

    return this.enrichGroupData(group);
  }

  /**
   * Update a participant group
   * @param id Participant group ID
   * @param data Updated participant group data
   * @param companyId Company ID to ensure group belongs to the company
   * @returns Updated participant group
   */
  async updateGroup(
    id: number,
    data: UpdateParticipantGroupDto,
    companyId: number,
  ): Promise<CLParticipantGroupDto | null> {
    // First verify the group belongs to the company
    const existingGroup = await this.prisma.client.participantGroup.findFirst({
      where: {
        id,
        company_id: companyId,
      },
    });

    if (!existingGroup) {
      return null;
    }

    const group = await this.prisma.client.participantGroup.update({
      where: { id },
      data: {
        ...(data.name && { name: data.name.trim() }),
        ...(data.description !== undefined && { description: data.description?.trim() || null }),
        ...(data.color_code !== undefined && { color_code: data.color_code?.trim() || null }),
      },
    });

    return this.enrichGroupData(group);
  }

  /**
   * Delete a participant group
   * @param id Participant group ID
   * @param companyId Company ID to ensure group belongs to the company
   */
  async deleteGroup(id: number, companyId: number): Promise<void> {
    // First verify the group belongs to the company
    const existingGroup = await this.prisma.client.participantGroup.findFirst({
      where: {
        id,
        company_id: companyId,
      },
    });

    if (!existingGroup) {
      throw new NotFoundException(
        `Participant group with ID ${id} not found or does not belong to company ${companyId}`,
      );
    }

    await this.prisma.client.participantGroup.delete({
      where: { id },
    });
  }

  /**
   * Enrich participant group data with additional fields for frontend
   * @param group Database participant group object
   * @returns Enriched participant group DTO
   */
  private enrichGroupData(group: Record<string, unknown>): CLParticipantGroupDto {
    const rawLast = group["last_activity"];
    let last_activity: string | null;
    if (rawLast && typeof rawLast === "object" && rawLast !== null && "toISOString" in rawLast) {
      last_activity = (rawLast as Date).toISOString();
    } else if (!rawLast) {
      last_activity = null;
    } else {
      last_activity = rawLast as string;
    }

    return bnestPlainToDto({ ...group, last_activity }, CLParticipantGroupDto);
  }
}

results matching ""

    No results matching ""