import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { WorkflowStepModel, WorkflowStepsDB } from '../schema/workflow-step.schema'; import { CreateWorkflowStepDto } from '../../dto/create-workflow-step.dto'; import { UpdateWorkflowStepDto } from '../../dto/update-workflow-step.dto'; import { WorkflowStep } from 'src/Types&Enums/blame-request-management/blameWorkflow-steps.enum'; import { ClaimWorkflowStep } from 'src/Types&Enums/claim-request-management/claim-workflow-steps.enum'; // Type alias for combined workflow steps type AnyWorkflowStep = WorkflowStep | ClaimWorkflowStep; @Injectable() export class WorkflowStepDbService { constructor( @InjectModel(WorkflowStepsDB) private readonly workflowStepModel: Model, ) {} /** * Create a new workflow step */ async create(createDto: CreateWorkflowStepDto): Promise { const created = new this.workflowStepModel(createDto); return await created.save(); } /** * Find all active workflow steps */ async findAll(): Promise { return await this.workflowStepModel .find({ isActive: true }) .sort({ stepNumber: 1 }) .exec(); } /** * Find all workflow steps including inactive ones */ async findAllIncludingInactive(): Promise { return await this.workflowStepModel .find() .sort({ stepNumber: 1 }) .exec(); } /** * Find a workflow step by ID */ async findById(id: string): Promise { return await this.workflowStepModel.findById(id).exec(); } /** * Find a workflow step by step key (supports both blame and claim) */ async findByStepKey(stepKey: AnyWorkflowStep): Promise { return await this.workflowStepModel.findOne({ stepKey }).exec(); } /** * Find a workflow step by step number */ async findByStepNumber(stepNumber: number): Promise { return await this.workflowStepModel.findOne({ stepNumber }).exec(); } /** * Find steps by category */ async findByCategory(category: string): Promise { return await this.workflowStepModel .find({ category, isActive: true }) .sort({ stepNumber: 1 }) .exec(); } /** * Update a workflow step by ID */ async update(id: string, updateDto: UpdateWorkflowStepDto): Promise { return await this.workflowStepModel .findByIdAndUpdate(id, updateDto, { new: true }) .exec(); } /** * Update a workflow step by step key (supports both blame and claim) */ async updateByStepKey( stepKey: AnyWorkflowStep, updateDto: UpdateWorkflowStepDto, ): Promise { return await this.workflowStepModel .findOneAndUpdate({ stepKey }, updateDto, { new: true }) .exec(); } /** * Soft delete (deactivate) a workflow step */ async remove(id: string): Promise { return await this.workflowStepModel .findByIdAndUpdate(id, { isActive: false }, { new: true }) .exec(); } /** * Upsert a workflow step by step key (supports both blame and claim) */ async upsertByStepKey( stepKey: AnyWorkflowStep, data: CreateWorkflowStepDto | UpdateWorkflowStepDto, ): Promise { return await this.workflowStepModel .findOneAndUpdate({ stepKey }, data, { upsert: true, new: true }) .exec(); } /** * Bulk upsert workflow steps */ async bulkUpsert(steps: CreateWorkflowStepDto[]): Promise { const bulkOps = steps.map((step) => ({ updateOne: { filter: { stepKey: step.stepKey }, update: { $set: step as any }, upsert: true, }, })); return await this.workflowStepModel.bulkWrite(bulkOps as any); } /** * Get the next step number */ async getNextStepNumber(): Promise { const maxStep = await this.workflowStepModel .findOne() .sort({ stepNumber: -1 }) .select('stepNumber') .exec(); return maxStep ? maxStep.stepNumber + 1 : 1; } /** * Check if a step exists (supports both blame and claim) */ async exists(stepKey: AnyWorkflowStep): Promise { const count = await this.workflowStepModel.countDocuments({ stepKey }).exec(); return count > 0; } }