diff --git a/apps/judicial-system/backend/src/app/modules/case/internalCase.controller.ts b/apps/judicial-system/backend/src/app/modules/case/internalCase.controller.ts index 2b03c85cdb96..0a7dce8d89b7 100644 --- a/apps/judicial-system/backend/src/app/modules/case/internalCase.controller.ts +++ b/apps/judicial-system/backend/src/app/modules/case/internalCase.controller.ts @@ -178,31 +178,6 @@ export class InternalCaseController { ) } - @UseGuards(CaseExistsGuard, new CaseTypeGuard(indictmentCases)) - @Post( - `case/:caseId/${ - messageEndpoint[MessageType.DELIVERY_TO_COURT_INDICTMENT_DEFENDER] - }`, - ) - @ApiOkResponse({ - type: DeliverResponse, - description: 'Delivers indictment case defender info to court', - }) - deliverIndictmentDefenderInfoToCourt( - @Param('caseId') caseId: string, - @CurrentCase() theCase: Case, - @Body() deliverDto: DeliverDto, - ): Promise { - this.logger.debug( - `Delivering the indictment defender info for case ${caseId} to court`, - ) - - return this.internalCaseService.deliverIndictmentDefenderInfoToCourt( - theCase, - deliverDto.user, - ) - } - @UseGuards(CaseExistsGuard, new CaseTypeGuard(indictmentCases)) @Post( `case/:caseId/${ diff --git a/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts b/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts index 94b5abaa4750..7b0896f219a7 100644 --- a/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts +++ b/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts @@ -617,29 +617,6 @@ export class InternalCaseService { }) } - async deliverIndictmentDefenderInfoToCourt( - theCase: Case, - user: TUser, - ): Promise { - return this.courtService - .updateIndictmentCaseWithDefenderInfo( - user, - theCase.id, - theCase.court?.name, - theCase.courtCaseNumber, - theCase.defendants, - ) - .then(() => ({ delivered: true })) - .catch((reason) => { - this.logger.error( - `Failed to update indictment case ${theCase.id} with defender info`, - { reason }, - ) - - return { delivered: false } - }) - } - async deliverIndictmentAssignedRolesToCourt( theCase: Case, user: TUser, diff --git a/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverIndictmentDefenderInfoToCourtGuards.spec.ts b/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverIndictmentDefenderInfoToCourtGuards.spec.ts deleted file mode 100644 index 4fa794094133..000000000000 --- a/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverIndictmentDefenderInfoToCourtGuards.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { CanActivate } from '@nestjs/common' - -import { indictmentCases } from '@island.is/judicial-system/types' - -import { CaseExistsGuard } from '../../guards/caseExists.guard' -import { CaseTypeGuard } from '../../guards/caseType.guard' -import { InternalCaseController } from '../../internalCase.controller' - -describe('InternalCaseController - Deliver indictment defender info to court guards', () => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let guards: any[] - - beforeEach(() => { - guards = Reflect.getMetadata( - '__guards__', - InternalCaseController.prototype.deliverIndictmentDefenderInfoToCourt, - ) - }) - - it('should have two guards', () => { - expect(guards).toHaveLength(2) - }) - - describe('CaseExistsGuard', () => { - let guard: CanActivate - - beforeEach(() => { - guard = new guards[0]() - }) - - it('should have CaseExistsGuard as guard 1', () => { - expect(guard).toBeInstanceOf(CaseExistsGuard) - }) - }) - - describe('CaseTypeGuard', () => { - let guard: CanActivate - - beforeEach(() => { - guard = guards[1] - }) - - it('should have CaseTypeGuard as guard 2', () => { - expect(guard).toBeInstanceOf(CaseTypeGuard) - expect(guard).toEqual({ - allowedCaseTypes: indictmentCases, - }) - }) - }) -}) diff --git a/apps/judicial-system/backend/src/app/modules/court/court.service.ts b/apps/judicial-system/backend/src/app/modules/court/court.service.ts index 3ff75964c054..a0a51c29e7a6 100644 --- a/apps/judicial-system/backend/src/app/modules/court/court.service.ts +++ b/apps/judicial-system/backend/src/app/modules/court/court.service.ts @@ -25,7 +25,6 @@ import { } from '@island.is/judicial-system/types' import { nowFactory } from '../../factories' -import { Defendant } from '../defendant' import { EventService } from '../event' import { RobotLog } from './models/robotLog.model' import { courtModuleConfig } from './court.config' @@ -615,17 +614,17 @@ export class CourtService { caseId: string, courtName?: string, courtCaseNumber?: string, - defendants?: Defendant[], + defendantNationalId?: string, + defenderName?: string, + defenderEmail?: string, ): Promise { try { - const defendantInfo = defendants?.map((defendant) => ({ - nationalId: defendant.nationalId, - defenderName: defendant.defenderName, - defenderEmail: defendant.defenderEmail, - })) - - const subject = `${courtName} - ${courtCaseNumber} - verjanda upplýsingar` - const content = JSON.stringify({ defendants: defendantInfo, courtName }) + const subject = `${courtName} - ${courtCaseNumber} - verjandi varnaraðila` + const content = JSON.stringify({ + nationalId: defendantNationalId, + defenderName, + defenderEmail, + }) return this.sendToRobot( subject, @@ -635,7 +634,7 @@ export class CourtService { ) } catch (error) { this.eventService.postErrorEvent( - 'Failed to update indictment with defender info', + 'Failed to update indictment case with defender info', { caseId, actor: user.name, diff --git a/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts b/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts index 8906b2815629..b266c32f2a76 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts @@ -133,30 +133,42 @@ export class DefendantService { theCase: Case, updatedDefendant: Defendant, oldDefendant: Defendant, + user: User, ): Promise { if (!theCase.courtCaseNumber) { return } - if (updatedDefendant.isDefenderChoiceConfirmed) { + if ( + updatedDefendant.isDefenderChoiceConfirmed && + !oldDefendant.isDefenderChoiceConfirmed + ) { + // Defender choice was just confirmed by the court + const messages: Message[] = [ + { + type: MessageType.DELIVERY_TO_COURT_INDICTMENT_DEFENDER, + user, + caseId: theCase.id, + elementId: updatedDefendant.id, + }, + ] + if ( updatedDefendant.defenderChoice === DefenderChoice.CHOOSE || updatedDefendant.defenderChoice === DefenderChoice.DELEGATE ) { - // TODO: Update defender with robot if needed - // Defender was just confirmed by judge if (!oldDefendant.isDefenderChoiceConfirmed) { - await this.messageService.sendMessagesToQueue([ - { - type: MessageType.DEFENDANT_NOTIFICATION, - caseId: theCase.id, - body: { type: DefendantNotificationType.DEFENDER_ASSIGNED }, - elementId: updatedDefendant.id, - }, - ]) + messages.push({ + type: MessageType.DEFENDANT_NOTIFICATION, + caseId: theCase.id, + body: { type: DefendantNotificationType.DEFENDER_ASSIGNED }, + elementId: updatedDefendant.id, + }) } } + + return this.messageService.sendMessagesToQueue(messages) } } @@ -212,7 +224,7 @@ export class DefendantService { ) } - async updateRequestCase( + async updateRequestCaseDefendant( theCase: Case, defendant: Defendant, update: UpdateDefendantDto, @@ -234,10 +246,11 @@ export class DefendantService { return updatedDefendant } - async updateIndictmentCase( + async updateIndictmentCaseDefendant( theCase: Case, defendant: Defendant, update: UpdateDefendantDto, + user: User, ): Promise { const updatedDefendant = await this.updateDatabaseDefendant( theCase.id, @@ -249,6 +262,7 @@ export class DefendantService { theCase, updatedDefendant, defendant, + user, ) return updatedDefendant @@ -261,9 +275,14 @@ export class DefendantService { user: User, ): Promise { if (isIndictmentCase(theCase.type)) { - return this.updateIndictmentCase(theCase, defendant, update) + return this.updateIndictmentCaseDefendant( + theCase, + defendant, + update, + user, + ) } else { - return this.updateRequestCase(theCase, defendant, update, user) + return this.updateRequestCaseDefendant(theCase, defendant, update, user) } } @@ -429,4 +448,30 @@ export class DefendantService { return { delivered: false } }) } + + async deliverIndictmentDefenderToCourt( + theCase: Case, + defendant: Defendant, + user: User, + ): Promise { + return this.courtService + .updateIndictmentCaseWithDefenderInfo( + user, + theCase.id, + theCase.court?.name, + theCase.courtCaseNumber, + defendant.nationalId, + defendant.defenderName, + defendant.defenderEmail, + ) + .then(() => ({ delivered: true })) + .catch((reason) => { + this.logger.error( + `Failed to update defender info for defendant ${defendant.id} of indictment case ${theCase.id}`, + { reason }, + ) + + return { delivered: false } + }) + } } diff --git a/apps/judicial-system/backend/src/app/modules/defendant/dto/deliverDefendantToCourt.dto.ts b/apps/judicial-system/backend/src/app/modules/defendant/dto/deliver.dto.ts similarity index 85% rename from apps/judicial-system/backend/src/app/modules/defendant/dto/deliverDefendantToCourt.dto.ts rename to apps/judicial-system/backend/src/app/modules/defendant/dto/deliver.dto.ts index 7671fe935ed8..7595952ea24d 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/dto/deliverDefendantToCourt.dto.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/dto/deliver.dto.ts @@ -4,7 +4,7 @@ import { ApiProperty } from '@nestjs/swagger' import type { User } from '@island.is/judicial-system/types' -export class DeliverDefendantToCourtDto { +export class DeliverDto { @IsNotEmpty() @IsObject() @ApiProperty({ type: Object }) diff --git a/apps/judicial-system/backend/src/app/modules/defendant/internalDefendant.controller.ts b/apps/judicial-system/backend/src/app/modules/defendant/internalDefendant.controller.ts index f835ad07b5b1..92511ff786d0 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/internalDefendant.controller.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/internalDefendant.controller.ts @@ -17,10 +17,14 @@ import { messageEndpoint, MessageType, } from '@island.is/judicial-system/message' -import { indictmentCases } from '@island.is/judicial-system/types' +import { + indictmentCases, + investigationCases, + restrictionCases, +} from '@island.is/judicial-system/types' import { Case, CaseExistsGuard, CaseTypeGuard, CurrentCase } from '../case' -import { DeliverDefendantToCourtDto } from './dto/deliverDefendantToCourt.dto' +import { DeliverDto } from './dto/deliver.dto' import { InternalUpdateDefendantDto } from './dto/internalUpdateDefendant.dto' import { CurrentDefendant } from './guards/defendant.decorator' import { DefendantExistsGuard } from './guards/defendantExists.guard' @@ -38,7 +42,10 @@ export class InternalDefendantController { @Inject(LOGGER_PROVIDER) private readonly logger: Logger, ) {} - @UseGuards(DefendantExistsGuard) + @UseGuards( + new CaseTypeGuard([...restrictionCases, ...investigationCases]), + DefendantExistsGuard, + ) @Post( `${messageEndpoint[MessageType.DELIVERY_TO_COURT_DEFENDANT]}/:defendantId`, ) @@ -51,7 +58,7 @@ export class InternalDefendantController { @Param('defendantId') defendantId: string, @CurrentCase() theCase: Case, @CurrentDefendant() defendant: Defendant, - @Body() deliverDefendantToCourtDto: DeliverDefendantToCourtDto, + @Body() deliverDefendantToCourtDto: DeliverDto, ): Promise { this.logger.debug( `Delivering defendant ${defendantId} of case ${caseId} to court`, @@ -85,4 +92,32 @@ export class InternalDefendantController { updatedDefendantChoice, ) } + + @UseGuards(new CaseTypeGuard(indictmentCases), DefendantExistsGuard) + @Post( + `${ + messageEndpoint[MessageType.DELIVERY_TO_COURT_INDICTMENT_DEFENDER] + }/:defendantId`, + ) + @ApiOkResponse({ + type: DeliverResponse, + description: 'Delivers indictment case defender info to court', + }) + deliverIndictmentDefenderToCourt( + @Param('caseId') caseId: string, + @Param('defendantId') defendantId: string, + @CurrentCase() theCase: Case, + @CurrentDefendant() defendant: Defendant, + @Body() deliverDto: DeliverDto, + ): Promise { + this.logger.debug( + `Delivering defender info for defendant ${defendantId} of case ${caseId} to court`, + ) + + return this.defendantService.deliverIndictmentDefenderToCourt( + theCase, + defendant, + deliverDto.user, + ) + } } diff --git a/apps/judicial-system/backend/src/app/modules/defendant/test/defendantController/update.spec.ts b/apps/judicial-system/backend/src/app/modules/defendant/test/defendantController/update.spec.ts index d445408d802a..9b5d893e2bc1 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/test/defendantController/update.spec.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/test/defendantController/update.spec.ts @@ -185,8 +185,14 @@ describe('DefendantController - Update', () => { }) if (shouldSendEmail) { - it('should queue message if defender has been confirmed', () => { + it('should queue messages if defender has been confirmed', () => { expect(mockMessageService.sendMessagesToQueue).toHaveBeenCalledWith([ + { + type: MessageType.DELIVERY_TO_COURT_INDICTMENT_DEFENDER, + user, + caseId, + elementId: defendantId, + }, { type: MessageType.DEFENDANT_NOTIFICATION, caseId, diff --git a/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/deliverDefendantToCourtGuards.spec.ts b/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/deliverDefendantToCourtGuards.spec.ts index 69cc2065dd45..7bd257fe4077 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/deliverDefendantToCourtGuards.spec.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/deliverDefendantToCourtGuards.spec.ts @@ -1,3 +1,9 @@ +import { + investigationCases, + restrictionCases, +} from '@island.is/judicial-system/types' + +import { CaseTypeGuard } from '../../../case' import { DefendantExistsGuard } from '../../guards/defendantExists.guard' import { InternalDefendantController } from '../../internalDefendant.controller' @@ -13,7 +19,11 @@ describe('InternalDefendantController - Deliver defendant to court guards', () = }) it('should have the right guard configuration', () => { - expect(guards).toHaveLength(1) - expect(new guards[0]()).toBeInstanceOf(DefendantExistsGuard) + expect(guards).toHaveLength(2) + expect(guards[0]).toBeInstanceOf(CaseTypeGuard) + expect(guards[0]).toEqual({ + allowedCaseTypes: [...restrictionCases, ...investigationCases], + }) + expect(new guards[1]()).toBeInstanceOf(DefendantExistsGuard) }) }) diff --git a/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverIndictmentDefenderInfoToCourt.spec.ts b/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/deliverIndictmentDefenderToCourt.spec.ts similarity index 56% rename from apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverIndictmentDefenderInfoToCourt.spec.ts rename to apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/deliverIndictmentDefenderToCourt.spec.ts index f60117749089..5aa71689f3cf 100644 --- a/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverIndictmentDefenderInfoToCourt.spec.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/deliverIndictmentDefenderToCourt.spec.ts @@ -2,11 +2,12 @@ import { uuid } from 'uuidv4' import { CaseType, User } from '@island.is/judicial-system/types' -import { createTestingCaseModule } from '../createTestingCaseModule' +import { createTestingDefendantModule } from '../createTestingDefendantModule' +import { Case } from '../../../case' import { CourtService } from '../../../court' import { DeliverDto } from '../../dto/deliver.dto' -import { Case } from '../../models/case.model' +import { Defendant } from '../../models/defendant.model' import { DeliverResponse } from '../../models/deliver.response' interface Then { @@ -16,56 +17,64 @@ interface Then { type GivenWhenThen = ( caseId: string, + defendantId: string, theCase: Case, + defendant: Defendant, body: DeliverDto, ) => Promise -describe('InternalCaseController - Deliver indictment defender info to court', () => { +describe('InternalDefendantController - Deliver indictment defender to court', () => { const user = { id: uuid() } as User const caseId = uuid() + const defendantId = uuid() const courtName = uuid() const courtCaseNumber = uuid() + const defendant = { + id: defendantId, + name: 'Test Ákærði', + nationalId: '1234567890', + defenderNationalId: '1234567899', + defenderName: 'Test Verjandi', + defenderEmail: 'defenderEmail', + } as Defendant const theCase = { id: caseId, type: CaseType.INDICTMENT, court: { name: courtName }, courtCaseNumber, - defendants: [ - { - name: 'Test Ákærði', - nationalId: '1234567890', - defenderNationalId: '1234567899', - defenderName: 'Test Verjandi', - defenderEmail: 'defenderEmail', - }, - { - name: 'Test Ákærði 2', - nationalId: '1234567891', - defenderNationalId: '1234567898', - defenderName: 'Test Verjandi 2', - defenderEmail: 'defenderEmail2', - }, - ], + defendants: [defendant], } as Case let mockCourtService: jest.Mocked let givenWhenThen: GivenWhenThen beforeEach(async () => { - const { courtService, internalCaseController } = - await createTestingCaseModule() + const { courtService, internalDefendantController } = + await createTestingDefendantModule() mockCourtService = courtService as jest.Mocked mockCourtService.updateIndictmentCaseWithDefenderInfo.mockResolvedValue( uuid(), ) - givenWhenThen = async (caseId: string, theCase: Case, body: DeliverDto) => { + givenWhenThen = async ( + caseId: string, + defendantId: string, + theCase: Case, + defendant: Defendant, + body: DeliverDto, + ) => { const then = {} as Then - await internalCaseController - .deliverIndictmentDefenderInfoToCourt(caseId, theCase, body) + await internalDefendantController + .deliverIndictmentDefenderToCourt( + caseId, + defendantId, + theCase, + defendant, + body, + ) .then((result) => (then.result = result)) .catch((error) => (then.error = error)) @@ -74,7 +83,9 @@ describe('InternalCaseController - Deliver indictment defender info to court', ( }) it('should deliver the defender information to court', async () => { - const then = await givenWhenThen(caseId, theCase, { user }) + const then = await givenWhenThen(caseId, defendantId, theCase, defendant, { + user, + }) expect( mockCourtService.updateIndictmentCaseWithDefenderInfo, @@ -83,7 +94,9 @@ describe('InternalCaseController - Deliver indictment defender info to court', ( caseId, courtName, courtCaseNumber, - theCase.defendants, + defendant.nationalId, + defendant.defenderName, + defendant.defenderEmail, ) expect(then.result).toEqual({ delivered: true }) @@ -96,7 +109,9 @@ describe('InternalCaseController - Deliver indictment defender info to court', ( error, ) - const then = await givenWhenThen(caseId, theCase, { user }) + const then = await givenWhenThen(caseId, defendantId, theCase, defendant, { + user, + }) expect(then.result).toEqual({ delivered: false }) }) diff --git a/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/deliverIndictmentDefenderToCourtGuards.spec.ts b/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/deliverIndictmentDefenderToCourtGuards.spec.ts new file mode 100644 index 000000000000..8e61e07902e8 --- /dev/null +++ b/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/deliverIndictmentDefenderToCourtGuards.spec.ts @@ -0,0 +1,26 @@ +import { indictmentCases } from '@island.is/judicial-system/types' + +import { CaseTypeGuard } from '../../../case' +import { DefendantExistsGuard } from '../../guards/defendantExists.guard' +import { InternalDefendantController } from '../../internalDefendant.controller' + +describe('InternalDefendantController - Deliver indictment defender to court guards', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let guards: any[] + + beforeEach(() => { + guards = Reflect.getMetadata( + '__guards__', + InternalDefendantController.prototype.deliverIndictmentDefenderToCourt, + ) + }) + + it('should have the right guard configuration', () => { + expect(guards).toHaveLength(2) + expect(guards[0]).toBeInstanceOf(CaseTypeGuard) + expect(guards[0]).toEqual({ + allowedCaseTypes: indictmentCases, + }) + expect(new guards[1]()).toBeInstanceOf(DefendantExistsGuard) + }) +}) diff --git a/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/internalDefendantControllerGuards.spec.ts b/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/internalDefendantControllerGuards.spec.ts index ae0ad03605fb..ea850b4407f1 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/internalDefendantControllerGuards.spec.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/test/internalDefendantController/internalDefendantControllerGuards.spec.ts @@ -41,16 +41,4 @@ describe('InternalDefendantController - guards', () => { expect(guard).toBeInstanceOf(CaseExistsGuard) }) }) - - describe('Method level guards', () => { - it('should have DefendantExistsGuard on deliverDefendantToCourt method', () => { - const methodGuards = Reflect.getMetadata( - '__guards__', - InternalDefendantController.prototype.deliverDefendantToCourt, - ) - expect(methodGuards).toHaveLength(1) - const guard = new methodGuards[0]() - expect(guard).toBeInstanceOf(DefendantExistsGuard) - }) - }) }) diff --git a/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts b/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts index 5259ec00dcb0..64fc48de8dc9 100644 --- a/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts +++ b/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts @@ -61,9 +61,7 @@ export const include: Includeable[] = [ @Injectable() export class SubpoenaService { constructor( - @InjectConnection() private readonly sequelize: Sequelize, @InjectModel(Subpoena) private readonly subpoenaModel: typeof Subpoena, - @InjectModel(Defendant) private readonly defendantModel: typeof Defendant, private readonly pdfService: PdfService, private readonly messageService: MessageService, @Inject(forwardRef(() => PoliceService))