diff --git a/examples/bri-3/src/bri/workgroup/workflows/agents/workflowsStorage.agent.ts b/examples/bri-3/src/bri/workgroup/workflows/agents/workflowsStorage.agent.ts index 0cc0215db..cef36d259 100644 --- a/examples/bri-3/src/bri/workgroup/workflows/agents/workflowsStorage.agent.ts +++ b/examples/bri-3/src/bri/workgroup/workflows/agents/workflowsStorage.agent.ts @@ -3,13 +3,17 @@ import { InjectMapper } from '@automapper/nestjs'; import { Injectable, NotFoundException } from '@nestjs/common'; import { WORKFLOW_NOT_FOUND_ERR_MESSAGE } from '../api/err.messages'; import { Workflow } from '../models/workflow'; +import { BpiAccount, Workflow as WorkflowModel } from '@prisma/client'; import { PrismaService } from '../../../../shared/prisma/prisma.service'; +import { PrismaPromise } from '@prisma/client'; +import { BpiAccountStorageAgent } from '../../../state/bpiAccounts/agents/bpiAccountsStorage.agent'; @Injectable() export class WorkflowStorageAgent { constructor( @InjectMapper() private mapper: Mapper, private readonly prisma: PrismaService, + private readonly bpiAccountStorageAgent: BpiAccountStorageAgent, ) {} async getWorkflowById(id: string): Promise { @@ -49,14 +53,14 @@ export class WorkflowStorageAgent { }); } - async storeNewWorkflow(workflow: Workflow): Promise { + storeNewWorkflow(workflow: Workflow): PrismaPromise { const workstepIds = workflow.worksteps.map((w) => { return { id: w.id, }; }); - const newWorkflowModel = await this.prisma.workflow.create({ + return this.prisma.workflow.create({ data: { id: workflow.id, name: workflow.name, @@ -71,8 +75,6 @@ export class WorkflowStorageAgent { bpiAccount: true, }, }); - - return this.mapper.map(newWorkflowModel, Workflow, Workflow); } async updateWorkflow(workflow: Workflow): Promise { @@ -104,4 +106,24 @@ export class WorkflowStorageAgent { where: { id: workflow.id }, }); } + + async storeWorkflowTransaction( + bpiAccountCandidate: BpiAccount, + workflowCandidate: Workflow, + ): Promise { + const boundStoreNewWorkflow = this.storeNewWorkflow.bind(this); + const boundStoreNewBpiAccount = + this.bpiAccountStorageAgent.storeNewBpiAccount.bind( + this.bpiAccountStorageAgent, + ); + const results = await this.prisma.executeTransaction(() => { + return boundStoreNewBpiAccount(bpiAccountCandidate).then( + (newBpiAccount: { id: string }) => { + workflowCandidate.bpiAccountId = newBpiAccount.id; + return boundStoreNewWorkflow(workflowCandidate); + }, + ); + }); + return results; + } } diff --git a/examples/bri-3/src/bri/workgroup/workflows/capabilities/createWorkflow/createWorkflowCommand.handler.ts b/examples/bri-3/src/bri/workgroup/workflows/capabilities/createWorkflow/createWorkflowCommand.handler.ts index 1334ec201..e89ecf9d4 100644 --- a/examples/bri-3/src/bri/workgroup/workflows/capabilities/createWorkflow/createWorkflowCommand.handler.ts +++ b/examples/bri-3/src/bri/workgroup/workflows/capabilities/createWorkflow/createWorkflowCommand.handler.ts @@ -1,6 +1,5 @@ import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; import { BpiAccountAgent } from '../../../../state/bpiAccounts/agents/bpiAccounts.agent'; -import { BpiAccountStorageAgent } from '../../../../state/bpiAccounts/agents/bpiAccountsStorage.agent'; import { BpiSubjectAccountAgent } from '../../../../identity/bpiSubjectAccounts/agents/bpiSubjectAccounts.agent'; import { WorkgroupAgent } from '../../../../workgroup/workgroups/agents/workgroups.agent'; import { WorkflowAgent } from '../../agents/workflows.agent'; @@ -17,7 +16,6 @@ export class CreateWorkflowCommandHandler private subjectAccountAgent: BpiSubjectAccountAgent, private workgroupAgent: WorkgroupAgent, private storageAgent: WorkflowStorageAgent, - private accountStorageAgent: BpiAccountStorageAgent, ) {} async execute(command: CreateWorkflowCommand) { @@ -47,21 +45,18 @@ export class CreateWorkflowCommandHandler 'sample state object prover system', ); - const newBpiAccount = await this.accountStorageAgent.storeNewBpiAccount( - newBpiAccountCandidate, - ); - const newWorkflowCandidate = this.agent.createNewWorkflow( command.name, workstepsToConnect, command.workgroupId, - newBpiAccount, + newBpiAccountCandidate, ); - const newWorkflow = await this.storageAgent.storeNewWorkflow( + const results = await this.storageAgent.storeWorkflowTransaction( + newBpiAccountCandidate, newWorkflowCandidate, ); - return newWorkflow.id; + return results; } } diff --git a/examples/bri-3/src/shared/prisma/prisma.service.ts b/examples/bri-3/src/shared/prisma/prisma.service.ts index 83cc7e1c8..3ddeb62d8 100644 --- a/examples/bri-3/src/shared/prisma/prisma.service.ts +++ b/examples/bri-3/src/shared/prisma/prisma.service.ts @@ -1,9 +1,23 @@ import { Injectable } from '@nestjs/common'; -import { PrismaClient } from '@prisma/client'; +import { PrismaClient, PrismaPromise } from '@prisma/client'; + +type DbOperation = () => Promise | PrismaPromise; @Injectable() export class PrismaService extends PrismaClient { constructor() { super({ log: ['info'] }); } + + public async executeTransaction( + ...operations: DbOperation[] + ): Promise { + return await this.$transaction(async () => { + const results: any[] = []; + for (const operation of operations) { + results.push(await operation()); + } + return results; + }); + } }