Skip to content

Commit

Permalink
feat(j-s): Connect case files to defendant or civil claimant
Browse files Browse the repository at this point in the history
  • Loading branch information
unakb committed Nov 27, 2024
1 parent 918943a commit bdeea4f
Show file tree
Hide file tree
Showing 14 changed files with 318 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,19 @@ export class BackendService extends DataSource<{ req: Request }> {
return this.post(`case/${id}/file/url`, createPresignedPost)
}

createCaseFile(id: string, createFile: unknown): Promise<CaseFile> {
return this.post(`case/${id}/file`, createFile)
createCaseFile(
id: string,
createFile: unknown,
defendantId?: string,
civilClaimantId?: string,
): Promise<CaseFile> {
const connectionInjection = defendantId
? `/defendant/${defendantId}`
: civilClaimantId
? `/civilClaimant/${civilClaimantId}`
: ''

return this.post(`case/${id}${connectionInjection}/file`, createFile)
}

getCaseFileSignedUrl(
Expand Down Expand Up @@ -435,8 +446,15 @@ export class BackendService extends DataSource<{ req: Request }> {
limitedAccessCreateCaseFile(
id: string,
createFile: unknown,
civilClaimantId?: string,
): Promise<CaseFile> {
return this.post(`case/${id}/limitedAccess/file`, createFile)
const connectionInjection = civilClaimantId
? `/civilClaimant/${civilClaimantId}`
: ''
return this.post(
`case/${id}/limitedAccess${connectionInjection}/file`,
createFile,
)
}

limitedAccessGetCaseFileSignedUrl(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,14 @@ export class CreateFileInput {
@IsOptional()
@Field(() => String, { nullable: true })
readonly userGeneratedFilename?: string

@Allow()
@IsOptional()
@Field(() => ID, { nullable: true })
readonly defendantId?: string

@Allow()
@IsOptional()
@Field(() => ID, { nullable: true })
readonly civilClaimantId?: string
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,19 @@ export class FileResolver {
@Context('dataSources')
{ backendService }: { backendService: BackendService },
): Promise<CaseFile> {
const { caseId, ...createFile } = input
const { caseId, defendantId, civilClaimantId, ...createFile } = input

this.logger.debug(`Creating a file for case ${caseId}`)

return this.auditTrailService.audit(
user.id,
AuditedAction.CREATE_FILE,
backendService.createCaseFile(caseId, createFile),
backendService.createCaseFile(
caseId,
createFile,
defendantId,
civilClaimantId,
),
(file) => file.id,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,18 @@ export class LimitedAccessFileResolver {
@Context('dataSources')
{ backendService }: { backendService: BackendService },
): Promise<CaseFile> {
const { caseId, ...createFile } = input
const { caseId, civilClaimantId, ...createFile } = input

this.logger.debug(`Creating a file for case ${caseId}`)

return this.auditTrailService.audit(
user.id,
AuditedAction.CREATE_FILE,
backendService.limitedAccessCreateCaseFile(caseId, createFile),
backendService.limitedAccessCreateCaseFile(
caseId,
createFile,
civilClaimantId,
),
(file) => file.id,
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict'

module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction(async (t) => {
await queryInterface.addColumn(
'case_file',
'defendant_id',
{
type: Sequelize.UUID,
references: {
model: 'defendant',
key: 'id',
},
allowNull: true,
},
{ transaction: t },
)
await queryInterface.addColumn(
'case_file',
'civil_claimant_id',
{
type: Sequelize.UUID,
references: {
model: 'civil_claimant',
key: 'id',
},
allowNull: true,
},
{ transaction: t },
)
})
},
down: (queryInterface) => {
return queryInterface.sequelize.transaction(async (t) => {
await queryInterface.removeColumn('case_file', 'civil_claimant_id', {
transaction: t,
})
await queryInterface.removeColumn('case_file', 'defendant_id', {
transaction: t,
})
})
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,21 @@ import {
CurrentCase,
} from '../case'
import { MergedCaseExistsGuard } from '../case/guards/mergedCaseExists.guard'
import {
CivilClaimant,
CivilClaimantExistsGuard,
CurrentCivilClaimant,
CurrentDefendant,
Defendant,
DefendantExistsGuard,
} from '../defendant'
import { CreateFileDto } from './dto/createFile.dto'
import { CreatePresignedPostDto } from './dto/createPresignedPost.dto'
import { UpdateFilesDto } from './dto/updateFile.dto'
import { CurrentCaseFile } from './guards/caseFile.decorator'
import { CaseFileExistsGuard } from './guards/caseFileExists.guard'
import { ViewCaseFileGuard } from './guards/viewCaseFile.guard'
import { WriteCaseFileGuard } from './guards/writeCaseFile.guard'
import { DeleteFileResponse } from './models/deleteFile.response'
import { CaseFile } from './models/file.model'
import { PresignedPost } from './models/presignedPost.model'
Expand Down Expand Up @@ -98,7 +107,7 @@ export class FileController {
return this.fileService.createPresignedPost(theCase, createPresignedPost)
}

@UseGuards(RolesGuard, CaseExistsGuard, CaseWriteGuard)
@UseGuards(RolesGuard, CaseExistsGuard, CaseWriteGuard, WriteCaseFileGuard)
@RolesRules(
prosecutorRule,
prosecutorRepresentativeRule,
Expand Down Expand Up @@ -126,6 +135,68 @@ export class FileController {
return this.fileService.createCaseFile(theCase, createFile, user)
}

@UseGuards(
RolesGuard,
CaseExistsGuard,
DefendantExistsGuard,
CaseWriteGuard,
WriteCaseFileGuard,
)
@RolesRules(publicProsecutorStaffRule)
@Post('defendant/:defendantId/file')
@ApiCreatedResponse({
type: CaseFile,
description: 'Creates a new case file connected to a defendant',
})
async createDefendantCaseFile(
@Param('caseId') caseId: string,
@Param('defendantId') defendantId: string,
@CurrentHttpUser() user: User,
@CurrentCase() theCase: Case,
@CurrentDefendant() defendant: Defendant,
@Body() createFile: CreateFileDto,
): Promise<CaseFile> {
this.logger.debug(
`Creating a file for case ${caseId} for defendant ${defendantId}`,
)

return this.fileService.createCaseFile(theCase, createFile, user, defendant)
}

@UseGuards(
RolesGuard,
CaseExistsGuard,
CivilClaimantExistsGuard,
CaseWriteGuard,
WriteCaseFileGuard,
)
@RolesRules(publicProsecutorStaffRule)
@Post('defendant/:defendantId/file')
@ApiCreatedResponse({
type: CaseFile,
description: 'Creates a new case file connected to a defendant',
})
async createCivilClaimantCaseFile(
@Param('caseId') caseId: string,
@Param('civilClaimantId') civilClaimantId: string,
@CurrentHttpUser() user: User,
@CurrentCase() theCase: Case,
@CurrentCivilClaimant() civilClaimant: CivilClaimant,
@Body() createFile: CreateFileDto,
): Promise<CaseFile> {
this.logger.debug(
`Creating a file for case ${caseId} for civil claimant ${civilClaimantId}`,
)

return this.fileService.createCaseFile(
theCase,
createFile,
user,
undefined,
civilClaimant,
)
}

@UseGuards(
RolesGuard,
CaseExistsGuard,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { createConfirmedPdf } from '../../formatters'
import { AwsS3Service } from '../aws-s3'
import { Case } from '../case'
import { CourtDocumentFolder, CourtService } from '../court'
import { CivilClaimant, Defendant } from '../defendant'
import { UserService } from '../user'
import { CreateFileDto } from './dto/createFile.dto'
import { CreatePresignedPostDto } from './dto/createPresignedPost.dto'
Expand Down Expand Up @@ -339,6 +340,8 @@ export class FileService {
theCase: Case,
createFile: CreateFileDto,
user: User,
defendant?: Defendant,
civilClaimant?: CivilClaimant,
): Promise<CaseFile> {
const { key } = createFile

Expand All @@ -360,6 +363,8 @@ export class FileService {
userGeneratedFilename:
createFile.userGeneratedFilename ?? fileName.replace(/\.pdf$/, ''),
submittedBy: user.name,
defendantId: defendant?.id,
civilClaimantId: civilClaimant?.id,
})

if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('LimitedAccess Write Case File Guard', () => {
})

describe.each(allowedCaseFileCategories)(
'a defender can view %s',
'a defender can access %s',
(category) => {
describe('when creating a case file', () => {
let then: Then
Expand Down Expand Up @@ -93,7 +93,7 @@ describe('LimitedAccess Write Case File Guard', () => {
(category) =>
!allowedCaseFileCategories.includes(category as CaseFileCategory),
),
)('a defender can not view %s', (category) => {
)('a defender can not access %s', (category) => {
describe('when creating a case file', () => {
let then: Then

Expand Down Expand Up @@ -137,7 +137,7 @@ describe('LimitedAccess Write Case File Guard', () => {
Object.keys(UserRole).filter((role) => role !== UserRole.DEFENDER),
)('role %s', (role) => {
describe.each(Object.keys(CaseFileCategory))(
'can not view %s',
'can not access %s',
(category) => {
describe('when creating a case file', () => {
let then: Then
Expand Down Expand Up @@ -225,7 +225,7 @@ describe('LimitedAccess Write Case File Guard', () => {
})
})

describe('a defender can view DEFENDANT_CASE_FILE in indictment cases', () => {
describe('a defender can access DEFENDANT_CASE_FILE in indictment cases', () => {
describe('when creating a case file', () => {
let then: Then

Expand Down Expand Up @@ -265,7 +265,7 @@ describe('LimitedAccess Write Case File Guard', () => {

describe.each(
Object.keys(CaseType).filter((ct) => ct !== CaseType.INDICTMENT),
)('a defender can not view DEFENDANT_CASE_FILE in %s cases', (caseType) => {
)('a defender can not access DEFENDANT_CASE_FILE in %s cases', (caseType) => {
describe('when creating a case file', () => {
let then: Then

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
BadRequestException,
CanActivate,
ExecutionContext,
Injectable,
InternalServerErrorException,
} from '@nestjs/common'

import { CaseFileCategory, User } from '@island.is/judicial-system/types'

import { Case } from '../../case'

@Injectable()
export class WriteCaseFileGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest()

const user: User = request.user
const theCase: Case = request.case
const defendant = request.defendant
const civilClaimant = request.civilClaimant

if (!theCase) {
throw new InternalServerErrorException('Missing case')
}

if (!user) {
throw new InternalServerErrorException('Missing user')
}

// The case file category is either in the request body (creating case file)
// or in the case file (deleting case file)
const caseFileCategory: CaseFileCategory =
request.body?.category ?? request.caseFile?.category

if (!caseFileCategory) {
throw new InternalServerErrorException('Missing case file category')
}

if (
caseFileCategory === CaseFileCategory.SENT_TO_PRISON_ADMIN_FILE &&
!defendant
) {
throw new BadRequestException('Missing defendant for case file category')
}

if (caseFileCategory === CaseFileCategory.CIVIL_CLAIM && !civilClaimant) {
throw new BadRequestException(
'Missing civil claimant for case file category',
)
}

return true
}
}
Loading

0 comments on commit bdeea4f

Please sign in to comment.