Skip to content

Commit

Permalink
feat(j-s): send criminal records to public prosecutor static email (#…
Browse files Browse the repository at this point in the history
…17406)

* feat(j-s): add criminal record files uploaded when submiting case to public prosecutor

* chroe(j-s): add tests for criminal record notification

* chore(j-s): add parameter for email secret in all env and adjust email assignment logic

* chore: charts update dirty files

* fix(j-s): clean-up

* fix(j-s): format

* fix(j-s): Remove unused import

---------

Co-authored-by: andes-it <[email protected]>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 7, 2025
1 parent 7f6cb5f commit fd4a86b
Show file tree
Hide file tree
Showing 15 changed files with 215 additions and 18 deletions.
2 changes: 2 additions & 0 deletions apps/judicial-system/backend/infra/judicial-system-backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ export const serviceSetup = (): ServiceBuilder<'judicial-system-backend'> =>
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL',
PRISON_ADMIN_INDICTMENT_EMAILS:
'/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS',
PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL:
'/k8s/judicial-system/PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL',
AUTH_JWT_SECRET: '/k8s/judicial-system/AUTH_JWT_SECRET',
ADMIN_USERS: '/k8s/judicial-system/ADMIN_USERS',
BACKEND_ACCESS_TOKEN: '/k8s/judicial-system/BACKEND_ACCESS_TOKEN',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,11 @@ export const notifications = {
defaultMessage: 'Landsréttur',
description: 'Nafn á Landsrétti í tölvupóstum',
},
publicProsecutorCriminalRecords: {
id: 'judicial.system.backend:notifications.email_names.public_prosecutor_criminal_records',
defaultMessage: 'Ritari sakaskrár',
description: 'Nafn á ritara sakaskrá í tölvupóstum',
},
}),
COAJudgeAssigned: defineMessages({
subject: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export const notificationModuleConfig = defineConfig({
'PRISON_ADMIN_INDICTMENT_EMAILS',
'',
),
publicProsecutorCriminalRecordsEmail: env.required(
'PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL',
'',
),
courtsEmails: env.requiredJSON('COURTS_EMAILS', {}) as {
[key: string]: string
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import {
Injectable,
InternalServerErrorException,
} from '@nestjs/common'
import { ConfigType } from '@nestjs/config'

import { type Logger, LOGGER_PROVIDER } from '@island.is/logging'

import { MessageService, MessageType } from '@island.is/judicial-system/message'
import {
CaseFileCategory,
EventNotificationType,
IndictmentCaseNotificationType,
InstitutionNotificationType,
Expand Down Expand Up @@ -71,15 +71,28 @@ export class NotificationDispatchService {
private async dispatchIndictmentSentToPublicProsecutorNotifications(
theCase: Case,
): Promise<void> {
return this.messageService.sendMessagesToQueue([
const messages = [
{
type: MessageType.INDICTMENT_CASE_NOTIFICATION,
caseId: theCase.id,
body: {
type: IndictmentCaseNotificationType.INDICTMENT_VERDICT_INFO,
},
},
])
]
const hasCriminalRecordFiles = theCase.caseFiles?.some(
(file) => file.category === CaseFileCategory.CRIMINAL_RECORD_UPDATE,
)
if (hasCriminalRecordFiles) {
messages.push({
type: MessageType.INDICTMENT_CASE_NOTIFICATION,
caseId: theCase.id,
body: {
type: IndictmentCaseNotificationType.CRIMINAL_RECORD_FILES_UPLOADED,
},
})
}
return this.messageService.sendMessagesToQueue(messages)
}

async dispatchEventNotification(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import { EmailService } from '@island.is/email-service'
import { type Logger, LOGGER_PROVIDER } from '@island.is/logging'
import { type ConfigType } from '@island.is/nest/config'

import { ROUTE_HANDLER_ROUTE } from '@island.is/judicial-system/consts'
import {
CaseIndictmentRulingDecision,
IndictmentCaseNotificationType,
IndictmentDecision,
} from '@island.is/judicial-system/types'

import { notifications } from '../../../../messages'
import { Case } from '../../../case'
import { EventService } from '../../../event'
import { BaseNotificationService } from '../../baseNotification.service'
Expand Down Expand Up @@ -124,13 +125,51 @@ export class IndictmentCaseNotificationService extends BaseNotificationService {
)
}

private async sendCriminalRecordFilesUploadedNotification(
theCase: Case,
): Promise<DeliverResponse> {
const formattedSubject = this.formatMessage(
strings.criminalRecordFilesUploadedEmail.subject,
{
courtCaseNumber: theCase.courtCaseNumber,
},
)

const formattedBody = this.formatMessage(
strings.criminalRecordFilesUploadedEmail.body,
{
courtCaseNumber: theCase.courtCaseNumber,
courtName: theCase.court?.name.replace('dómur', 'dómi'),
linkStart: `<a href="${this.config.clientUrl}${ROUTE_HANDLER_ROUTE}/${theCase.id}">`,
linkEnd: '</a>',
},
)

return this.sendEmails(
theCase,
IndictmentCaseNotificationType.CRIMINAL_RECORD_FILES_UPLOADED,
formattedSubject,
formattedBody,
[
{
name: this.formatMessage(
notifications.emailNames.publicProsecutorCriminalRecords,
),
email: this.config.email.publicProsecutorCriminalRecordsEmail,
},
],
)
}

private sendNotification(
notificationType: IndictmentCaseNotificationType,
theCase: Case,
): Promise<DeliverResponse> {
switch (notificationType) {
case IndictmentCaseNotificationType.INDICTMENT_VERDICT_INFO:
return this.sendVerdictInfoNotification(theCase)
case IndictmentCaseNotificationType.CRIMINAL_RECORD_FILES_UPLOADED:
return this.sendCriminalRecordFilesUploadedNotification(theCase)

default:
throw new InternalServerErrorException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,19 @@ export const strings = {
'Notað sem body í tilkynningu um stöðu birtingar dóms í lokinni ákæru',
},
}),
criminalRecordFilesUploadedEmail: defineMessages({
subject: {
id: 'judicial.system.backend:notifications.criminal_record_files_uploaded_email.subject',
defaultMessage: 'Tilkynning til sakaskrár í máli {courtCaseNumber}',
description:
'Fyrirsögn í pósti til ritara sakaskrá þegar skjal fyrir tilkynningu til skakaskrár er hlaðið upp',
},
body: {
id: 'judicial.system.backend:notifications.criminal_record_files_uploaded_email.body',
defaultMessage:
'Máli {courtCaseNumber} hjá {courtName} hefur verið lokið. Skjöl málsins eru aðgengileg á {linkStart}yfirlitssíðu málsins í Réttarvörslugátt{linkEnd}',
description:
'Texti í pósti til ritara sakaskrá þegar skjal fyrir tilkynningu til skakaskrár er hlaðið upp',
},
}),
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@ import { uuid } from 'uuidv4'

import { MessageService, MessageType } from '@island.is/judicial-system/message'
import {
CaseFileCategory,
EventNotificationType,
IndictmentCaseNotificationType,
} from '@island.is/judicial-system/types'

import { createTestingNotificationModule } from '../../createTestingNotificationModule'

import { Case } from '../../../../case'
import { CaseFile } from '../../../../file'
import { InternalNotificationController } from '../../../internalNotification.controller'

describe('InternalNotificationController - Dispatch event notifications', () => {
const theCase = { id: uuid() } as Case
const theCase = {
id: uuid(),
caseFiles: [
{
category: CaseFileCategory.CRIMINAL_RECORD_UPDATE,
},
] as CaseFile[],
} as Case

let mockMessageService: MessageService
let internalNotificationController: InternalNotificationController

Expand All @@ -32,33 +42,42 @@ describe('InternalNotificationController - Dispatch event notifications', () =>
{
notificationType:
EventNotificationType.INDICTMENT_SENT_TO_PUBLIC_PROSECUTOR,
expectedMessage: {
type: MessageType.INDICTMENT_CASE_NOTIFICATION,
caseId: theCase.id,
body: {
type: IndictmentCaseNotificationType.INDICTMENT_VERDICT_INFO,
expectedMessages: [
{
type: MessageType.INDICTMENT_CASE_NOTIFICATION,
caseId: theCase.id,
body: {
type: IndictmentCaseNotificationType.INDICTMENT_VERDICT_INFO,
},
},
},
{
type: MessageType.INDICTMENT_CASE_NOTIFICATION,
caseId: theCase.id,
body: {
type: IndictmentCaseNotificationType.CRIMINAL_RECORD_FILES_UPLOADED,
},
},
],
},
]

it.each(
notificationScenarios.map(({ notificationType, expectedMessage }) => ({
notificationScenarios.map(({ notificationType, expectedMessages }) => ({
notificationType,
expectedMessage,
description: `should send message to queue for notification type ${notificationType}`,
expectedMessages,
description: `should send messages to queue for notification type ${notificationType}`,
})),
)('$description', async ({ notificationType, expectedMessage }) => {
)('$description', async ({ notificationType, expectedMessages }) => {
const result =
await internalNotificationController.dispatchEventNotification(
theCase.id,
theCase,
{ type: notificationType },
)

expect(mockMessageService.sendMessagesToQueue).toHaveBeenCalledWith([
expectedMessage,
])
expect(mockMessageService.sendMessagesToQueue).toHaveBeenCalledWith(
expectedMessages,
)
expect(result).toEqual({ delivered: true })
})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { uuid } from 'uuidv4'

import { EmailService } from '@island.is/email-service'
import { ConfigType } from '@island.is/nest/config'

import { IndictmentCaseNotificationType } from '@island.is/judicial-system/types'

import { createTestingNotificationModule } from '../../createTestingNotificationModule'

import { Case } from '../../../../case'
import { DeliverResponse } from '../../../models/deliver.response'
import { notificationModuleConfig } from '../../../notification.config'

interface Then {
result: DeliverResponse
error: Error
}

type GivenWhenThen = (
theCase: Case,
notificationType: IndictmentCaseNotificationType,
) => Promise<Then>

describe('IndictmentCaseService', () => {
const caseId = uuid()
const courtName = uuid()

const courtCaseNumber = uuid()
const theCase = {
id: caseId,
court: { name: courtName },
courtCaseNumber,
} as Case

let mockEmailService: EmailService
let mockConfig: ConfigType<typeof notificationModuleConfig>
let givenWhenThen: GivenWhenThen

beforeEach(async () => {
process.env.PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL =
'[email protected]'

const {
emailService,
notificationConfig,
indictmentCaseNotificationService,
} = await createTestingNotificationModule()

mockEmailService = emailService
mockConfig = notificationConfig

givenWhenThen = async (
theCase: Case,
notificationType: IndictmentCaseNotificationType,
) => {
const then = {} as Then

await indictmentCaseNotificationService
.sendIndictmentCaseNotification(notificationType, theCase)
.then((result) => (then.result = result))
.catch((error) => (then.error = error))

return then
}
})

describe('notification sent to public prosecutor criminal records secretary', () => {
it('should send notification', async () => {
const then = await givenWhenThen(
theCase,
IndictmentCaseNotificationType.CRIMINAL_RECORD_FILES_UPLOADED,
)

expect(mockEmailService.sendEmail).toBeCalledWith(
expect.objectContaining({
to: [
{
name: 'Ritari sakaskrár',
address: mockConfig.email.publicProsecutorCriminalRecordsEmail,
},
],
subject: expect.stringContaining(
`Tilkynning til sakaskrár í máli ${courtCaseNumber}`,
),
html: expect.stringContaining(
`Máli ${courtCaseNumber} hjá ${courtName} hefur verið lokið.`,
),
}),
)
expect(then.result).toEqual({ delivered: true })
})
})
})
1 change: 1 addition & 0 deletions charts/judicial-system/values.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ judicial-system-backend:
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL: '/k8s/judicial-system/PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
XROAD_CLIENT_PEM: '/k8s/judicial-system/XROAD_CLIENT_PEM'
Expand Down
1 change: 1 addition & 0 deletions charts/judicial-system/values.prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ judicial-system-backend:
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL: '/k8s/judicial-system/PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
XROAD_CLIENT_PEM: '/k8s/judicial-system/XROAD_CLIENT_PEM'
Expand Down
1 change: 1 addition & 0 deletions charts/judicial-system/values.staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ judicial-system-backend:
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL: '/k8s/judicial-system/PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
XROAD_CLIENT_PEM: '/k8s/judicial-system/XROAD_CLIENT_PEM'
Expand Down
1 change: 1 addition & 0 deletions charts/services/judicial-system-backend/values.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ secrets:
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL: '/k8s/judicial-system/PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
XROAD_CLIENT_PEM: '/k8s/judicial-system/XROAD_CLIENT_PEM'
Expand Down
1 change: 1 addition & 0 deletions charts/services/judicial-system-backend/values.prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ secrets:
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL: '/k8s/judicial-system/PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
XROAD_CLIENT_PEM: '/k8s/judicial-system/XROAD_CLIENT_PEM'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ secrets:
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL: '/k8s/judicial-system/PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
XROAD_CLIENT_PEM: '/k8s/judicial-system/XROAD_CLIENT_PEM'
Expand Down
1 change: 1 addition & 0 deletions libs/judicial-system/types/src/lib/notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export enum CaseNotificationType {

export enum IndictmentCaseNotificationType {
INDICTMENT_VERDICT_INFO = 'INDICTMENT_VERDICT_INFO',
CRIMINAL_RECORD_FILES_UPLOADED = 'CRIMINAL_RECORD_FILES_UPLOADED',
}

export enum DefendantNotificationType {
Expand Down

0 comments on commit fd4a86b

Please sign in to comment.