diff --git a/docs/dynamodb-access-patterns.csv b/docs/dynamodb-access-patterns.csv index b9ee4eac496..1b6930704b4 100644 --- a/docs/dynamodb-access-patterns.csv +++ b/docs/dynamodb-access-patterns.csv @@ -1,11 +1,8 @@ Access Scenario,PK,SK,GS1PK,GSI2PK -the case deadline object,case-deadline|${DEADLINE_ID},case-deadline|${DEADLINE_ID}, -associate a deadline with a case (mapping record),case|${CASE_ID},case-deadline|${DEADLINE_ID}, a case,case|${CASE_ID},case|${CASE_ID},leadCase|${LEAD_CASE_ID} associate an irs practitioner onto a case,case|${CASE_ID},irsPractitioner|${USER_ID},leadCase|${LEAD_CASE_ID} associate a private practitioner onto a case,case|${CASE_ID},privatePractitioner|${USER_ID},leadCase|${LEAD_CASE_ID} associate docket entry on a case,case|${CASE_ID},docket-entry|${DOCKET_ENTRY_ID}, -add correspondence to a case,case|${CASE_ID},correspondence|${CORRESPONDENCE_ID}, add a hearing to a case,case|${CASE_ID},hearing|${TRIAL_SESSION_ID}, a work item on a case,case|${CASE_ID},work-item|${WORK_ITEM_ID},work-item|${WORK_ITEM_ID},assigneeId|${ASSIGNEE_ID} docket number generator counter,docketNumberCounter-${YEAR},docketNumberCounter-${YEAR}, diff --git a/scripts/dynamo/fix-race-condition-served-in-drafts.test.ts b/scripts/dynamo/fix-race-condition-served-in-drafts.test.ts index 4c08cf1b2a8..b7f1eff63da 100644 --- a/scripts/dynamo/fix-race-condition-served-in-drafts.test.ts +++ b/scripts/dynamo/fix-race-condition-served-in-drafts.test.ts @@ -1,6 +1,8 @@ /* * @jest-environment node */ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; +import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { DynamoDBClient, GetItemCommand } from '@aws-sdk/client-dynamodb'; import { MOCK_DOCUMENTS } from '@shared/test/mockDocketEntry'; diff --git a/scripts/reports/cases-closed-in-year.ts b/scripts/reports/cases-closed-in-year.ts index b0c43a03639..20480a32410 100644 --- a/scripts/reports/cases-closed-in-year.ts +++ b/scripts/reports/cases-closed-in-year.ts @@ -80,7 +80,7 @@ const getAllCasesClosedInFiscalYear = async ({ const wasClosedThisFiscalYear = (c: RawCase): boolean => { let closedThisFiscalYear = false; - for (const csh of c.caseStatusHistory) { + for (const csh of c.caseStatusHistory || []) { if ( csh.date && csh.date >= BEGIN && @@ -115,7 +115,7 @@ const outputCsv = ({ .replace('Special Trial ', '') .replace('Judge ', '') || ''; const closedDateHumanized = - c.caseStatusHistory + (c.caseStatusHistory || []) .reverse() .find( csh => diff --git a/scripts/run-once-scripts/postgres-migration/delete-case-correspondences.ts b/scripts/run-once-scripts/postgres-migration/delete-case-correspondences.ts new file mode 100644 index 00000000000..76a67099a15 --- /dev/null +++ b/scripts/run-once-scripts/postgres-migration/delete-case-correspondences.ts @@ -0,0 +1,64 @@ +/** + * HOW TO RUN + * TABLE_NAME=testing npx ts-node --transpileOnly scripts/run-once-scripts/postgres-migration/delete-case-correspondences.ts + */ + +import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb'; +import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; +import { getDbReader } from '../../../web-api/src/database'; +import { isEmpty } from 'lodash'; +import { batchDeleteDynamoItems } from './batch-delete-dynamo-items'; +import { environment } from '../../../web-api/src/environment'; + +const caseCorrespondencePageSize = 10000; +const dynamoDbClient = new DynamoDBClient({ region: 'us-east-1' }); +const dynamoDbDocClient = DynamoDBDocumentClient.from(dynamoDbClient); + +// We set the environment as 'production' (= "a deployed environment") to get the RDS connection to work properly +environment.nodeEnv = 'production'; +process.env.CIRCLE_BRANCH = 'test'; + +const getCaseCorrespondencesToDelete = async (offset: number) => { + const caseCorrespondences = await getDbReader(reader => + reader + .selectFrom('dwCaseCorrespondence') + .select(['docketNumber', 'correspondenceId']) + .orderBy('correspondenceId') + .limit(caseCorrespondencePageSize) + .offset(offset) + .execute(), + ); + return caseCorrespondences; +}; + +let totalItemsDeleted = 0; + +async function main() { + let offset = 0; + let caseCorrespondencesToDelete = + await getCaseCorrespondencesToDelete(offset); + + while (!isEmpty(caseCorrespondencesToDelete)) { + const dynamoItemsToDelete = caseCorrespondencesToDelete.map(cd => ({ + DeleteRequest: { + Key: { + pk: `case|${cd.docketNumber}`, + sk: `correspondence${cd.correspondenceId}`, + }, + }, + })); + totalItemsDeleted += await batchDeleteDynamoItems( + dynamoItemsToDelete, + dynamoDbDocClient, + environment.dynamoDbTableName, + ); + console.log( + `Total case correspondences deleted so far: ${totalItemsDeleted}`, + ); + offset += caseCorrespondencePageSize; + caseCorrespondencesToDelete = await getCaseCorrespondencesToDelete(offset); + } + console.log('Done deleting case correspondences from Dynamo'); +} + +main().catch(console.error); diff --git a/scripts/run-once-scripts/postgres-migration/delete-case-deadlines.ts b/scripts/run-once-scripts/postgres-migration/delete-case-deadlines.ts new file mode 100644 index 00000000000..3d8a8b9e5fd --- /dev/null +++ b/scripts/run-once-scripts/postgres-migration/delete-case-deadlines.ts @@ -0,0 +1,63 @@ +/** + * HOW TO RUN + * + * TABLE_NAME=testing npx ts-node --transpileOnly scripts/run-once-scripts/postgres-migration/delete-case-deadlines.ts + */ + +import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb'; +import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; +import { requireEnvVars } from '../../../shared/admin-tools/util'; +import { getDbReader } from '../../../web-api/src/database'; +import { isEmpty } from 'lodash'; +import { batchDeleteDynamoItems } from './batch-delete-dynamo-items'; +import { environment } from '../../../web-api/src/environment'; + +const caseDeadlinePageSize = 10000; +const dynamoDbClient = new DynamoDBClient({ region: 'us-east-1' }); +const dynamoDbDocClient = DynamoDBDocumentClient.from(dynamoDbClient); + +// We set the environment as 'production' (= "a deployed environment") to get the RDS connection to work properly +environment.nodeEnv = 'production'; +process.env.CIRCLE_BRANCH = 'test'; + +const getCaseDeadlinesToDelete = async (offset: number) => { + const caseDeadlines = await getDbReader(reader => + reader + .selectFrom('dwCaseDeadline') + .select(['docketNumber', 'caseDeadlineId']) + .orderBy('caseDeadlineId') + .limit(caseDeadlinePageSize) + .offset(offset) + .execute(), + ); + return caseDeadlines; +}; + +let totalItemsDeleted = 0; + +async function main() { + let offset = 0; + let caseDeadlinesToDelete = await getCaseDeadlinesToDelete(offset); + + while (!isEmpty(caseDeadlinesToDelete)) { + const dynamoItemsToDelete = caseDeadlinesToDelete.map(cd => ({ + DeleteRequest: { + Key: { + pk: `case|${cd.docketNumber}`, + sk: `case-deadline|${cd.caseDeadlineId}`, + }, + }, + })); + totalItemsDeleted += await batchDeleteDynamoItems( + dynamoItemsToDelete, + dynamoDbDocClient, + environment.dynamoDbTableName, + ); + console.log(`Total case deadlines deleted so far: ${totalItemsDeleted}`); + offset += caseDeadlinePageSize; + caseDeadlinesToDelete = await getCaseDeadlinesToDelete(offset); + } + console.log('Done deleting case deadlines from Dynamo'); +} + +main().catch(console.error); diff --git a/scripts/run-once-scripts/postgres-migration/delete-case-worksheets.ts b/scripts/run-once-scripts/postgres-migration/delete-case-worksheets.ts new file mode 100644 index 00000000000..56692c39503 --- /dev/null +++ b/scripts/run-once-scripts/postgres-migration/delete-case-worksheets.ts @@ -0,0 +1,63 @@ +/** + * HOW TO RUN + * + * TABLE_NAME=testing npx ts-node --transpileOnly scripts/run-once-scripts/postgres-migration/delete-case-worksheets.ts + */ + +import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb'; +import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; +import { requireEnvVars } from '../../../shared/admin-tools/util'; +import { getDbReader } from '../../../web-api/src/database'; +import { isEmpty } from 'lodash'; +import { batchDeleteDynamoItems } from './batch-delete-dynamo-items'; +import { environment } from '../../../web-api/src/environment'; + +const caseWorksheetPageSize = 10000; +const dynamoDbClient = new DynamoDBClient({ region: 'us-east-1' }); +const dynamoDbDocClient = DynamoDBDocumentClient.from(dynamoDbClient); + +// We set the environment as 'production' (= "a deployed environment") to get the RDS connection to work properly +environment.nodeEnv = 'production'; +process.env.CIRCLE_BRANCH = 'test'; + +const getCaseWorksheetsToDelete = async (offset: number) => { + const caseWorksheets = await getDbReader(reader => + reader + .selectFrom('dwCaseWorksheet') + .select(['docketNumber']) + .orderBy('docketNumber') + .limit(caseWorksheetPageSize) + .offset(offset) + .execute(), + ); + return caseWorksheets; +}; + +let totalItemsDeleted = 0; + +async function main() { + let offset = 0; + let caseWorksheetsToDelete = await getCaseWorksheetsToDelete(offset); + + while (!isEmpty(caseWorksheetsToDelete)) { + const dynamoItemsToDelete = caseWorksheetsToDelete.map(cd => ({ + DeleteRequest: { + Key: { + pk: `case|${cd.docketNumber}`, + sk: `case-worksheet|${cd.docketNumber}`, + }, + }, + })); + totalItemsDeleted += await batchDeleteDynamoItems( + dynamoItemsToDelete, + dynamoDbDocClient, + environment.dynamoDbTableName, + ); + console.log(`Total case worksheets deleted so far: ${totalItemsDeleted}`); + offset += caseWorksheetPageSize; + caseWorksheetsToDelete = await getCaseWorksheetsToDelete(offset); + } + console.log('Done deleting case worksheets from Dynamo'); +} + +main().catch(console.error); diff --git a/scripts/run-once-scripts/postgres-migration/delete-messages.ts b/scripts/run-once-scripts/postgres-migration/delete-messages.ts index cc022e06f85..8c5b34a9807 100644 --- a/scripts/run-once-scripts/postgres-migration/delete-messages.ts +++ b/scripts/run-once-scripts/postgres-migration/delete-messages.ts @@ -1,7 +1,7 @@ /** * HOW TO RUN * - * TABLE_NAME=testing npx ts-node --transpileOnly scripts/postgres/delete-messages.ts + * TABLE_NAME=testing npx ts-node --transpileOnly scripts/run-once-scripts/postgres-migration/delete-messages.ts */ import { diff --git a/shared/src/business/entities/CaseDeadline.test.ts b/shared/src/business/entities/CaseDeadline.test.ts index 2d87ba49618..c4ccaef0921 100644 --- a/shared/src/business/entities/CaseDeadline.test.ts +++ b/shared/src/business/entities/CaseDeadline.test.ts @@ -1,47 +1,24 @@ import { CaseDeadline } from './CaseDeadline'; -import { applicationContext } from '../test/createTestApplicationContext'; describe('CaseDeadline', () => { const DOCKET_NUMBER = '123-19'; it('should generate a sortable docket number using the docket number provided', () => { - const caseDeadline = new CaseDeadline( - { - associatedJudge: 'Judge Buch', - associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', - deadlineDate: '2019-03-01T21:42:29.073Z', - description: 'One small step', - docketNumber: DOCKET_NUMBER, - sortableDocketNumber: undefined, - }, - { applicationContext }, - ); + const caseDeadline = new CaseDeadline({ + associatedJudge: 'Judge Buch', + associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', + deadlineDate: '2019-03-01T21:42:29.073Z', + description: 'One small step', + docketNumber: DOCKET_NUMBER, + sortableDocketNumber: undefined, + }); expect(caseDeadline.sortableDocketNumber).toEqual(2019000123); }); - describe('constructor', () => { - it('should throw an error when application context is not provided', () => { - expect( - () => - new CaseDeadline( - { - associatedJudge: 'Judge Buch', - associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', - deadlineDate: '2019-03-01T21:42:29.073Z', - description: 'One small step', - docketNumber: DOCKET_NUMBER, - sortableDocketNumber: undefined, - }, - {} as any, - ), - ).toThrow('applicationContext must be defined'); - }); - }); - describe('validation', () => { it('should be invalid when required fields that are not defaulted in the constructor are not provided', () => { - const caseDeadline = new CaseDeadline({}, { applicationContext }); + const caseDeadline = new CaseDeadline({}); expect(caseDeadline.getFormattedValidationErrors()).toEqual({ associatedJudge: 'Associated judge is required', @@ -54,44 +31,37 @@ describe('CaseDeadline', () => { }); it('should be valid when required fields are all provided', () => { - const caseDeadline = new CaseDeadline( - { - associatedJudge: 'Judge Buch', - associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', - deadlineDate: '2019-03-01T21:42:29.073Z', - description: 'One small step', - docketNumber: DOCKET_NUMBER, - leadDocketNumber: DOCKET_NUMBER, - }, - { applicationContext }, - ); + const caseDeadline = new CaseDeadline({ + associatedJudge: 'Judge Buch', + associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', + deadlineDate: '2019-03-01T21:42:29.073Z', + description: 'One small step', + docketNumber: DOCKET_NUMBER, + leadDocketNumber: DOCKET_NUMBER, + }); expect(caseDeadline.getFormattedValidationErrors()).toEqual(null); }); it('should be valid when all required fields are present and optional fields are not', () => { - const caseDeadline = new CaseDeadline( - { - associatedJudge: 'Judge Buch', - associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', - deadlineDate: '2019-03-01T21:42:29.073Z', - description: 'One small step', - docketNumber: DOCKET_NUMBER, - leadDocketNumber: undefined, /// Optional property - }, - { applicationContext }, - ); + const caseDeadline = new CaseDeadline({ + associatedJudge: 'Judge Buch', + associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', + deadlineDate: '2019-03-01T21:42:29.073Z', + description: 'One small step', + docketNumber: DOCKET_NUMBER, + leadDocketNumber: undefined, /// Optional property + }); expect(caseDeadline.getFormattedValidationErrors()).toEqual(null); }); it('should be invalid and return a helpful message when the user provides a description that is too long', () => { - const caseDeadline = new CaseDeadline( - { - associatedJudge: 'Judge Buch', - associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', - deadlineDate: '2019-03-01T21:42:29.073Z', - description: `I got the horses in the back + const caseDeadline = new CaseDeadline({ + associatedJudge: 'Judge Buch', + associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', + deadlineDate: '2019-03-01T21:42:29.073Z', + description: `I got the horses in the back Horse tack is attached Hat is matte black Got the boots that's black to match @@ -99,10 +69,8 @@ describe('CaseDeadline', () => { You can whip your Porsche I been in the valley You ain't been up off that porch, now`, // Description can be at most 120 characters - docketNumber: DOCKET_NUMBER, - }, - { applicationContext }, - ); + docketNumber: DOCKET_NUMBER, + }); expect(caseDeadline.getFormattedValidationErrors()).toEqual({ description: diff --git a/shared/src/business/entities/CaseDeadline.ts b/shared/src/business/entities/CaseDeadline.ts index 336b8142335..36b97ba4a7c 100644 --- a/shared/src/business/entities/CaseDeadline.ts +++ b/shared/src/business/entities/CaseDeadline.ts @@ -3,6 +3,7 @@ import { Case } from './cases/Case'; import { JoiValidationConstants } from './JoiValidationConstants'; import { JoiValidationEntity } from '@shared/business/entities/JoiValidationEntity'; import { createISODateString } from '../utilities/DateHandler'; +import { getUniqueId } from '@shared/sharedAppContext'; import joi from 'joi'; export class CaseDeadline extends JoiValidationEntity { public associatedJudge: string; @@ -15,17 +16,12 @@ export class CaseDeadline extends JoiValidationEntity { public leadDocketNumber?: string; public sortableDocketNumber: number; - constructor(rawProps, { applicationContext }) { + constructor(rawProps) { super('CaseDeadline'); - if (!applicationContext) { - throw new TypeError('applicationContext must be defined'); - } - this.associatedJudge = rawProps.associatedJudge; this.associatedJudgeId = rawProps.associatedJudgeId; - this.caseDeadlineId = - rawProps.caseDeadlineId || applicationContext.getUniqueId(); + this.caseDeadlineId = rawProps.caseDeadlineId || getUniqueId(); this.createdAt = rawProps.createdAt || createISODateString(); this.deadlineDate = rawProps.deadlineDate; this.description = rawProps.description; diff --git a/shared/src/business/entities/Correspondence.test.ts b/shared/src/business/entities/Correspondence.test.ts index 6777ac46ea9..eb255d25bdc 100644 --- a/shared/src/business/entities/Correspondence.test.ts +++ b/shared/src/business/entities/Correspondence.test.ts @@ -4,6 +4,7 @@ describe('Correspondence', () => { const validCorrespondence: RawCorrespondence = { archived: false, correspondenceId: 'e9ab90a9-2150-4dd1-90b4-fee2097c23db', + docketNumber: '101-23', documentTitle: 'A Title', entityName: 'Correspondence', filedBy: 'Nika Manpreet', @@ -24,6 +25,7 @@ describe('Correspondence', () => { const correspondence = new Correspondence({ archived: true, correspondenceId: 'e9ab90a9-2150-4dd1-90b4-fee2097c23db', + docketNumber: '101-23', documentTitle: 'A Title', filedBy: 'A dog', filingDate: undefined, diff --git a/shared/src/business/entities/Correspondence.ts b/shared/src/business/entities/Correspondence.ts index cf1bcc303e0..e4665c01a0f 100644 --- a/shared/src/business/entities/Correspondence.ts +++ b/shared/src/business/entities/Correspondence.ts @@ -10,6 +10,7 @@ export class Correspondence extends JoiValidationEntity { public filedBy: string; public filingDate: string; public userId: string; + public docketNumber: string; constructor(rawProps) { super('Correspondence'); @@ -20,6 +21,7 @@ export class Correspondence extends JoiValidationEntity { this.filedBy = rawProps.filedBy; this.filingDate = rawProps.filingDate || createISODateString(); this.userId = rawProps.userId; + this.docketNumber = rawProps.docketNumber; } static VALIDATION_RULES = { @@ -28,6 +30,7 @@ export class Correspondence extends JoiValidationEntity { .optional() .description('A correspondence document that was archived.'), correspondenceId: JoiValidationConstants.UUID.required(), + docketNumber: JoiValidationConstants.STRING.max(10).required(), documentTitle: JoiValidationConstants.STRING.max(500).required(), filedBy: JoiValidationConstants.STRING.max(500).allow('').optional(), filingDate: JoiValidationConstants.ISO_DATE.max('now') diff --git a/shared/src/business/entities/caseWorksheet/CaseWorksheet.ts b/shared/src/business/entities/caseWorksheet/CaseWorksheet.ts index f1cef882236..b399231ea8e 100644 --- a/shared/src/business/entities/caseWorksheet/CaseWorksheet.ts +++ b/shared/src/business/entities/caseWorksheet/CaseWorksheet.ts @@ -6,6 +6,7 @@ export class CaseWorksheet extends JoiValidationEntity { public finalBriefDueDate?: string; public primaryIssue?: string; public statusOfMatter?: string; + public judgeUserId: string; constructor(rawProps) { super('CaseWorksheet'); @@ -14,6 +15,7 @@ export class CaseWorksheet extends JoiValidationEntity { this.finalBriefDueDate = rawProps.finalBriefDueDate; this.primaryIssue = rawProps.primaryIssue; this.statusOfMatter = rawProps.statusOfMatter; + this.judgeUserId = rawProps.judgeUserId; } static STATUS_OF_MATTER_OPTIONS = [ @@ -35,6 +37,7 @@ export class CaseWorksheet extends JoiValidationEntity { .messages({ '*': 'Enter a valid due date', }), + judgeUserId: JoiValidationConstants.UUID.required(), primaryIssue: JoiValidationConstants.STRING.allow('').optional(), statusOfMatter: JoiValidationConstants.STRING.valid( ...CaseWorksheet.STATUS_OF_MATTER_OPTIONS, diff --git a/shared/src/business/entities/cases/Case.archiveCorrespondence.test.ts b/shared/src/business/entities/cases/Case.archiveCorrespondence.test.ts index 152f586975e..812ad19c2ae 100644 --- a/shared/src/business/entities/cases/Case.archiveCorrespondence.test.ts +++ b/shared/src/business/entities/cases/Case.archiveCorrespondence.test.ts @@ -9,6 +9,7 @@ describe('archiveCorrespondence', () => { beforeEach(() => { correspondenceToArchive = new Correspondence({ correspondenceId: '123-abc', + docketNumber: '101-23', documentTitle: 'My Correspondence', filedBy: 'Docket clerk', }); diff --git a/shared/src/business/entities/cases/Case.deleteCorrespondenceById.test.ts b/shared/src/business/entities/cases/Case.deleteCorrespondenceById.test.ts index 49a9b14afdd..4a2b8552a5b 100644 --- a/shared/src/business/entities/cases/Case.deleteCorrespondenceById.test.ts +++ b/shared/src/business/entities/cases/Case.deleteCorrespondenceById.test.ts @@ -6,6 +6,7 @@ import { mockDocketClerkUser } from '@shared/test/mockAuthUsers'; describe('deleteCorrespondenceById', () => { const mockCorrespondence = new Correspondence({ + docketNumer: '101-23', documentTitle: 'A correpsondence', filingDate: '2025-03-01T00:00:00.000Z', userId: MOCK_USERS['a7d90c05-f6cd-442c-a168-202db587f16f'].userId, diff --git a/shared/src/business/entities/cases/Case.getCorrespondenceById.test.ts b/shared/src/business/entities/cases/Case.getCorrespondenceById.test.ts index 3880b18518e..ce9fa5e4328 100644 --- a/shared/src/business/entities/cases/Case.getCorrespondenceById.test.ts +++ b/shared/src/business/entities/cases/Case.getCorrespondenceById.test.ts @@ -7,6 +7,7 @@ describe('getCorrespondenceById', () => { it('should get a correspondence document by id', () => { const mockCorrespondence = new Correspondence({ correspondenceId: '123-abc', + docketNumber: '101-23', documentTitle: 'My Correspondence', filedBy: 'Docket clerk', }); diff --git a/shared/src/business/entities/cases/Case.removeFromTrial.test.ts b/shared/src/business/entities/cases/Case.removeFromTrial.test.ts index 688700a57f0..8c18720c1f2 100644 --- a/shared/src/business/entities/cases/Case.removeFromTrial.test.ts +++ b/shared/src/business/entities/cases/Case.removeFromTrial.test.ts @@ -44,7 +44,7 @@ describe('removeFromTrial', () => { changedBy: user, }); const indexOfLastCaseHistoryItem = - caseToUpdate.caseStatusHistory.length - 1; + caseToUpdate.caseStatusHistory!.length - 1; expect(caseToUpdate.status).toEqual( CASE_STATUS_TYPES.generalDocketReadyForTrial, @@ -55,7 +55,7 @@ describe('removeFromTrial', () => { expect(caseToUpdate.trialSessionId).toBeFalsy(); expect(caseToUpdate.trialTime).toBeFalsy(); expect( - caseToUpdate.caseStatusHistory[indexOfLastCaseHistoryItem], + caseToUpdate.caseStatusHistory![indexOfLastCaseHistoryItem], ).toMatchObject({ changedBy: user }); }); diff --git a/shared/src/business/entities/cases/Case.test.ts b/shared/src/business/entities/cases/Case.test.ts index 11274a7bef3..6f3d2967f6c 100644 --- a/shared/src/business/entities/cases/Case.test.ts +++ b/shared/src/business/entities/cases/Case.test.ts @@ -1,4 +1,7 @@ /* eslint-disable max-lines */ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; +import '@web-api/persistence/postgres/cases/mocks.jest'; import { AUTOMATIC_BLOCKED_REASONS, CASE_STATUS_TYPES, @@ -127,7 +130,9 @@ describe('Case entity', () => { }); it('defaults the orders to false', () => { - const myCase = new Case(MOCK_CASE, { authorizedUser: mockDocketClerkUser }); + const myCase = new Case(MOCK_CASE, { + authorizedUser: mockDocketClerkUser, + }); expect(myCase).toMatchObject({ isSealed: false, diff --git a/shared/src/business/entities/cases/Case.ts b/shared/src/business/entities/cases/Case.ts index a1a06d696e3..bad0a7d3472 100644 --- a/shared/src/business/entities/cases/Case.ts +++ b/shared/src/business/entities/cases/Case.ts @@ -85,7 +85,7 @@ export class Case extends JoiValidationEntity { public blocked?: boolean; public blockedDate?: string; public blockedReason?: string; - public caseStatusHistory: CaseStatusChange[]; + public caseStatusHistory?: CaseStatusChange[]; public caseNote?: string; public damages?: number; public highPriority?: boolean; @@ -134,7 +134,7 @@ export class Case extends JoiValidationEntity { public noticeOfTrialDate?: string; public docketNumberWithSuffix?: string; public canAllowDocumentService?: boolean; - public canAllowPrintableDocketRecord!: boolean; + public canAllowPrintableDocketRecord?: boolean; public canDojPractitionersRepresentParty?: boolean; public archivedDocketEntries?: RawDocketEntry[]; public docketEntries: any[]; @@ -953,7 +953,13 @@ export class Case extends JoiValidationEntity { assignCorrespondences({ rawCase }) { if (Array.isArray(rawCase.correspondence)) { this.correspondence = rawCase.correspondence - .map(correspondence => new Correspondence(correspondence)) + .map( + correspondence => + new Correspondence({ + ...correspondence, + docketNumber: rawCase.docketNumber, + }), + ) .sort((a, b) => compareStrings(a.filingDate, b.filingDate)); } else { this.correspondence = []; @@ -961,7 +967,11 @@ export class Case extends JoiValidationEntity { if (Array.isArray(rawCase.archivedCorrespondences)) { this.archivedCorrespondences = rawCase.archivedCorrespondences.map( - correspondence => new Correspondence(correspondence), + correspondence => + new Correspondence({ + ...correspondence, + docketNumber: rawCase.docketNumber, + }), ); } else { this.archivedCorrespondences = []; @@ -1534,7 +1544,7 @@ export class Case extends JoiValidationEntity { const date = createISODateString(); this.status = updatedCaseStatus; - this.caseStatusHistory.push({ + this.caseStatusHistory?.push({ changedBy, date, updatedCaseStatus, @@ -2185,11 +2195,11 @@ export const shouldGenerateNoticesForCase = rawCase => { /** * determines whether or not we should show the printable docket record - * @param {Object} rawCase the case we are using to determine whether we should show the printable docket record + * @param {Object} rawCase the case we are using to determine whether we should show the printable docket record * @returns {Boolean} whether or not we should show the printable docket record */ export const canAllowPrintableDocketRecord = rawCase => { - if (typeof rawCase.canAllowPrintableDocketRecord !== 'undefined') { + if (rawCase.canAllowPrintableDocketRecord !== undefined) { return rawCase.canAllowPrintableDocketRecord; } return rawCase.status !== CASE_STATUS_TYPES.new; diff --git a/shared/src/business/entities/cases/Case.updateCorrespondence.test.ts b/shared/src/business/entities/cases/Case.updateCorrespondence.test.ts index df323ad4c91..c275ad72f0d 100644 --- a/shared/src/business/entities/cases/Case.updateCorrespondence.test.ts +++ b/shared/src/business/entities/cases/Case.updateCorrespondence.test.ts @@ -7,6 +7,7 @@ describe('updateCorrespondence', () => { it('should update a correspondence document', () => { const mockCorrespondence = new Correspondence({ correspondenceId: '123-abc', + docketNumber: '101-23', documentTitle: 'My Correspondence', filedBy: 'Docket clerk', }); @@ -32,6 +33,7 @@ describe('updateCorrespondence', () => { it('should not throw an exception when the specified correspondence document is not found', () => { const mockCorrespondence = new Correspondence({ correspondenceId: '123-abc', + docketNumber: '101-23', documentTitle: 'My Correspondence', filedBy: 'Docket clerk', }); diff --git a/shared/src/business/entities/cases/PaperPetition.test.ts b/shared/src/business/entities/cases/PaperPetition.test.ts index d4af1b3d4e2..9109b94d6db 100644 --- a/shared/src/business/entities/cases/PaperPetition.test.ts +++ b/shared/src/business/entities/cases/PaperPetition.test.ts @@ -497,6 +497,7 @@ describe('paperPetition entity', () => { const mockGuid = getUniqueId(); const mockCorrespondence = new Correspondence({ correspondenceId: mockGuid, + docketNumber: '101-23', documentTitle: 'My Correspondence', filedBy: 'Docket clerk', userId: mockGuid, diff --git a/shared/src/business/test/createTestApplicationContext.ts b/shared/src/business/test/createTestApplicationContext.ts index e6165664a2c..961d13754d1 100644 --- a/shared/src/business/test/createTestApplicationContext.ts +++ b/shared/src/business/test/createTestApplicationContext.ts @@ -78,7 +78,6 @@ import { import { getAllFeatureFlagsInteractor } from '@web-api/business/useCases/featureFlag/getAllFeatureFlagsInteractor'; import { getAllWebSocketConnections } from '@web-api/persistence/dynamo/notifications/getAllWebSocketConnections'; import { getCaseByDocketNumber } from '@web-api/persistence/dynamo/cases/getCaseByDocketNumber'; -import { getCaseDeadlinesByDocketNumber } from '@web-api/persistence/dynamo/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { getCaseDocumentsIdsFilteredByDocumentType } from '@shared/business/utilities/getCaseDocumentsIdsFilteredByDocumentType'; import { getConfigurationItemValue } from '@web-api/persistence/dynamo/deployTable/getConfigurationItemValue'; import { getConstants } from '@web-client/getConstants'; @@ -116,10 +115,10 @@ import { unsealDocketEntryInteractor } from '@web-api/business/useCases/docketEn import { updateCase } from '@web-api/persistence/dynamo/cases/updateCase'; import { updateCaseAndAssociations } from '@web-api/business/useCaseHelper/caseAssociation/updateCaseAndAssociations'; import { updateCaseAutomaticBlock } from '@web-api/business/useCaseHelper/automaticBlock/updateCaseAutomaticBlock'; -import { updateCaseCorrespondence } from '@web-api/persistence/dynamo/correspondence/updateCaseCorrespondence'; import { updateDocketEntry } from '@web-api/persistence/dynamo/documents/updateDocketEntry'; import { updateUserRecords } from '@web-api/persistence/dynamo/users/updateUserRecords'; import { uploadDocumentAndMakeSafeInteractor } from '@shared/business/useCases/uploadDocumentAndMakeSafeInteractor'; +import { upsertCaseCorrespondences } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; import { validatePenaltiesInteractor } from '@shared/business/useCases/validatePenaltiesInteractor'; import { verifyCaseForUser } from '@web-api/persistence/dynamo/cases/verifyCaseForUser'; import path from 'path'; @@ -477,10 +476,7 @@ export const createTestApplicationContext = () => { .mockImplementation(getAllWebSocketConnections), getCalendaredCasesForTrialSession: jest.fn(), getCaseByDocketNumber: jest.fn().mockImplementation(getCaseByDocketNumber), - getCaseDeadlinesByDateRange: jest.fn(), - getCaseDeadlinesByDocketNumber: jest - .fn() - .mockImplementation(getCaseDeadlinesByDocketNumber), + getCasesByFilters: jest.fn(), getConfigurationItemValue: jest .fn() .mockImplementation(getConfigurationItemValue), @@ -524,13 +520,13 @@ export const createTestApplicationContext = () => { setTrialSessionJobStatusForCase: jest.fn(), setTrialSessionProcessingStatus: jest.fn(), updateCase: jest.fn().mockImplementation(updateCase), - updateCaseCorrespondence: jest - .fn() - .mockImplementation(updateCaseCorrespondence), updateCaseHearing: jest.fn(), updateDocketEntry: jest.fn().mockImplementation(updateDocketEntry), uploadDocument: jest.fn(), uploadPdfFromClient: jest.fn().mockImplementation(() => ''), + upsertCaseCorrespondences: jest + .fn() + .mockImplementation(upsertCaseCorrespondences), verifyCaseForUser: jest.fn().mockImplementation(verifyCaseForUser), }); diff --git a/shared/src/business/useCases/caseDeadline/validateCaseDeadlineInteractor.ts b/shared/src/business/useCases/caseDeadline/validateCaseDeadlineInteractor.ts index df985534c88..5c2c9a8f224 100644 --- a/shared/src/business/useCases/caseDeadline/validateCaseDeadlineInteractor.ts +++ b/shared/src/business/useCases/caseDeadline/validateCaseDeadlineInteractor.ts @@ -4,9 +4,7 @@ export const validateCaseDeadlineInteractor = ( applicationContext, { caseDeadline }: { caseDeadline: RawCaseDeadline }, ): Record | null => { - const errors = new CaseDeadline(caseDeadline, { - applicationContext, - }).getFormattedValidationErrors(); + const errors = new CaseDeadline(caseDeadline).getFormattedValidationErrors(); return errors; }; diff --git a/shared/src/business/useCases/caseWorksheet/validateCaseWorksheetInteractor.test.ts b/shared/src/business/useCases/caseWorksheet/validateCaseWorksheetInteractor.test.ts index 1dfd8118639..3a5ec600938 100644 --- a/shared/src/business/useCases/caseWorksheet/validateCaseWorksheetInteractor.test.ts +++ b/shared/src/business/useCases/caseWorksheet/validateCaseWorksheetInteractor.test.ts @@ -1,4 +1,5 @@ import { RawCaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; +import { judgeColvin } from '@shared/test/mockUsers'; import { validateCaseWorksheetInteractor } from './validateCaseWorksheetInteractor'; describe('validateCaseWorksheetInteractor', () => { @@ -6,6 +7,7 @@ describe('validateCaseWorksheetInteractor', () => { const mockInvalidCaseWorksheet: RawCaseWorksheet = { docketNumber: undefined as any, // Docket number is required entityName: 'CaseWorksheet', + judgeUserId: judgeColvin.userId, }; const errors = validateCaseWorksheetInteractor({ @@ -19,6 +21,7 @@ describe('validateCaseWorksheetInteractor', () => { const mockValidCaseWorksheet: RawCaseWorksheet = { docketNumber: '111-11', entityName: 'CaseWorksheet', + judgeUserId: judgeColvin.userId, }; const errors = validateCaseWorksheetInteractor({ diff --git a/shared/src/business/useCases/getCaseDeadlinesInteractor.test.ts b/shared/src/business/useCases/getCaseDeadlinesInteractor.test.ts index c7f8129dffc..0efb227be85 100644 --- a/shared/src/business/useCases/getCaseDeadlinesInteractor.test.ts +++ b/shared/src/business/useCases/getCaseDeadlinesInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import { CASE_TYPES_MAP, CONTACT_TYPES, @@ -8,12 +9,17 @@ import { } from '../entities/EntityConstants'; import { MOCK_CASE } from '../../test/mockCase'; import { applicationContext } from '../test/createTestApplicationContext'; +import { getCaseDeadlinesByDateRange as getCaseDeadlinesByDateRangeMock } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDateRange'; + import { getCaseDeadlinesInteractor } from './getCaseDeadlinesInteractor'; import { mockPetitionerUser, mockPetitionsClerkUser, } from '@shared/test/mockAuthUsers'; +const getCaseDeadlinesByDateRange = + getCaseDeadlinesByDateRangeMock as jest.Mock; + describe('getCaseDeadlinesInteractor', () => { const mockDeadlines = [ { @@ -87,11 +93,10 @@ describe('getCaseDeadlinesInteractor', () => { beforeEach(() => { applicationContext.environment.stage = 'local'; - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDateRange.mockReturnValue({ - foundDeadlines: mockDeadlines, - }); + getCaseDeadlinesByDateRange.mockReturnValue({ + foundDeadlines: mockDeadlines, + totalCount: 2, + }); applicationContext .getPersistenceGateway() .getCasesByDocketNumbers.mockReturnValue(mockCases); @@ -159,10 +164,7 @@ describe('getCaseDeadlinesInteractor', () => { mockPetitionsClerkUser, ); - expect( - applicationContext.getPersistenceGateway().getCaseDeadlinesByDateRange - .mock.calls[0][0], - ).toMatchObject({ + expect(getCaseDeadlinesByDateRange.mock.calls[0][0]).toMatchObject({ endDate: END_DATE, judge: 'Buch', startDate: START_DATE, @@ -216,22 +218,21 @@ describe('getCaseDeadlinesInteractor', () => { ], }, ]); - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDateRange.mockReturnValue({ - foundDeadlines: [ - ...mockDeadlines, - { - associatedJudge: 'Judge Carluzzo', - associatedJudgeId: 'dabbad03-18d0-43ec-bafb-654e83405416', - caseDeadlineId: 'c63d6904-1234-4321-8259-9f8f65824bb7', - createdAt: '2019-02-01T21:40:46.415Z', - deadlineDate: '2019-04-01T21:40:46.415Z', - description: 'Yet anotherA deadline!', - docketNumber: '2000-20', - }, - ], - }); + getCaseDeadlinesByDateRange.mockReturnValue({ + foundDeadlines: [ + ...mockDeadlines, + { + associatedJudge: 'Judge Carluzzo', + associatedJudgeId: 'dabbad03-18d0-43ec-bafb-654e83405416', + caseDeadlineId: 'c63d6904-1234-4321-8259-9f8f65824bb7', + createdAt: '2019-02-01T21:40:46.415Z', + deadlineDate: '2019-04-01T21:40:46.415Z', + description: 'Yet anotherA deadline!', + docketNumber: '2000-20', + }, + ], + totalCount: 3, + }); const result = await getCaseDeadlinesInteractor( applicationContext, diff --git a/shared/src/business/useCases/getCaseDeadlinesInteractor.ts b/shared/src/business/useCases/getCaseDeadlinesInteractor.ts index 05422deff01..dc114dd27ad 100644 --- a/shared/src/business/useCases/getCaseDeadlinesInteractor.ts +++ b/shared/src/business/useCases/getCaseDeadlinesInteractor.ts @@ -9,6 +9,7 @@ import { isAuthorized, } from '../../authorization/authorizationClientService'; import { UnauthorizedError } from '@web-api/errors/errors'; +import { getCaseDeadlinesByDateRange } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDateRange'; import { pick } from 'lodash'; export const getCaseDeadlinesInteractor = async ( @@ -28,19 +29,14 @@ export const getCaseDeadlinesInteractor = async ( throw new UnauthorizedError('Unauthorized'); } - const { foundDeadlines } = await applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDateRange({ - applicationContext, - endDate, - judge, - startDate, - }); + const { foundDeadlines } = await getCaseDeadlinesByDateRange({ + endDate, + judge, + startDate, + }); - const validatedCaseDeadlines = CaseDeadline.validateRawCollection( - foundDeadlines, - { applicationContext }, - ); + const validatedCaseDeadlines = + CaseDeadline.validateRawCollection(foundDeadlines); const caseMap = await getCasesByDocketNumbers({ applicationContext, diff --git a/shared/src/business/useCases/removeCasePendingItemInteractor.test.ts b/shared/src/business/useCases/removeCasePendingItemInteractor.test.ts index 3a5446dc3b8..a1bd31d55e7 100644 --- a/shared/src/business/useCases/removeCasePendingItemInteractor.test.ts +++ b/shared/src/business/useCases/removeCasePendingItemInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { AUTOMATIC_BLOCKED_REASONS } from '../entities/EntityConstants'; @@ -5,12 +6,16 @@ import { MOCK_CASE } from '../../test/mockCase'; import { MOCK_LOCK } from '../../test/mockLock'; import { ServiceUnavailableError } from '@web-api/errors/errors'; import { applicationContext } from '../test/createTestApplicationContext'; +import { getCaseDeadlinesByDocketNumber as getCaseDeadlinesByDocketNumberMock } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { mockPetitionerUser, mockPetitionsClerkUser, } from '@shared/test/mockAuthUsers'; import { removeCasePendingItemInteractor } from './removeCasePendingItemInteractor'; +const getCaseDeadlinesByDocketNumber = + getCaseDeadlinesByDocketNumberMock as jest.Mock; + describe('removeCasePendingItemInteractor', () => { let mockLock; @@ -61,10 +66,6 @@ describe('removeCasePendingItemInteractor', () => { }); it('should call updateCase with automaticBlocked=false if there are no deadlines or pending items remaining on the case', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([]); - await removeCasePendingItemInteractor( applicationContext, { @@ -85,11 +86,7 @@ describe('removeCasePendingItemInteractor', () => { }); it('should call updateCase with automaticBlocked=true and a reason and call deleteCaseTrialSortMappingRecords if there are deadlines remaining on the case', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([ - { deadline: 'something' }, - ]); + getCaseDeadlinesByDocketNumber.mockReturnValue([{ deadline: 'something' }]); await removeCasePendingItemInteractor( applicationContext, diff --git a/shared/src/business/useCases/updateCaseContextInteractor.test.ts b/shared/src/business/useCases/updateCaseContextInteractor.test.ts index 7c455bfc6e7..d439263506c 100644 --- a/shared/src/business/useCases/updateCaseContextInteractor.test.ts +++ b/shared/src/business/useCases/updateCaseContextInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/messages/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; diff --git a/shared/src/business/utilities/calculateDaysElapsedSinceLastStatusChange.ts b/shared/src/business/utilities/calculateDaysElapsedSinceLastStatusChange.ts index 4e4560e4804..1034153f58d 100644 --- a/shared/src/business/utilities/calculateDaysElapsedSinceLastStatusChange.ts +++ b/shared/src/business/utilities/calculateDaysElapsedSinceLastStatusChange.ts @@ -5,10 +5,13 @@ import { isEmpty } from 'lodash'; export const calculateDaysElapsedSinceLastStatusChange = ( applicationContext: IApplicationContext, individualCase: { - caseStatusHistory: CaseStatusChange[]; + caseStatusHistory?: CaseStatusChange[]; }, ): { daysElapsedSinceLastStatusChange: number; statusDate: string } => { - if (isEmpty(individualCase.caseStatusHistory)) { + if ( + !individualCase.caseStatusHistory || // Redundant, but helps typescript not complain later + isEmpty(individualCase.caseStatusHistory) + ) { return { daysElapsedSinceLastStatusChange: 0, statusDate: '' }; } diff --git a/shared/src/test/mockCase.ts b/shared/src/test/mockCase.ts index 9bbfa02e8b0..8b26db8eee2 100644 --- a/shared/src/test/mockCase.ts +++ b/shared/src/test/mockCase.ts @@ -17,7 +17,11 @@ import { docketClerkUser, judgeUser } from './mockUsers'; export const MOCK_CASE: RawCase = { archivedDocketEntries: [], + associatedJudge: undefined, + associatedJudgeId: undefined, + canAllowPrintableDocketRecord: undefined, caseCaption: 'Test Petitioner, Petitioner', + caseStatusHistory: undefined, caseType: CASE_TYPES_MAP.other, consolidatedCases: [], correspondence: [], diff --git a/shared/src/test/mockCaseWorksheet.ts b/shared/src/test/mockCaseWorksheet.ts index 1fb63e832f9..ffc3a677a82 100644 --- a/shared/src/test/mockCaseWorksheet.ts +++ b/shared/src/test/mockCaseWorksheet.ts @@ -3,11 +3,13 @@ import { RawCaseWorksheet, } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; import { MOCK_CASE } from '@shared/test/mockCase'; +import { judgeColvin } from '@shared/test/mockUsers'; export const MOCK_CASE_WORKSHEET: RawCaseWorksheet = { docketNumber: MOCK_CASE.docketNumber, entityName: 'CaseWorksheet', finalBriefDueDate: '2023-07-29', + judgeUserId: judgeColvin.userId, primaryIssue: 'anything', statusOfMatter: CaseWorksheet.STATUS_OF_MATTER_OPTIONS[0], }; diff --git a/web-api/src/business/useCaseHelper/autoGenerateDeadline.test.ts b/web-api/src/business/useCaseHelper/autoGenerateDeadline.test.ts index 4ae0af5f90a..8c8093fc896 100644 --- a/web-api/src/business/useCaseHelper/autoGenerateDeadline.test.ts +++ b/web-api/src/business/useCaseHelper/autoGenerateDeadline.test.ts @@ -1,10 +1,12 @@ -import { applicationContext } from '../../../../shared/src/business/test/createTestApplicationContext'; +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import { autoGenerateDeadline } from './autoGenerateDeadline'; +import { upsertCaseDeadlines as upsertCaseDeadlinesMock } from '@web-api/persistence/postgres/caseDeadlines/upsertCaseDeadlines'; + +const upsertCaseDeadlines = upsertCaseDeadlinesMock as jest.Mock; describe('autoGenerateDeadline', () => { it('should create a case deadline', async () => { await autoGenerateDeadline({ - applicationContext, deadlineDate: '2019-03-01T21:42:29.073Z', description: 'Time is a created thing.', subjectCaseEntity: { @@ -15,9 +17,6 @@ describe('autoGenerateDeadline', () => { }, }); - expect( - applicationContext.getPersistenceGateway().createCaseDeadline.mock - .calls[0][0].caseDeadline, - ).toBeDefined(); + expect(upsertCaseDeadlines.mock.calls[0][0]).toBeDefined(); }); }); diff --git a/web-api/src/business/useCaseHelper/autoGenerateDeadline.ts b/web-api/src/business/useCaseHelper/autoGenerateDeadline.ts index f581522005c..3b715490b58 100644 --- a/web-api/src/business/useCaseHelper/autoGenerateDeadline.ts +++ b/web-api/src/business/useCaseHelper/autoGenerateDeadline.ts @@ -1,35 +1,19 @@ import { CaseDeadline } from '../../../../shared/src/business/entities/CaseDeadline'; +import { upsertCaseDeadlines } from '@web-api/persistence/postgres/caseDeadlines/upsertCaseDeadlines'; -/** - * autoGenerateDeadline - * - * @param {object} applicationContext the application context - * @param {string} providers.deadlineDate the date of the deadline to generated - * @param {string} providers.description the description of the deadline - * @param {Case} providers.subjectCaseEntity the subjectCaseEntity - */ export const autoGenerateDeadline = async ({ - applicationContext, deadlineDate, description, subjectCaseEntity, }) => { - const newCaseDeadline = new CaseDeadline( - { - associatedJudge: subjectCaseEntity.associatedJudge, - associatedJudgeId: subjectCaseEntity.associatedJudgeId, - deadlineDate, - description, - docketNumber: subjectCaseEntity.docketNumber, - sortableDocketNumber: subjectCaseEntity.sortableDocketNumber, - }, - { - applicationContext, - }, - ); - - await applicationContext.getPersistenceGateway().createCaseDeadline({ - applicationContext, - caseDeadline: newCaseDeadline.validate().toRawObject(), + const newCaseDeadline = new CaseDeadline({ + associatedJudge: subjectCaseEntity.associatedJudge, + associatedJudgeId: subjectCaseEntity.associatedJudgeId, + deadlineDate, + description, + docketNumber: subjectCaseEntity.docketNumber, + sortableDocketNumber: subjectCaseEntity.sortableDocketNumber, }); + + await upsertCaseDeadlines([newCaseDeadline.validate().toRawObject()]); }; diff --git a/web-api/src/business/useCaseHelper/automaticBlock/updateCaseAutomaticBlock.test.ts b/web-api/src/business/useCaseHelper/automaticBlock/updateCaseAutomaticBlock.test.ts index a7eb1d261b0..7fc8c3c0566 100644 --- a/web-api/src/business/useCaseHelper/automaticBlock/updateCaseAutomaticBlock.test.ts +++ b/web-api/src/business/useCaseHelper/automaticBlock/updateCaseAutomaticBlock.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import { AUTOMATIC_BLOCKED_REASONS, CASE_STATUS_TYPES, @@ -10,9 +11,13 @@ import { import { PENDING_DOCKET_ENTRY } from '../../../../../shared/src/test/mockDocketEntry'; import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; import { cloneDeep } from 'lodash'; +import { getCaseDeadlinesByDocketNumber as getCaseDeadlinesByDocketNumberMock } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { mockDocketClerkUser } from '@shared/test/mockAuthUsers'; import { updateCaseAutomaticBlock } from './updateCaseAutomaticBlock'; +const getCaseDeadlinesByDocketNumber = + getCaseDeadlinesByDocketNumberMock as jest.Mock; + describe('updateCaseAutomaticBlock', () => { let mockCase; @@ -22,9 +27,7 @@ describe('updateCaseAutomaticBlock', () => { }); it('sets the case to automaticBlocked and calls deleteCaseTrialSortMappingRecords if it has pending documents', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([]); + getCaseDeadlinesByDocketNumber.mockReturnValue([]); mockCase.docketEntries = [PENDING_DOCKET_ENTRY]; const caseEntity = new Case(mockCase, { @@ -47,11 +50,7 @@ describe('updateCaseAutomaticBlock', () => { }); it('sets the case to automaticBlocked and calls deleteCaseTrialSortMappingRecords if it has deadlines', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([ - { deadline: 'something' }, - ]); + getCaseDeadlinesByDocketNumber.mockReturnValue([{ deadline: 'something' }]); const caseEntity = new Case(MOCK_CASE_WITHOUT_PENDING, { authorizedUser: mockDocketClerkUser, @@ -73,11 +72,7 @@ describe('updateCaseAutomaticBlock', () => { }); it('does not set the case to automaticBlocked or call deleteCaseTrialSortMappingRecords if it already has a trial date', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([ - { deadline: 'something' }, - ]); + getCaseDeadlinesByDocketNumber.mockReturnValue([{ deadline: 'something' }]); const caseEntity = new Case( { @@ -102,11 +97,7 @@ describe('updateCaseAutomaticBlock', () => { }); it('does not set the case to automaticBlocked or call deleteCaseTrialSortMappingRecords when the case is marked as high priority', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([ - { deadline: 'something' }, - ]); + getCaseDeadlinesByDocketNumber.mockReturnValue([{ deadline: 'something' }]); const caseEntity = new Case( { ...MOCK_CASE_WITHOUT_PENDING, @@ -130,9 +121,7 @@ describe('updateCaseAutomaticBlock', () => { }); it('sets the case to not automaticBlocked but does not call createCaseTrialSortMappingRecords if the case does not have deadlines or pending items and the case is not generalDocketReadyForTrial status', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([]); + getCaseDeadlinesByDocketNumber.mockReturnValue([]); const caseEntity = new Case(MOCK_CASE_WITHOUT_PENDING, { authorizedUser: mockDocketClerkUser, @@ -154,9 +143,7 @@ describe('updateCaseAutomaticBlock', () => { }); it('sets the case to not automaticBlocked and calls createCaseTrialSortMappingRecords if the case does not have deadlines or pending items and the case is generalDocketReadyForTrial status', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([]); + getCaseDeadlinesByDocketNumber.mockReturnValue([]); const caseEntity = new Case( { @@ -184,9 +171,7 @@ describe('updateCaseAutomaticBlock', () => { }); it('does not call createCaseTrialSortMappingRecords if the case has no trial city', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([]); + getCaseDeadlinesByDocketNumber.mockReturnValue([]); const caseEntity = new Case( { diff --git a/web-api/src/business/useCaseHelper/automaticBlock/updateCaseAutomaticBlock.ts b/web-api/src/business/useCaseHelper/automaticBlock/updateCaseAutomaticBlock.ts index 61e36dfc3cf..cd5b630e537 100644 --- a/web-api/src/business/useCaseHelper/automaticBlock/updateCaseAutomaticBlock.ts +++ b/web-api/src/business/useCaseHelper/automaticBlock/updateCaseAutomaticBlock.ts @@ -1,3 +1,5 @@ +import { getCaseDeadlinesByDocketNumber } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; + /** * updateCaseAutomaticBlock * @@ -13,12 +15,9 @@ export const updateCaseAutomaticBlock = async ({ if (caseEntity.trialDate || caseEntity.highPriority) { return caseEntity; } - const caseDeadlines = await applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber({ - applicationContext, - docketNumber: caseEntity.docketNumber, - }); + const caseDeadlines = await getCaseDeadlinesByDocketNumber({ + docketNumber: caseEntity.docketNumber, + }); caseEntity.updateAutomaticBlocked({ caseDeadlines }); diff --git a/web-api/src/business/useCaseHelper/caseAssociation/updateCaseAndAssociations.test.ts b/web-api/src/business/useCaseHelper/caseAssociation/updateCaseAndAssociations.test.ts index f54f57ea41c..424f36884af 100644 --- a/web-api/src/business/useCaseHelper/caseAssociation/updateCaseAndAssociations.test.ts +++ b/web-api/src/business/useCaseHelper/caseAssociation/updateCaseAndAssociations.test.ts @@ -1,4 +1,6 @@ /* eslint-disable max-lines */ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; jest.mock('@shared/business/entities/Message.ts'); @@ -16,18 +18,28 @@ import { Message } from '../../../../../shared/src/business/entities/Message'; import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; import { cloneDeep } from 'lodash'; import { docketClerkUser } from '../../../../../shared/src/test/mockUsers'; +import { getCaseDeadlinesByDocketNumber as getCaseDeadlinesByDocketNumberMock } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { getMessagesByDocketNumber as getMessagesByDocketNumberMock } from '@web-api/persistence/postgres/messages/getMessagesByDocketNumber'; import { getWorkItemsByDocketNumber as getWorkItemsByDocketNumberMock } from '@web-api/persistence/postgres/workitems/getWorkItemsByDocketNumber'; import { mockDocketClerkUser } from '@shared/test/mockAuthUsers'; import { saveWorkItem as saveWorkItemMock } from '@web-api/persistence/postgres/workitems/saveWorkItem'; import { updateCaseAndAssociations } from './updateCaseAndAssociations'; import { updateMessage as updateMessageMock } from '@web-api/persistence/postgres/messages/updateMessage'; +import { upsertCaseCorrespondences as upsertCaseCorrespondencesMock } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; +import { upsertCaseDeadlines as upsertCaseDeadlinesMock } from '@web-api/persistence/postgres/caseDeadlines/upsertCaseDeadlines'; const getMessagesByDocketNumber = getMessagesByDocketNumberMock as jest.Mock; const updateMessage = updateMessageMock as jest.Mock; const saveWorkItem = saveWorkItemMock as jest.Mock; const getWorkItemsByDocketNumber = getWorkItemsByDocketNumberMock as jest.Mock; +const upsertCaseDeadlines = upsertCaseDeadlinesMock as jest.Mock; + +const getCaseDeadlinesByDocketNumber = + getCaseDeadlinesByDocketNumberMock as jest.Mock; + +const upsertCaseCorrespondences = upsertCaseCorrespondencesMock as jest.Mock; + describe('updateCaseAndAssociations', () => { let updateCaseMock = jest.fn(); let validMockCase; @@ -39,6 +51,7 @@ describe('updateCaseAndAssociations', () => { archivedCorrespondences: [ { correspondenceId: '95a84f02-23e6-4fff-9770-41f655f972a3', + docketNumber: MOCK_CASE.docketNumber, documentTitle: 'Inverted Yield Curve', filedByRole: docketClerkUser.role, userId: docketClerkUser.userId, @@ -47,6 +60,7 @@ describe('updateCaseAndAssociations', () => { correspondence: [ { correspondenceId: 'b7a6b14a-e4bd-4a20-9b6a-83674b36a162', + docketNumber: MOCK_CASE.docketNumber, documentTitle: 'Deflationary Spending', filedByRole: docketClerkUser.role, userId: docketClerkUser.userId, @@ -74,6 +88,10 @@ describe('updateCaseAndAssociations', () => { .updateCase.mockImplementation(updateCaseMock); }); + beforeEach(() => { + getCaseDeadlinesByDocketNumber.mockResolvedValue([]); + }); + it('gets the old case before passing it to updateCase persistence method', async () => { const caseToUpdate = { ...validMockCase, @@ -119,11 +137,9 @@ describe('updateCaseAndAssociations', () => { }); it('does not attempt to make any update calls to persistence if any queries to persistence fail', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockRejectedValueOnce( - new Error('query problem'), - ); + getCaseDeadlinesByDocketNumber.mockRejectedValue( + new Error('query problem'), + ); await expect( updateCaseAndAssociations({ @@ -182,9 +198,7 @@ describe('updateCaseAndAssociations', () => { ).not.toHaveBeenCalled(); // updateCaseDeadlines - expect( - applicationContext.getPersistenceGateway().createCaseDeadline, - ).not.toHaveBeenCalled(); + expect(upsertCaseDeadlines).not.toHaveBeenCalled(); // update the case itself, final persistence call expect( @@ -379,10 +393,12 @@ describe('updateCaseAndAssociations', () => { archivedCorrespondences: [ { ...validMockCase.archivedCorrespondences[0], + docketNumber: validMockCase.docketNumber, documentTitle: 'Updated Archived Correspondence', }, { correspondenceId: applicationContext.getUniqueId(), + docketNumber: validMockCase.docketNumber, documentTitle: 'New Archived Correspondence', userId: applicationContext.getUniqueId(), }, @@ -390,10 +406,12 @@ describe('updateCaseAndAssociations', () => { correspondence: [ { ...validMockCase.correspondence[0], + docketNumber: validMockCase.docketNumber, documentTitle: 'Updated Correspondence', }, { correspondenceId: applicationContext.getUniqueId(), + docketNumber: validMockCase.docketNumber, documentTitle: 'New Correspondence', userId: applicationContext.getUniqueId(), }, @@ -406,9 +424,7 @@ describe('updateCaseAndAssociations', () => { caseToUpdate, }); - expect( - applicationContext.getPersistenceGateway().updateCaseCorrespondence, - ).toHaveBeenCalledTimes(4); + expect(upsertCaseCorrespondences).toHaveBeenCalledTimes(4); }); }); @@ -724,21 +740,14 @@ describe('updateCaseAndAssociations', () => { }); describe('case deadlines', () => { - const mockDeadline = new CaseDeadline( - {}, - { - applicationContext, - }, - ); + const mockDeadline = new CaseDeadline({}); beforeAll(() => { applicationContext .getPersistenceGateway() .getCaseByDocketNumber.mockReturnValue(validMockCase); - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([ - { ...mockDeadline, pk: 'abc|987', sk: 'user-case|123' }, - ]); + getCaseDeadlinesByDocketNumber.mockReturnValue([ + { ...mockDeadline, pk: 'abc|987', sk: 'user-case|123' }, + ]); }); it('should not fetch or persist any case deadline data if associated judge is unchanged', async () => { @@ -750,13 +759,8 @@ describe('updateCaseAndAssociations', () => { authorizedUser: mockDocketClerkUser, caseToUpdate: updatedCase, }); - expect( - applicationContext.getPersistenceGateway() - .getCaseDeadlinesByDocketNumber, - ).not.toHaveBeenCalled(); - expect( - applicationContext.getPersistenceGateway().createCaseDeadline, - ).not.toHaveBeenCalled(); + expect(getCaseDeadlinesByDocketNumber).not.toHaveBeenCalled(); + expect(upsertCaseDeadlines).not.toHaveBeenCalled(); }); it('should fetch and persist case deadline data when associated judge has changed', async () => { @@ -770,17 +774,9 @@ describe('updateCaseAndAssociations', () => { authorizedUser: mockDocketClerkUser, caseToUpdate: updatedCase, }); - expect( - applicationContext.getPersistenceGateway() - .getCaseDeadlinesByDocketNumber, - ).toHaveBeenCalled(); + expect(getCaseDeadlinesByDocketNumber).toHaveBeenCalled(); expect(CaseDeadline.validateRawCollection).toHaveBeenCalled(); - expect( - applicationContext.getPersistenceGateway().createCaseDeadline, - ).toHaveBeenCalledWith({ - applicationContext, - caseDeadline: { some: 'deadline' }, - }); + expect(upsertCaseDeadlines).toHaveBeenCalledWith([{ some: 'deadline' }]); }); }); }); diff --git a/web-api/src/business/useCaseHelper/caseAssociation/updateCaseAndAssociations.ts b/web-api/src/business/useCaseHelper/caseAssociation/updateCaseAndAssociations.ts index a0c66836fbd..9200ce180e2 100644 --- a/web-api/src/business/useCaseHelper/caseAssociation/updateCaseAndAssociations.ts +++ b/web-api/src/business/useCaseHelper/caseAssociation/updateCaseAndAssociations.ts @@ -8,11 +8,14 @@ import { PrivatePractitioner } from '../../../../../shared/src/business/entities import { ServerApplicationContext } from '@web-api/applicationContext'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; import { WorkItem } from '../../../../../shared/src/business/entities/WorkItem'; +import { getCaseDeadlinesByDocketNumber } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { getMessagesByDocketNumber } from '@web-api/persistence/postgres/messages/getMessagesByDocketNumber'; import { getWorkItemsByDocketNumber } from '@web-api/persistence/postgres/workitems/getWorkItemsByDocketNumber'; import { saveWorkItem } from '@web-api/persistence/postgres/workitems/saveWorkItem'; import { updateMessage } from '@web-api/persistence/postgres/messages/updateMessage'; import { upsertCase } from '@web-api/persistence/postgres/cases/upsertCase'; +import { upsertCaseCorrespondences } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; +import { upsertCaseDeadlines } from '@web-api/persistence/postgres/caseDeadlines/upsertCaseDeadlines'; import diff from 'diff-arrays-of-objects'; /** @@ -120,6 +123,7 @@ const updateCaseMessages = async ({ * @returns {Array} the persistence functions required to complete this action */ const updateCorrespondence = ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars applicationContext, caseToUpdate, oldCase, @@ -149,13 +153,7 @@ const updateCorrespondence = ({ return validCorrespondence.map( correspondence => function updateCorrespondence_cb() { - return applicationContext - .getPersistenceGateway() - .updateCaseCorrespondence({ - applicationContext, - correspondence, - docketNumber: caseToUpdate.docketNumber, - }); + return upsertCaseCorrespondences([correspondence]); }, ); }; @@ -362,45 +360,29 @@ const updateCaseWorkItems = async ({ caseToUpdate, oldCase }) => { ); }; -/** - * Identifies user case mappings which require updates and issues persistence calls - * @param {object} args the arguments for updating the case - * @param {object} args.applicationContext the application context - * @param {object} args.caseToUpdate the case with its updated document data - * @param {object} args.oldCase the case as it is currently stored in persistence, prior to these changes - * @returns {Array} the persistence functions required to complete this action - */ const updateCaseDeadlines = async ({ - applicationContext, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + applicationContext, // cannot remove till remaining RELATED_CASE_OPERATIONS functions no longer use applicationContext caseToUpdate, oldCase, }) => { if (oldCase.associatedJudge === caseToUpdate.associatedJudge) { return []; } - - const deadlines = await applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber({ - applicationContext, - docketNumber: caseToUpdate.docketNumber, - }); + const deadlines = await getCaseDeadlinesByDocketNumber({ + docketNumber: caseToUpdate.docketNumber, + }); deadlines.forEach(caseDeadline => { caseDeadline.associatedJudge = caseToUpdate.associatedJudge; caseDeadline.associatedJudgeId = caseToUpdate.associatedJudgeId; }); - const validCaseDeadlines = CaseDeadline.validateRawCollection(deadlines, { - applicationContext, - }); + const validCaseDeadlines = CaseDeadline.validateRawCollection(deadlines); return validCaseDeadlines.map( caseDeadline => function updateCaseDeadlines_cb() { - return applicationContext.getPersistenceGateway().createCaseDeadline({ - applicationContext, - caseDeadline, - }); + return upsertCaseDeadlines([caseDeadline]); }, ); }; @@ -421,6 +403,7 @@ export const updateCaseAndAssociations = async ({ authorizedUser: UnknownAuthUser; caseToUpdate: any; }): Promise => { + console.log('updateCaseAndAssociations'); const caseEntity: Case = caseToUpdate.validate ? caseToUpdate : new Case(caseToUpdate, { diff --git a/web-api/src/business/useCaseHelper/docketEntry/fileAndServeDocumentOnOneCase.test.ts b/web-api/src/business/useCaseHelper/docketEntry/fileAndServeDocumentOnOneCase.test.ts index 6f0c8a88468..1abf51a4ae5 100644 --- a/web-api/src/business/useCaseHelper/docketEntry/fileAndServeDocumentOnOneCase.test.ts +++ b/web-api/src/business/useCaseHelper/docketEntry/fileAndServeDocumentOnOneCase.test.ts @@ -1,4 +1,5 @@ /* eslint-disable max-lines */ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { AUTOMATIC_BLOCKED_REASONS, @@ -43,7 +44,7 @@ describe('fileAndServeDocumentOnOneCase', () => { { docketEntryId: mockDocketEntryId, docketNumber: MOCK_CASE.docketNumber, - documentType: eventCodeMap.documentType, + documentType: eventCodeMap?.documentType, eventCode, filedByRole: ROLES.judge, signedAt: createISODateString(), diff --git a/web-api/src/business/useCases/caseDeadline/createCaseDeadlineInteractor.test.ts b/web-api/src/business/useCases/caseDeadline/createCaseDeadlineInteractor.test.ts index 78e3122ed54..e648974dec6 100644 --- a/web-api/src/business/useCases/caseDeadline/createCaseDeadlineInteractor.test.ts +++ b/web-api/src/business/useCases/caseDeadline/createCaseDeadlineInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { @@ -16,8 +17,12 @@ import { import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; import { createCaseDeadlineInteractor } from './createCaseDeadlineInteractor'; +import { getCaseDeadlinesByDocketNumber as getCaseDeadlinesByDocketNumberMock } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { mockPetitionsClerkUser } from '@shared/test/mockAuthUsers'; +const getCaseDeadlinesByDocketNumber = + getCaseDeadlinesByDocketNumberMock as jest.Mock; + describe('createCaseDeadlineInteractor', () => { const mockCaseDeadline = { deadlineDate: '2019-03-01T21:42:29.073Z', @@ -37,17 +42,10 @@ describe('createCaseDeadlineInteractor', () => { applicationContext.environment.stage = 'local'; - applicationContext - .getPersistenceGateway() - .createCaseDeadline.mockImplementation(v => v); applicationContext .getPersistenceGateway() .getCaseByDocketNumber.mockImplementation(() => mockCase); - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([ - { deadline: 'something' }, - ]); + getCaseDeadlinesByDocketNumber.mockReturnValue([{ deadline: 'something' }]); }); it('throws an error if the user is not valid or authorized', async () => { diff --git a/web-api/src/business/useCases/caseDeadline/createCaseDeadlineInteractor.ts b/web-api/src/business/useCases/caseDeadline/createCaseDeadlineInteractor.ts index 9e040f51c51..0fa4fa20322 100644 --- a/web-api/src/business/useCases/caseDeadline/createCaseDeadlineInteractor.ts +++ b/web-api/src/business/useCases/caseDeadline/createCaseDeadlineInteractor.ts @@ -7,6 +7,7 @@ import { import { ServerApplicationContext } from '@web-api/applicationContext'; import { UnauthorizedError } from '@web-api/errors/errors'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; +import { upsertCaseDeadlines } from '@web-api/persistence/postgres/caseDeadlines/upsertCaseDeadlines'; import { withLocking } from '@web-api/business/useCaseHelper/acquireLock'; export const createCaseDeadline = async ( @@ -26,22 +27,14 @@ export const createCaseDeadline = async ( }); let caseEntity = new Case(caseDetail, { authorizedUser }); - const newCaseDeadline = new CaseDeadline( - { - ...caseDeadline, - associatedJudge: caseEntity.associatedJudge, - associatedJudgeId: caseEntity.associatedJudgeId, - }, - { - applicationContext, - }, - ); - - await applicationContext.getPersistenceGateway().createCaseDeadline({ - applicationContext, - caseDeadline: newCaseDeadline.validate().toRawObject(), + const newCaseDeadline = new CaseDeadline({ + ...caseDeadline, + associatedJudge: caseEntity.associatedJudge, + associatedJudgeId: caseEntity.associatedJudgeId, }); + await upsertCaseDeadlines([newCaseDeadline.validate().toRawObject()]); + caseEntity = await applicationContext .getUseCaseHelpers() .updateCaseAutomaticBlock({ diff --git a/web-api/src/business/useCases/caseDeadline/deleteCaseDeadlineInteractor.test.ts b/web-api/src/business/useCases/caseDeadline/deleteCaseDeadlineInteractor.test.ts index 22e8958bc5d..f6d58e64684 100644 --- a/web-api/src/business/useCases/caseDeadline/deleteCaseDeadlineInteractor.test.ts +++ b/web-api/src/business/useCases/caseDeadline/deleteCaseDeadlineInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { AUTOMATIC_BLOCKED_REASONS } from '../../../../../shared/src/business/entities/EntityConstants'; @@ -9,8 +10,14 @@ import { } from '@web-api/errors/errors'; import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; import { deleteCaseDeadlineInteractor } from './deleteCaseDeadlineInteractor'; +import { deleteCaseDeadline as deleteCaseDeadlineMock } from '@web-api/persistence/postgres/caseDeadlines/deleteCaseDeadline'; +import { getCaseDeadlinesByDocketNumber as getCaseDeadlinesByDocketNumberMock } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { mockPetitionsClerkUser } from '@shared/test/mockAuthUsers'; +const getCaseDeadlinesByDocketNumber = + getCaseDeadlinesByDocketNumberMock as jest.Mock; +const deleteCaseDeadline = deleteCaseDeadlineMock as jest.Mock; + describe('deleteCaseDeadlineInteractor', () => { let user; let mockCase; @@ -27,9 +34,7 @@ describe('deleteCaseDeadlineInteractor', () => { .getPersistenceGateway() .getCaseByDocketNumber.mockReturnValue(mockCase); - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockImplementation(() => mockDeadlines); + getCaseDeadlinesByDocketNumber.mockImplementation(() => mockDeadlines); }); beforeEach(() => { @@ -107,12 +112,8 @@ describe('deleteCaseDeadlineInteractor', () => { mockPetitionsClerkUser, ); - expect( - applicationContext.getPersistenceGateway().deleteCaseDeadline.mock - .calls[0][0], - ).toMatchObject({ + expect(deleteCaseDeadline.mock.calls[0][0]).toMatchObject({ caseDeadlineId: '6805d1ab-18d0-43ec-bafb-654e83405416', - docketNumber: '123-20', }); expect( applicationContext.getPersistenceGateway().updateCase.mock.calls[0][0] @@ -140,12 +141,8 @@ describe('deleteCaseDeadlineInteractor', () => { mockPetitionsClerkUser, ); - expect( - applicationContext.getPersistenceGateway().deleteCaseDeadline.mock - .calls[0][0], - ).toMatchObject({ + expect(deleteCaseDeadline.mock.calls[0][0]).toMatchObject({ caseDeadlineId: '6805d1ab-18d0-43ec-bafb-654e83405416', - docketNumber: '123-20', }); expect( applicationContext.getPersistenceGateway().updateCase.mock.calls[0][0] diff --git a/web-api/src/business/useCases/caseDeadline/deleteCaseDeadlineInteractor.ts b/web-api/src/business/useCases/caseDeadline/deleteCaseDeadlineInteractor.ts index e950c02150a..e12318a6412 100644 --- a/web-api/src/business/useCases/caseDeadline/deleteCaseDeadlineInteractor.ts +++ b/web-api/src/business/useCases/caseDeadline/deleteCaseDeadlineInteractor.ts @@ -6,6 +6,7 @@ import { import { ServerApplicationContext } from '@web-api/applicationContext'; import { UnauthorizedError } from '@web-api/errors/errors'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; +import { deleteCaseDeadline as deleteDeadline } from '@web-api/persistence/postgres/caseDeadlines/deleteCaseDeadline'; import { withLocking } from '@web-api/business/useCaseHelper/acquireLock'; export const deleteCaseDeadline = async ( @@ -26,10 +27,8 @@ export const deleteCaseDeadline = async ( let updatedCase = new Case(caseToUpdate, { authorizedUser }); - await applicationContext.getPersistenceGateway().deleteCaseDeadline({ - applicationContext, + await deleteDeadline({ caseDeadlineId, - docketNumber, }); updatedCase = await applicationContext diff --git a/web-api/src/business/useCases/caseDeadline/getCaseDeadlinesForCaseInteractor.test.ts b/web-api/src/business/useCases/caseDeadline/getCaseDeadlinesForCaseInteractor.test.ts index 25e68fa89b9..9d4af097156 100644 --- a/web-api/src/business/useCases/caseDeadline/getCaseDeadlinesForCaseInteractor.test.ts +++ b/web-api/src/business/useCases/caseDeadline/getCaseDeadlinesForCaseInteractor.test.ts @@ -1,6 +1,11 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; +import { getCaseDeadlinesByDocketNumber as getCaseDeadlinesByDocketNumberMock } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { getCaseDeadlinesForCaseInteractor } from './getCaseDeadlinesForCaseInteractor'; +const getCaseDeadlinesByDocketNumber = + getCaseDeadlinesByDocketNumberMock as jest.Mock; + describe('getCaseDeadlinesForCaseInteractor', () => { const mockCaseDeadline = { associatedJudge: 'Buch', @@ -11,19 +16,14 @@ describe('getCaseDeadlinesForCaseInteractor', () => { }; it('gets the case deadlines', async () => { - applicationContext.environment.stage = 'local'; - - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([mockCaseDeadline]); + getCaseDeadlinesByDocketNumber.mockReturnValue([mockCaseDeadline]); applicationContext.getUniqueId.mockReturnValue( '6ba578e7-5736-435b-a41b-2de3eec29fe7', ); - const caseDeadlines = await getCaseDeadlinesForCaseInteractor( - applicationContext, - { docketNumber: mockCaseDeadline.docketNumber }, - ); + const caseDeadlines = await getCaseDeadlinesForCaseInteractor({ + docketNumber: mockCaseDeadline.docketNumber, + }); expect(caseDeadlines).toBeDefined(); }); diff --git a/web-api/src/business/useCases/caseDeadline/getCaseDeadlinesForCaseInteractor.ts b/web-api/src/business/useCases/caseDeadline/getCaseDeadlinesForCaseInteractor.ts index f8a52dd20b3..0d17b1c2469 100644 --- a/web-api/src/business/useCases/caseDeadline/getCaseDeadlinesForCaseInteractor.ts +++ b/web-api/src/business/useCases/caseDeadline/getCaseDeadlinesForCaseInteractor.ts @@ -1,26 +1,14 @@ import { CaseDeadline } from '../../../../../shared/src/business/entities/CaseDeadline'; -import { ServerApplicationContext } from '@web-api/applicationContext'; +import { getCaseDeadlinesByDocketNumber } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; -/** - * getCaseDeadlinesForCaseInteractor - * - * @param {object} applicationContext the application context - * @param {object} providers the providers object - * @param {string} providers.docketNumber the docket number of the case to get case deadlines for - * @returns {Promise} the promise of the getCaseDeadlines call - */ -export const getCaseDeadlinesForCaseInteractor = async ( - applicationContext: ServerApplicationContext, - { docketNumber }: { docketNumber: string }, -) => { - const caseDeadlines = await applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber({ - applicationContext, - docketNumber, - }); - - return CaseDeadline.validateRawCollection(caseDeadlines, { - applicationContext, +export const getCaseDeadlinesForCaseInteractor = async ({ + docketNumber, +}: { + docketNumber: string; +}) => { + const caseDeadlines = await getCaseDeadlinesByDocketNumber({ + docketNumber, }); + + return CaseDeadline.validateRawCollection(caseDeadlines); }; diff --git a/web-api/src/business/useCases/caseDeadline/updateCaseDeadlineInteractor.test.ts b/web-api/src/business/useCases/caseDeadline/updateCaseDeadlineInteractor.test.ts index 1a588295df6..16a3b93f3bc 100644 --- a/web-api/src/business/useCases/caseDeadline/updateCaseDeadlineInteractor.test.ts +++ b/web-api/src/business/useCases/caseDeadline/updateCaseDeadlineInteractor.test.ts @@ -1,24 +1,27 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; +import { CaseDeadline } from '@shared/business/entities/CaseDeadline'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; -import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; import { mockPetitionsClerkUser } from '@shared/test/mockAuthUsers'; import { updateCaseDeadlineInteractor } from './updateCaseDeadlineInteractor'; +import { upsertCaseDeadlines as upsertCaseDeadlinesMock } from '@web-api/persistence/postgres/caseDeadlines/upsertCaseDeadlines'; + +const upsertCaseDeadlines = upsertCaseDeadlinesMock as jest.Mock; describe('updateCaseDeadlineInteractor', () => { const CASE_DEADLINE_ID = '6805d1ab-18d0-43ec-bafb-654e83405416'; - const mockCaseDeadline = { + const mockCaseDeadline = new CaseDeadline({ associatedJudge: 'Buch', associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', caseDeadlineId: CASE_DEADLINE_ID, deadlineDate: '2019-03-01T21:42:29.073Z', description: 'hello world', docketNumber: '123-20', - } as any; + }); it('throws an error if the user is not valid or authorized', async () => { await expect( updateCaseDeadlineInteractor( - applicationContext, { caseDeadline: mockCaseDeadline, }, @@ -28,29 +31,16 @@ describe('updateCaseDeadlineInteractor', () => { }); it('updates a case deadline', async () => { - applicationContext.environment.stage = 'local'; - const caseDeadline = await updateCaseDeadlineInteractor( - applicationContext, { caseDeadline: mockCaseDeadline, }, mockPetitionsClerkUser, ); - expect( - applicationContext.getPersistenceGateway().deleteCaseDeadline.mock - .calls[0][0], - ).toMatchObject({ - caseDeadlineId: CASE_DEADLINE_ID, - docketNumber: '123-20', - }); - expect( - applicationContext.getPersistenceGateway().createCaseDeadline.mock - .calls[0][0], - ).toMatchObject({ - caseDeadline: mockCaseDeadline, - }); + expect(upsertCaseDeadlines.mock.calls[0][0]).toMatchObject([ + mockCaseDeadline, + ]); expect(caseDeadline).toBeDefined(); }); }); diff --git a/web-api/src/business/useCases/caseDeadline/updateCaseDeadlineInteractor.ts b/web-api/src/business/useCases/caseDeadline/updateCaseDeadlineInteractor.ts index ffc19a64f35..89c4b4acd50 100644 --- a/web-api/src/business/useCases/caseDeadline/updateCaseDeadlineInteractor.ts +++ b/web-api/src/business/useCases/caseDeadline/updateCaseDeadlineInteractor.ts @@ -3,12 +3,11 @@ import { ROLE_PERMISSIONS, isAuthorized, } from '../../../../../shared/src/authorization/authorizationClientService'; -import { ServerApplicationContext } from '@web-api/applicationContext'; import { UnauthorizedError } from '@web-api/errors/errors'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; +import { upsertCaseDeadlines } from '@web-api/persistence/postgres/caseDeadlines/upsertCaseDeadlines'; export const updateCaseDeadlineInteractor = async ( - applicationContext: ServerApplicationContext, { caseDeadline }: { caseDeadline: CaseDeadline }, authorizedUser: UnknownAuthUser, ) => { @@ -16,22 +15,11 @@ export const updateCaseDeadlineInteractor = async ( throw new UnauthorizedError('Unauthorized for updating case deadline'); } - const caseDeadlineToUpdate = new CaseDeadline(caseDeadline, { - applicationContext, - }) + const caseDeadlineToUpdate = new CaseDeadline(caseDeadline) .validate() .toRawObject(); - await applicationContext.getPersistenceGateway().deleteCaseDeadline({ - applicationContext, - caseDeadlineId: caseDeadlineToUpdate.caseDeadlineId, - docketNumber: caseDeadlineToUpdate.docketNumber, - }); - - await applicationContext.getPersistenceGateway().createCaseDeadline({ - applicationContext, - caseDeadline: caseDeadlineToUpdate, - }); + await upsertCaseDeadlines([caseDeadlineToUpdate]); return caseDeadlineToUpdate; }; diff --git a/web-api/src/business/useCases/caseWorksheet/updateCaseWorksheetInteractor.test.ts b/web-api/src/business/useCases/caseWorksheet/updateCaseWorksheetInteractor.test.ts index c177ffd3625..fa5a779cb76 100644 --- a/web-api/src/business/useCases/caseWorksheet/updateCaseWorksheetInteractor.test.ts +++ b/web-api/src/business/useCases/caseWorksheet/updateCaseWorksheetInteractor.test.ts @@ -1,31 +1,31 @@ +import '@web-api/persistence/postgres/caseWorksheets/mocks.jest'; import { InvalidEntityError, UnauthorizedError } from '@web-api/errors/errors'; import { RawCaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; -import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; +import { getCaseWorksheetsByDocketNumber as getCaseWorksheetsByDocketNumberMock } from '@web-api/persistence/postgres/caseWorksheets/getCaseWorksheetsByDocketNumber'; import { judgeColvin } from '@shared/test/mockUsers'; import { mockChambersUser, mockPetitionsClerkUser, } from '@shared/test/mockAuthUsers'; import { updateCaseWorksheetInteractor } from './updateCaseWorksheetInteractor'; +import { upsertCaseWorksheets as upsertCaseWorksheetsMock } from '@web-api/persistence/postgres/caseWorksheets/upsertCaseWorksheets'; + +const getCaseWorksheetsByDocketNumber = + getCaseWorksheetsByDocketNumberMock as jest.Mock; +const upsertCaseWorksheets = upsertCaseWorksheetsMock as jest.Mock; describe('updateCaseWorksheetInteractor', () => { const mockCaseWorksheet: RawCaseWorksheet = { docketNumber: '101-23', entityName: 'CaseWorksheet', + judgeUserId: judgeColvin.userId, primaryIssue: 'Don`t go chasin waterfalls', }; - beforeAll(() => { - applicationContext - .getUseCaseHelpers() - .getJudgeForUserHelper.mockReturnValue(judgeColvin); - }); - it('should throw an error when the user does not have access to the case worksheet feature', async () => { await expect( updateCaseWorksheetInteractor( - applicationContext, { worksheet: mockCaseWorksheet, }, @@ -35,13 +35,8 @@ describe('updateCaseWorksheetInteractor', () => { }); it('should throw an error when the updated case worksheet is invalid', async () => { - applicationContext - .getPersistenceGateway() - .getUserById.mockReturnValue(judgeColvin); - await expect( updateCaseWorksheetInteractor( - applicationContext, { worksheet: { ...mockCaseWorksheet, @@ -55,15 +50,9 @@ describe('updateCaseWorksheetInteractor', () => { it('should persist and return the updated case worksheet when the updates are valid', async () => { const mockFinalBriefDueDate = '2023-08-29'; - applicationContext - .getPersistenceGateway() - .getUserById.mockReturnValue(judgeColvin); - applicationContext - .getPersistenceGateway() - .getCaseWorksheet.mockResolvedValue(mockCaseWorksheet); + getCaseWorksheetsByDocketNumber.mockResolvedValue([mockCaseWorksheet]); const result = await updateCaseWorksheetInteractor( - applicationContext, { worksheet: { ...mockCaseWorksheet, @@ -77,27 +66,17 @@ describe('updateCaseWorksheetInteractor', () => { ...mockCaseWorksheet, finalBriefDueDate: mockFinalBriefDueDate, }; - expect( - applicationContext.getUseCaseHelpers().getJudgeInSectionHelper, - ).not.toHaveBeenCalled(); - expect( - applicationContext.getPersistenceGateway().updateCaseWorksheet, - ).toHaveBeenCalledWith({ - applicationContext: expect.anything(), - caseWorksheet: expectedUpdatedCaseWorksheet, - judgeUserId: judgeColvin.userId, - }); + expect(upsertCaseWorksheets).toHaveBeenCalledWith([ + expectedUpdatedCaseWorksheet, + ]); expect(result).toEqual(expectedUpdatedCaseWorksheet); }); it('should persist the updated case worksheet when the updates are valid, using the judge`s userId in the section when the current user is a chambers user', async () => { const mockFinalBriefDueDate = '2023-08-29'; - applicationContext - .getPersistenceGateway() - .getCaseWorksheet.mockResolvedValue(mockCaseWorksheet); + getCaseWorksheetsByDocketNumber.mockResolvedValue([mockCaseWorksheet]); const result = await updateCaseWorksheetInteractor( - applicationContext, { worksheet: { ...mockCaseWorksheet, @@ -111,19 +90,9 @@ describe('updateCaseWorksheetInteractor', () => { ...mockCaseWorksheet, finalBriefDueDate: mockFinalBriefDueDate, }; - expect( - applicationContext.getUseCaseHelpers().getJudgeForUserHelper.mock - .calls[0][1], - ).toEqual({ - user: mockChambersUser, - }); - expect( - applicationContext.getPersistenceGateway().updateCaseWorksheet, - ).toHaveBeenCalledWith({ - applicationContext: expect.anything(), - caseWorksheet: expectedUpdatedCaseWorksheet, - judgeUserId: judgeColvin.userId, - }); + expect(upsertCaseWorksheets).toHaveBeenCalledWith([ + expectedUpdatedCaseWorksheet, + ]); expect(result).toEqual(expectedUpdatedCaseWorksheet); }); }); diff --git a/web-api/src/business/useCases/caseWorksheet/updateCaseWorksheetInteractor.ts b/web-api/src/business/useCases/caseWorksheet/updateCaseWorksheetInteractor.ts index 92b85e1e96d..d10d83c4d6a 100644 --- a/web-api/src/business/useCases/caseWorksheet/updateCaseWorksheetInteractor.ts +++ b/web-api/src/business/useCases/caseWorksheet/updateCaseWorksheetInteractor.ts @@ -6,12 +6,11 @@ import { ROLE_PERMISSIONS, isAuthorized, } from '../../../../../shared/src/authorization/authorizationClientService'; -import { ServerApplicationContext } from '@web-api/applicationContext'; import { UnauthorizedError } from '@web-api/errors/errors'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; +import { upsertCaseWorksheets } from '@web-api/persistence/postgres/caseWorksheets/upsertCaseWorksheets'; export const updateCaseWorksheetInteractor = async ( - applicationContext: ServerApplicationContext, { worksheet, }: { @@ -23,19 +22,11 @@ export const updateCaseWorksheetInteractor = async ( throw new UnauthorizedError('Unauthorized'); } - const judgeUser = await applicationContext - .getUseCaseHelpers() - .getJudgeForUserHelper(applicationContext, { user: authorizedUser }); - const caseWorksheetEntity = new CaseWorksheet(worksheet).validate(); const rawCaseWorksheet = caseWorksheetEntity.toRawObject(); - await applicationContext.getPersistenceGateway().updateCaseWorksheet({ - applicationContext, - caseWorksheet: rawCaseWorksheet, - judgeUserId: judgeUser.userId, - }); + await upsertCaseWorksheets([rawCaseWorksheet]); return rawCaseWorksheet; }; diff --git a/web-api/src/business/useCases/checkForReadyForTrialCasesInteractor.test.ts b/web-api/src/business/useCases/checkForReadyForTrialCasesInteractor.test.ts index 95b4870b6e3..e0f95e8f6d7 100644 --- a/web-api/src/business/useCases/checkForReadyForTrialCasesInteractor.test.ts +++ b/web-api/src/business/useCases/checkForReadyForTrialCasesInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/messages/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; diff --git a/web-api/src/business/useCases/correspondence/archiveCorrespondenceDocumentInteractor.test.ts b/web-api/src/business/useCases/correspondence/archiveCorrespondenceDocumentInteractor.test.ts index 84014ec126e..e5c5dffde01 100644 --- a/web-api/src/business/useCases/correspondence/archiveCorrespondenceDocumentInteractor.test.ts +++ b/web-api/src/business/useCases/correspondence/archiveCorrespondenceDocumentInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { Correspondence } from '../../../../../shared/src/business/entities/Correspondence'; @@ -8,6 +9,9 @@ import { ServiceUnavailableError } from '@web-api/errors/errors'; import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; import { archiveCorrespondenceDocumentInteractor } from './archiveCorrespondenceDocumentInteractor'; import { mockDocketClerkUser } from '@shared/test/mockAuthUsers'; +import { upsertCaseCorrespondences as upsertCaseCorrespondencesMock } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; + +const upsertCaseCorrespondences = upsertCaseCorrespondencesMock as jest.Mock; describe('archiveCorrespondenceDocumentInteractor', () => { let mockUserId = '2474e5c0-f741-4120-befa-b77378ac8bf0'; @@ -25,6 +29,7 @@ describe('archiveCorrespondenceDocumentInteractor', () => { mockLock = undefined; mockCorrespondence = new Correspondence({ correspondenceId: mockCorrespondenceId, + docketNumber: MOCK_CASE.docketNumber, documentTitle: 'My Correspondence', filedBy: 'Docket clerk', userId: mockUserId, @@ -81,16 +86,9 @@ describe('archiveCorrespondenceDocumentInteractor', () => { mockDocketClerkUser, ); - expect( - applicationContext.getPersistenceGateway().updateCaseCorrespondence.mock - .calls[0][0], - ).toMatchObject({ - correspondence: { - ...mockCorrespondence, - archived: true, - }, - docketNumber: MOCK_CASE.docketNumber, - }); + expect(upsertCaseCorrespondences.mock.calls[0][0]).toMatchObject([ + { ...mockCorrespondence, archived: true }, + ]); }); it('should update the case to reflect the archived correspondence', async () => { diff --git a/web-api/src/business/useCases/correspondence/archiveCorrespondenceDocumentInteractor.ts b/web-api/src/business/useCases/correspondence/archiveCorrespondenceDocumentInteractor.ts index 758b9d52246..e94f072e60d 100644 --- a/web-api/src/business/useCases/correspondence/archiveCorrespondenceDocumentInteractor.ts +++ b/web-api/src/business/useCases/correspondence/archiveCorrespondenceDocumentInteractor.ts @@ -6,6 +6,7 @@ import { import { ServerApplicationContext } from '@web-api/applicationContext'; import { UnauthorizedError } from '@web-api/errors/errors'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; +import { upsertCaseCorrespondences } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; import { withLocking } from '@web-api/business/useCaseHelper/acquireLock'; export const archiveCorrespondenceDocument = async ( @@ -36,11 +37,9 @@ export const archiveCorrespondenceDocument = async ( caseEntity.archiveCorrespondence(correspondenceToArchiveEntity); - await applicationContext.getPersistenceGateway().updateCaseCorrespondence({ - applicationContext, - correspondence: correspondenceToArchiveEntity.validate().toRawObject(), - docketNumber, - }); + await upsertCaseCorrespondences([ + correspondenceToArchiveEntity.validate().toRawObject(), + ]); await applicationContext.getUseCaseHelpers().updateCaseAndAssociations({ applicationContext, diff --git a/web-api/src/business/useCases/correspondence/fileCorrespondenceDocumentInteractor.test.ts b/web-api/src/business/useCases/correspondence/fileCorrespondenceDocumentInteractor.test.ts index c3b9005e29b..999302ed380 100644 --- a/web-api/src/business/useCases/correspondence/fileCorrespondenceDocumentInteractor.test.ts +++ b/web-api/src/business/useCases/correspondence/fileCorrespondenceDocumentInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; import { CASE_TYPES_MAP, CONTACT_TYPES, @@ -13,6 +14,9 @@ import { mockDocketClerkUser, mockPetitionerUser, } from '@shared/test/mockAuthUsers'; +import { upsertCaseCorrespondences as upsertCaseCorrespondencesMock } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; + +const upsertCaseCorrespondences = upsertCaseCorrespondencesMock as jest.Mock; describe('fileCorrespondenceDocumentInteractor', () => { const mockCase = { @@ -119,19 +123,16 @@ describe('fileCorrespondenceDocumentInteractor', () => { }, docketClerkUser, ); - expect( - applicationContext.getPersistenceGateway().updateCaseCorrespondence.mock - .calls[0][0], - ).toMatchObject({ - correspondence: { + expect(upsertCaseCorrespondences.mock.calls[0][0]).toMatchObject([ + { correspondenceId: mockCorrespondenceId, + docketNumber: mockCase.docketNumber, documentTitle: mockDocumentTitle, filedBy: docketClerkUser.name, filingDate: mockFilingDate, userId: docketClerkUser.userId, }, - docketNumber: mockCase.docketNumber, - }); + ]); }); it('should return an updated raw case object', async () => { @@ -156,6 +157,7 @@ describe('fileCorrespondenceDocumentInteractor', () => { correspondence: [ { correspondenceId: mockCorrespondenceId, + docketNumber: mockCase.docketNumber, documentTitle: mockDocumentTitle, filedBy: docketClerkUser.name, filingDate: mockFilingDate, diff --git a/web-api/src/business/useCases/correspondence/fileCorrespondenceDocumentInteractor.ts b/web-api/src/business/useCases/correspondence/fileCorrespondenceDocumentInteractor.ts index 75fdb4eacea..ff0d3140d9e 100644 --- a/web-api/src/business/useCases/correspondence/fileCorrespondenceDocumentInteractor.ts +++ b/web-api/src/business/useCases/correspondence/fileCorrespondenceDocumentInteractor.ts @@ -7,6 +7,7 @@ import { } from '../../../../../shared/src/authorization/authorizationClientService'; import { ServerApplicationContext } from '@web-api/applicationContext'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; +import { upsertCaseCorrespondences } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; /** * fileCorrespondenceDocumentInteractor @@ -51,6 +52,7 @@ export const fileCorrespondenceDocumentInteractor = async ( const correspondenceEntity = new Correspondence({ ...documentMetadata, correspondenceId: primaryDocumentFileId, + docketNumber: caseToUpdate.docketNumber, filedBy: user.name, userId: user.userId, }); @@ -58,11 +60,9 @@ export const fileCorrespondenceDocumentInteractor = async ( caseEntity.fileCorrespondence(correspondenceEntity); if (caseEntity.validate()) { - await applicationContext.getPersistenceGateway().updateCaseCorrespondence({ - applicationContext, - correspondence: correspondenceEntity.validate().toRawObject(), - docketNumber, - }); + await upsertCaseCorrespondences([ + correspondenceEntity.validate().toRawObject(), + ]); } return caseEntity.toRawObject(); diff --git a/web-api/src/business/useCases/correspondence/updateCorrespondenceDocumentInteractor.test.ts b/web-api/src/business/useCases/correspondence/updateCorrespondenceDocumentInteractor.test.ts index 1e3e186b510..17991576586 100644 --- a/web-api/src/business/useCases/correspondence/updateCorrespondenceDocumentInteractor.test.ts +++ b/web-api/src/business/useCases/correspondence/updateCorrespondenceDocumentInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; import { CASE_TYPES_MAP, CONTACT_TYPES, @@ -13,12 +14,18 @@ import { mockPetitionerUser, } from '@shared/test/mockAuthUsers'; import { updateCorrespondenceDocumentInteractor } from './updateCorrespondenceDocumentInteractor'; +import { upsertCaseCorrespondences as upsertCaseCorrespondencesMock } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; + +const upsertCaseCorrespondences = upsertCaseCorrespondencesMock as jest.Mock; describe('updateCorrespondenceDocumentInteractor', () => { const mockDocketEntryId = 'cf105788-5d34-4451-aa8d-dfd9a851b675'; + const docketNumber = '123-45'; + const mockCorrespondence = new Correspondence({ correspondenceId: '74e36bf7-dcbd-4ee7-a9ec-6d7446096df8', + docketNumber, documentTitle: 'old document title', filedBy: 'docket clerk', userId: '5980d666-641d-455a-8386-18908d50c98e', @@ -31,7 +38,7 @@ describe('updateCorrespondenceDocumentInteractor', () => { docketEntries: [ { docketEntryId: mockDocketEntryId, - docketNumber: '123-45', + docketNumber, documentTitle: 'Docket Record 1', documentType: 'Order that case is assigned', eventCode: 'OAJ', @@ -44,7 +51,7 @@ describe('updateCorrespondenceDocumentInteractor', () => { userId: '2474e5c0-f741-4120-befa-b77378ac8bf0', }, ], - docketNumber: '123-45', + docketNumber, filingType: 'Myself', partyType: PARTY_TYPES.petitioner, petitioners: [ @@ -95,16 +102,12 @@ describe('updateCorrespondenceDocumentInteractor', () => { mockDocketClerkUser, ); - expect( - applicationContext.getPersistenceGateway().updateCaseCorrespondence.mock - .calls[0][0], - ).toMatchObject({ - correspondence: { + expect(upsertCaseCorrespondences.mock.calls[0][0]).toMatchObject([ + { ...mockCorrespondence, documentTitle: 'A title that has been updated', }, - docketNumber: mockCase.docketNumber, - }); + ]); }); it('should return an updated raw case object', async () => { diff --git a/web-api/src/business/useCases/correspondence/updateCorrespondenceDocumentInteractor.ts b/web-api/src/business/useCases/correspondence/updateCorrespondenceDocumentInteractor.ts index 80228e52194..f513fb7657d 100644 --- a/web-api/src/business/useCases/correspondence/updateCorrespondenceDocumentInteractor.ts +++ b/web-api/src/business/useCases/correspondence/updateCorrespondenceDocumentInteractor.ts @@ -7,6 +7,7 @@ import { import { ServerApplicationContext } from '@web-api/applicationContext'; import { UnauthorizedError } from '@web-api/errors/errors'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; +import { upsertCaseCorrespondences } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; export const updateCorrespondenceDocumentInteractor = async ( applicationContext: ServerApplicationContext, @@ -34,6 +35,7 @@ export const updateCorrespondenceDocumentInteractor = async ( const updatedCorrespondenceEntity = new Correspondence({ ...currentCorrespondenceDocument, + docketNumber: caseToUpdate.docketNumber, documentTitle: documentMetadata.documentTitle, }); @@ -41,11 +43,9 @@ export const updateCorrespondenceDocumentInteractor = async ( const caseEntityRaw = caseEntity.validate().toRawObject(); - await applicationContext.getPersistenceGateway().updateCaseCorrespondence({ - applicationContext, - correspondence: updatedCorrespondenceEntity.validate().toRawObject(), - docketNumber, - }); + await upsertCaseCorrespondences([ + updatedCorrespondenceEntity.validate().toRawObject(), + ]); return caseEntityRaw; }; diff --git a/web-api/src/business/useCases/courtIssuedDocument/fileAndServeCourtIssuedDocumentInteractor.locking.test.ts b/web-api/src/business/useCases/courtIssuedDocument/fileAndServeCourtIssuedDocumentInteractor.locking.test.ts index e2154bc8b36..c3bdb0b802e 100644 --- a/web-api/src/business/useCases/courtIssuedDocument/fileAndServeCourtIssuedDocumentInteractor.locking.test.ts +++ b/web-api/src/business/useCases/courtIssuedDocument/fileAndServeCourtIssuedDocumentInteractor.locking.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { MOCK_CASE } from '../../../../../shared/src/test/mockCase'; diff --git a/web-api/src/business/useCases/courtIssuedDocument/fileAndServeCourtIssuedDocumentInteractor.ts b/web-api/src/business/useCases/courtIssuedDocument/fileAndServeCourtIssuedDocumentInteractor.ts index 42470ac99ce..be7564ca8ae 100644 --- a/web-api/src/business/useCases/courtIssuedDocument/fileAndServeCourtIssuedDocumentInteractor.ts +++ b/web-api/src/business/useCases/courtIssuedDocument/fileAndServeCourtIssuedDocumentInteractor.ts @@ -194,7 +194,6 @@ export const fileAndServeCourtIssuedDocument = async ( if (isSubjectCase && docketEntryEntity.shouldAutoGenerateDeadline()) { await applicationContext.getUseCaseHelpers().autoGenerateDeadline({ - applicationContext, deadlineDate: docketEntryEntity.date, description: docketEntryEntity.getAutoGeneratedDeadlineDescription(), diff --git a/web-api/src/business/useCases/courtIssuedDocument/serveCourtIssuedDocumentInteractor.ts b/web-api/src/business/useCases/courtIssuedDocument/serveCourtIssuedDocumentInteractor.ts index 48e73cb70eb..5bc7619cff0 100644 --- a/web-api/src/business/useCases/courtIssuedDocument/serveCourtIssuedDocumentInteractor.ts +++ b/web-api/src/business/useCases/courtIssuedDocument/serveCourtIssuedDocumentInteractor.ts @@ -85,7 +85,6 @@ export const serveCourtIssuedDocument = async ( if (docketEntryToServe.shouldAutoGenerateDeadline()) { await applicationContext.getUseCaseHelpers().autoGenerateDeadline({ - applicationContext, deadlineDate: docketEntryToServe.date, description: docketEntryToServe.getAutoGeneratedDeadlineDescription(), subjectCaseEntity, diff --git a/web-api/src/business/useCases/docketEntry/addPaperFilingInteractor.locking.test.ts b/web-api/src/business/useCases/docketEntry/addPaperFilingInteractor.locking.test.ts index c94f5e5538d..31d74ff78c7 100644 --- a/web-api/src/business/useCases/docketEntry/addPaperFilingInteractor.locking.test.ts +++ b/web-api/src/business/useCases/docketEntry/addPaperFilingInteractor.locking.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { MOCK_CASE } from '../../../../../shared/src/test/mockCase'; diff --git a/web-api/src/business/useCases/docketEntry/addPaperFilingInteractor.test.ts b/web-api/src/business/useCases/docketEntry/addPaperFilingInteractor.test.ts index 89ea939a9c9..749627f527b 100644 --- a/web-api/src/business/useCases/docketEntry/addPaperFilingInteractor.test.ts +++ b/web-api/src/business/useCases/docketEntry/addPaperFilingInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/messages/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; @@ -15,9 +16,13 @@ import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; import { addPaperFilingInteractor } from './addPaperFilingInteractor'; import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; import { docketClerkUser } from '../../../../../shared/src/test/mockUsers'; +import { getCaseDeadlinesByDocketNumber as getCaseDeadlinesByDocketNumberMock } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { mockDocketClerkUser } from '@shared/test/mockAuthUsers'; import { saveWorkItem as saveWorkItemMock } from '@web-api/persistence/postgres/workitems/saveWorkItem'; +const getCaseDeadlinesByDocketNumber = + getCaseDeadlinesByDocketNumberMock as jest.Mock; + describe('addPaperFilingInteractor', () => { const saveWorkItem = saveWorkItemMock as jest.Mock; const mockClientConnectionId = '987654'; @@ -323,11 +328,7 @@ describe('addPaperFilingInteractor', () => { }); it('sets the case as blocked with due dates if the document filed is a tracked document type and the case has due dates', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([ - { deadline: 'something' }, - ]); + getCaseDeadlinesByDocketNumber.mockReturnValue([{ deadline: 'something' }]); await addPaperFilingInteractor( applicationContext, diff --git a/web-api/src/business/useCases/docketEntry/completeDocketEntryQCInteractor.test.ts b/web-api/src/business/useCases/docketEntry/completeDocketEntryQCInteractor.test.ts index 7c2c7907777..83c911b6c6c 100644 --- a/web-api/src/business/useCases/docketEntry/completeDocketEntryQCInteractor.test.ts +++ b/web-api/src/business/useCases/docketEntry/completeDocketEntryQCInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { diff --git a/web-api/src/business/useCases/docketEntry/editPaperFilingInteractor.locking.test.ts b/web-api/src/business/useCases/docketEntry/editPaperFilingInteractor.locking.test.ts index fe3ae953aef..d8f96e51e89 100644 --- a/web-api/src/business/useCases/docketEntry/editPaperFilingInteractor.locking.test.ts +++ b/web-api/src/business/useCases/docketEntry/editPaperFilingInteractor.locking.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { MOCK_CASE } from '../../../../../shared/src/test/mockCase'; diff --git a/web-api/src/business/useCases/docketEntry/editPaperFilingInteractor.test.ts b/web-api/src/business/useCases/docketEntry/editPaperFilingInteractor.test.ts index c956c80f79a..21c307c788e 100644 --- a/web-api/src/business/useCases/docketEntry/editPaperFilingInteractor.test.ts +++ b/web-api/src/business/useCases/docketEntry/editPaperFilingInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { diff --git a/web-api/src/business/useCases/docketEntry/sealDocketEntryInteractor.test.ts b/web-api/src/business/useCases/docketEntry/sealDocketEntryInteractor.test.ts index c247a119f66..6cb9bbc2eac 100644 --- a/web-api/src/business/useCases/docketEntry/sealDocketEntryInteractor.test.ts +++ b/web-api/src/business/useCases/docketEntry/sealDocketEntryInteractor.test.ts @@ -42,6 +42,9 @@ describe('sealDocketEntryInteractor', () => { }); it('should throw an error when the docket entry is not found', async () => { + applicationContext + .getPersistenceGateway() + .getCaseByDocketNumber.mockReturnValue(MOCK_CASE); await expect( sealDocketEntryInteractor( applicationContext, diff --git a/web-api/src/business/useCases/docketEntry/unsealDocketEntryInteractor.test.ts b/web-api/src/business/useCases/docketEntry/unsealDocketEntryInteractor.test.ts index 9e7e677a647..763e37e4484 100644 --- a/web-api/src/business/useCases/docketEntry/unsealDocketEntryInteractor.test.ts +++ b/web-api/src/business/useCases/docketEntry/unsealDocketEntryInteractor.test.ts @@ -10,6 +10,9 @@ import { unsealDocketEntryInteractor } from './unsealDocketEntryInteractor'; describe('unsealDocketEntryInteractor', () => { const answerDocketEntryId = 'e6b81f4d-1e47-423a-8caf-6d2fdc3d3859'; + applicationContext + .getPersistenceGateway() + .getCaseByDocketNumber.mockReturnValue(MOCK_CASE); it('should only allow docket clerks to unseal a docket entry', async () => { await expect( @@ -38,9 +41,6 @@ describe('unsealDocketEntryInteractor', () => { }); it('should mark the docket entry as unsealed and save', async () => { - applicationContext - .getPersistenceGateway() - .getCaseByDocketNumber.mockReturnValue(MOCK_CASE); const unsealedDocketEntry = await unsealDocketEntryInteractor( applicationContext, { diff --git a/web-api/src/business/useCases/docketEntry/updateDocketEntryMetaInteractor.test.ts b/web-api/src/business/useCases/docketEntry/updateDocketEntryMetaInteractor.test.ts index 43d38fc66f3..91c3ed8a1ee 100644 --- a/web-api/src/business/useCases/docketEntry/updateDocketEntryMetaInteractor.test.ts +++ b/web-api/src/business/useCases/docketEntry/updateDocketEntryMetaInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { MOCK_CASE } from '../../../../../shared/src/test/mockCase'; diff --git a/web-api/src/business/useCases/externalDocument/fileExternalDocumentInteractor.test.ts b/web-api/src/business/useCases/externalDocument/fileExternalDocumentInteractor.test.ts index ea057ea4eb9..866175d6502 100644 --- a/web-api/src/business/useCases/externalDocument/fileExternalDocumentInteractor.test.ts +++ b/web-api/src/business/useCases/externalDocument/fileExternalDocumentInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { @@ -16,12 +17,16 @@ import { MOCK_LOCK } from '@shared/test/mockLock'; import { ServiceUnavailableError } from '@web-api/errors/errors'; import { applicationContext } from '@shared/business/test/createTestApplicationContext'; import { fileExternalDocumentInteractor } from './fileExternalDocumentInteractor'; +import { getCaseDeadlinesByDocketNumber as getCaseDeadlinesByDocketNumberMock } from '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { mockDocketClerkUser, mockIrsPractitionerUser, } from '@shared/test/mockAuthUsers'; import { saveWorkItem as saveWorkItemMock } from '@web-api/persistence/postgres/workitems/saveWorkItem'; +const getCaseDeadlinesByDocketNumber = + getCaseDeadlinesByDocketNumberMock as jest.Mock; + describe('fileExternalDocumentInteractor', () => { const saveWorkItem = saveWorkItemMock as jest.Mock; const mockDocketEntryId = applicationContext.getUniqueId(); @@ -504,13 +509,11 @@ describe('fileExternalDocumentInteractor', () => { }); it('should automatically block the case with deadlines if the document filed is a tracked document and the case has a deadline', async () => { - applicationContext - .getPersistenceGateway() - .getCaseDeadlinesByDocketNumber.mockReturnValue([ - { - deadlineDate: 'something', - }, - ]); + getCaseDeadlinesByDocketNumber.mockReturnValue([ + { + deadlineDate: 'something', + }, + ]); await fileExternalDocumentInteractor( applicationContext, diff --git a/web-api/src/business/useCases/judgeActivityReport/getCaseWorksheetsByJudgeInteractor.test.ts b/web-api/src/business/useCases/judgeActivityReport/getCaseWorksheetsByJudgeInteractor.test.ts index 3e8884b3db5..0c9272883fd 100644 --- a/web-api/src/business/useCases/judgeActivityReport/getCaseWorksheetsByJudgeInteractor.test.ts +++ b/web-api/src/business/useCases/judgeActivityReport/getCaseWorksheetsByJudgeInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseWorksheets/mocks.jest'; import { CASE_STATUS_TYPES } from '@shared/business/entities/EntityConstants'; import { GetCasesByStatusAndByJudgeRequest, @@ -11,12 +12,16 @@ import { import { MOCK_CASE_WORKSHEET } from '@shared/test/mockCaseWorksheet'; import { RawCaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; +import { getCaseWorksheetsByDocketNumber as getCaseWorksheetsByDocketNumberMock } from '@web-api/persistence/postgres/caseWorksheets/getCaseWorksheetsByDocketNumber'; import { judgeUser } from '@shared/test/mockUsers'; import { mockJudgeUser, mockPetitionsClerkUser, } from '@shared/test/mockAuthUsers'; +const getCaseWorksheetsByDocketNumber = + getCaseWorksheetsByDocketNumberMock as jest.Mock; + describe('getCaseWorksheetsByJudgeInteractor', () => { let mockGetDocketNumbersByStatusAndByJudgeResult: RawCase[] = []; @@ -52,12 +57,10 @@ describe('getCaseWorksheetsByJudgeInteractor', () => { beforeAll(() => { applicationContext.getSearchClient().count = jest.fn(); - applicationContext - .getPersistenceGateway() - .getCaseWorksheetsByDocketNumber.mockImplementation(() => [ - mockCaseWorksheet10123, - mockCaseWorksheet10223, - ]); + getCaseWorksheetsByDocketNumber.mockImplementation(() => [ + mockCaseWorksheet10123, + mockCaseWorksheet10223, + ]); }); applicationContext .getPersistenceGateway() diff --git a/web-api/src/business/useCases/judgeActivityReport/getCaseWorksheetsByJudgeInteractor.ts b/web-api/src/business/useCases/judgeActivityReport/getCaseWorksheetsByJudgeInteractor.ts index 38fe6015f59..54f86d99c58 100644 --- a/web-api/src/business/useCases/judgeActivityReport/getCaseWorksheetsByJudgeInteractor.ts +++ b/web-api/src/business/useCases/judgeActivityReport/getCaseWorksheetsByJudgeInteractor.ts @@ -8,6 +8,7 @@ import { RawCaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWo import { ServerApplicationContext } from '@web-api/applicationContext'; import { SubmittedCAVTableFields } from '@web-api/persistence/elasticsearch/getDocketNumbersByStatusAndByJudge'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; +import { getCaseWorksheetsByDocketNumber } from '@web-api/persistence/postgres/caseWorksheets/getCaseWorksheetsByDocketNumber'; export type GetCasesByStatusAndByJudgeRequest = { statuses: string[]; @@ -71,10 +72,7 @@ const getCases = async ( }, }); - const completeCaseRecords = await attachCaseWorkSheets( - applicationContext, - allCaseRecords, - ); + const completeCaseRecords = await attachCaseWorkSheets(allCaseRecords); return completeCaseRecords; }; @@ -95,16 +93,10 @@ const calculateNumberOfConsolidatedCases = async ( }); }; -async function attachCaseWorkSheets( - applicationContext: ServerApplicationContext, - cases: SubmittedCAVTableFields[], -) { - const caseWorksheets = await applicationContext - .getPersistenceGateway() - .getCaseWorksheetsByDocketNumber({ - applicationContext, - docketNumbers: cases.map(c => c.docketNumber), - }); +async function attachCaseWorkSheets(cases: SubmittedCAVTableFields[]) { + const caseWorksheets = await getCaseWorksheetsByDocketNumber({ + docketNumbers: cases.map(c => c.docketNumber), + }); const caseWorksheetMap: Map = new Map(); caseWorksheets.forEach(caseWorksheet => caseWorksheetMap.set(caseWorksheet.docketNumber, caseWorksheet), diff --git a/web-api/src/business/useCases/processStreamRecords/processCaseCorrespondenceEntries.test.ts b/web-api/src/business/useCases/processStreamRecords/processCaseCorrespondenceEntries.test.ts new file mode 100644 index 00000000000..a5d5507f24b --- /dev/null +++ b/web-api/src/business/useCases/processStreamRecords/processCaseCorrespondenceEntries.test.ts @@ -0,0 +1,30 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; +import { processCaseCorrespondenceEntries } from '@web-api/business/useCases/processStreamRecords/processCaseCorrespondenceEntries'; +import { upsertCaseCorrespondences } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; + +describe('processCaseCorrespondenceEntries', () => { + beforeEach(() => { + (upsertCaseCorrespondences as jest.Mock).mockResolvedValue(undefined); + }); + + it('should attempt to store case correspondences using the upsert method', async () => { + const mockDynamoCaseCorrespondence = { + dynamodb: { + NewImage: { + docketNumber: { + S: '123-45', + }, + entityName: { + S: 'CaseCorrespondence', + }, + }, + }, + }; + + await processCaseCorrespondenceEntries({ + caseCorrespondenceRecords: [mockDynamoCaseCorrespondence], + }); + + expect(upsertCaseCorrespondences).toHaveBeenCalled(); + }); +}); diff --git a/web-api/src/business/useCases/processStreamRecords/processCaseCorrespondenceEntries.ts b/web-api/src/business/useCases/processStreamRecords/processCaseCorrespondenceEntries.ts new file mode 100644 index 00000000000..cafa536099e --- /dev/null +++ b/web-api/src/business/useCases/processStreamRecords/processCaseCorrespondenceEntries.ts @@ -0,0 +1,22 @@ +import { RawCorrespondence } from '@shared/business/entities/Correspondence'; +import { getLogger } from 'aws-xray-sdk'; +import { unmarshall } from '@aws-sdk/util-dynamodb'; +import { upsertCaseCorrespondences } from '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences'; + +export const processCaseCorrespondenceEntries = async ({ + caseCorrespondenceRecords, +}: { + caseCorrespondenceRecords: any[]; +}) => { + if (!caseCorrespondenceRecords.length) return; + + getLogger().debug( + `going to upsert ${caseCorrespondenceRecords.length} correspondence records`, + ); + + await upsertCaseCorrespondences( + caseCorrespondenceRecords.map(record => { + return unmarshall(record.dynamodb.NewImage) as RawCorrespondence; + }), + ); +}; diff --git a/web-api/src/business/useCases/processStreamRecords/processCaseDeadlineEntries.test.ts b/web-api/src/business/useCases/processStreamRecords/processCaseDeadlineEntries.test.ts new file mode 100644 index 00000000000..b7c0d8b0283 --- /dev/null +++ b/web-api/src/business/useCases/processStreamRecords/processCaseDeadlineEntries.test.ts @@ -0,0 +1,30 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; +import { processCaseDeadlineEntries } from '@web-api/business/useCases/processStreamRecords/processCaseDeadlineEntries'; +import { upsertCaseDeadlines } from '@web-api/persistence/postgres/caseDeadlines/upsertCaseDeadlines'; + +describe('processCaseDeadlineEntries', () => { + beforeEach(() => { + (upsertCaseDeadlines as jest.Mock).mockResolvedValue(undefined); + }); + + it('should attempt to store case deadlines using the upsert method', async () => { + const mockDynamoCaseDeadlines = { + dynamodb: { + NewImage: { + docketNumber: { + S: '123-45', + }, + entityName: { + S: 'CaseDeadline', + }, + }, + }, + }; + + await processCaseDeadlineEntries({ + caseDeadlineRecords: [mockDynamoCaseDeadlines], + }); + + expect(upsertCaseDeadlines).toHaveBeenCalled(); + }); +}); diff --git a/web-api/src/business/useCases/processStreamRecords/processCaseDeadlineEntries.ts b/web-api/src/business/useCases/processStreamRecords/processCaseDeadlineEntries.ts new file mode 100644 index 00000000000..cefd9adf977 --- /dev/null +++ b/web-api/src/business/useCases/processStreamRecords/processCaseDeadlineEntries.ts @@ -0,0 +1,22 @@ +import { RawCaseDeadline } from '@shared/business/entities/CaseDeadline'; +import { getLogger } from 'aws-xray-sdk'; +import { unmarshall } from '@aws-sdk/util-dynamodb'; +import { upsertCaseDeadlines } from '@web-api/persistence/postgres/caseDeadlines/upsertCaseDeadlines'; + +export const processCaseDeadlineEntries = async ({ + caseDeadlineRecords, +}: { + caseDeadlineRecords: any[]; +}) => { + if (!caseDeadlineRecords.length) return; + + getLogger().debug( + `going to upsert ${caseDeadlineRecords.length} case deadline records`, + ); + + await upsertCaseDeadlines( + caseDeadlineRecords.map(record => { + return unmarshall(record.dynamodb.NewImage) as RawCaseDeadline; + }), + ); +}; diff --git a/web-api/src/business/useCases/processStreamRecords/processCaseWorksheetEntries.test.ts b/web-api/src/business/useCases/processStreamRecords/processCaseWorksheetEntries.test.ts new file mode 100644 index 00000000000..752549b3462 --- /dev/null +++ b/web-api/src/business/useCases/processStreamRecords/processCaseWorksheetEntries.test.ts @@ -0,0 +1,29 @@ +import '@web-api/persistence/postgres/caseWorksheets/mocks.jest'; +import { processCaseWorksheetEntries } from '@web-api/business/useCases/processStreamRecords/processCaseWorksheetEntries'; +import { upsertCaseWorksheets } from '@web-api/persistence/postgres/caseWorksheets/upsertCaseWorksheets'; +describe('processCaseWorksheetEntries', () => { + beforeEach(() => { + (upsertCaseWorksheets as jest.Mock).mockResolvedValue(undefined); + }); + + it('should attempt to store case worksheets using the upsert method', async () => { + const mockDynamoCaseWorksheets = { + dynamodb: { + NewImage: { + docketNumber: { + S: '123-45', + }, + entityName: { + S: 'CaseWorksheet', + }, + }, + }, + }; + + await processCaseWorksheetEntries({ + caseWorksheetRecords: [mockDynamoCaseWorksheets], + }); + + expect(upsertCaseWorksheets).toHaveBeenCalled(); + }); +}); diff --git a/web-api/src/business/useCases/processStreamRecords/processCaseWorksheetEntries.ts b/web-api/src/business/useCases/processStreamRecords/processCaseWorksheetEntries.ts new file mode 100644 index 00000000000..164c397eef1 --- /dev/null +++ b/web-api/src/business/useCases/processStreamRecords/processCaseWorksheetEntries.ts @@ -0,0 +1,22 @@ +import { RawCaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; +import { getLogger } from 'aws-xray-sdk'; +import { unmarshall } from '@aws-sdk/util-dynamodb'; +import { upsertCaseWorksheets } from '@web-api/persistence/postgres/caseWorksheets/upsertCaseWorksheets'; + +export const processCaseWorksheetEntries = async ({ + caseWorksheetRecords, +}: { + caseWorksheetRecords: any[]; +}) => { + if (!caseWorksheetRecords.length) return; + + getLogger().debug( + `going to upsert ${caseWorksheetRecords.length} case worksheet records`, + ); + + await upsertCaseWorksheets( + caseWorksheetRecords.map(record => { + return unmarshall(record.dynamodb.NewImage) as RawCaseWorksheet; + }), + ); +}; diff --git a/web-api/src/business/useCases/processStreamRecords/processMessageEntries.test.ts b/web-api/src/business/useCases/processStreamRecords/processMessageEntries.test.ts index 7aa4cc46dbb..53d2b82a15b 100644 --- a/web-api/src/business/useCases/processStreamRecords/processMessageEntries.test.ts +++ b/web-api/src/business/useCases/processStreamRecords/processMessageEntries.test.ts @@ -1,10 +1,7 @@ import '@web-api/persistence/postgres/messages/mocks.jest'; -import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; import { processMessageEntries } from './processMessageEntries'; import { upsertMessages } from '@web-api/persistence/postgres/messages/upsertMessages'; -jest.mock('@web-api/persistence/postgres/messages/upsertMessages'); - describe('processMessageEntries', () => { beforeEach(() => { (upsertMessages as jest.Mock).mockResolvedValue(undefined); @@ -31,7 +28,6 @@ describe('processMessageEntries', () => { }; await processMessageEntries({ - applicationContext, messageRecords: [mockRepliedToMessageRecord], }); diff --git a/web-api/src/business/useCases/processStreamRecords/processMessageEntries.ts b/web-api/src/business/useCases/processStreamRecords/processMessageEntries.ts index a1d0d1ae7a5..a24b05f5905 100644 --- a/web-api/src/business/useCases/processStreamRecords/processMessageEntries.ts +++ b/web-api/src/business/useCases/processStreamRecords/processMessageEntries.ts @@ -1,20 +1,16 @@ import { RawMessage } from '@shared/business/entities/Message'; +import { getLogger } from 'aws-xray-sdk'; import { unmarshall } from '@aws-sdk/util-dynamodb'; import { upsertMessages } from '@web-api/persistence/postgres/messages/upsertMessages'; -import type { ServerApplicationContext } from '@web-api/applicationContext'; export const processMessageEntries = async ({ - applicationContext, messageRecords, }: { - applicationContext: ServerApplicationContext; messageRecords: any[]; }) => { if (!messageRecords.length) return; - applicationContext.logger.debug( - `going to index ${messageRecords.length} message records`, - ); + getLogger().debug(`going to index ${messageRecords.length} message records`); await upsertMessages( messageRecords.map(messageRecord => { diff --git a/web-api/src/business/useCases/processStreamRecords/processStreamRecordsInteractor.test.ts b/web-api/src/business/useCases/processStreamRecords/processStreamRecordsInteractor.test.ts index 62a30a45b8e..029dc89adf0 100644 --- a/web-api/src/business/useCases/processStreamRecords/processStreamRecordsInteractor.test.ts +++ b/web-api/src/business/useCases/processStreamRecords/processStreamRecordsInteractor.test.ts @@ -5,11 +5,18 @@ jest.mock('./processPractitionerMappingEntries'); jest.mock('./processRemoveEntries'); jest.mock('./processWorkItemEntries'); jest.mock('./processCaseEntries'); +jest.mock('./processCaseDeadlineEntries'); +jest.mock('./processCaseCorrespondenceEntries'); +jest.mock('./processCaseWorksheetEntries'); jest.mock('./processUserCaseNoteEntries'); jest.mock('./processOtherEntries'); import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; +import { getLogger } from '@web-api/utilities/logger/getLogger'; import { partitionRecords } from './processStreamUtilities'; +import { processCaseCorrespondenceEntries } from '@web-api/business/useCases/processStreamRecords/processCaseCorrespondenceEntries'; +import { processCaseDeadlineEntries } from '@web-api/business/useCases/processStreamRecords/processCaseDeadlineEntries'; import { processCaseEntries } from './processCaseEntries'; +import { processCaseWorksheetEntries } from '@web-api/business/useCases/processStreamRecords/processCaseWorksheetEntries'; import { processDocketEntries } from './processDocketEntries'; import { processMessageEntries } from './processMessageEntries'; import { processOtherEntries } from './processOtherEntries'; @@ -19,6 +26,9 @@ import { processStreamRecordsInteractor } from './processStreamRecordsInteractor import { processUserCaseNoteEntries } from './processUserCaseNoteEntries'; import { processWorkItemEntries } from './processWorkItemEntries'; +const logger = getLogger(); +const errorSpy = jest.spyOn(logger, 'error'); + describe('processStreamRecordsInteractor', () => { beforeAll(() => { (processRemoveEntries as jest.Mock).mockResolvedValue([]); @@ -27,11 +37,17 @@ describe('processStreamRecordsInteractor', () => { (processWorkItemEntries as jest.Mock).mockResolvedValue([]); (processMessageEntries as jest.Mock).mockResolvedValue([]); (processPractitionerMappingEntries as jest.Mock).mockResolvedValue([]); + (processCaseDeadlineEntries as jest.Mock).mockResolvedValue([]); + (processCaseWorksheetEntries as jest.Mock).mockResolvedValue([]); + (processCaseCorrespondenceEntries as jest.Mock).mockResolvedValue([]); (processUserCaseNoteEntries as jest.Mock).mockResolvedValue([]); (processOtherEntries as jest.Mock).mockResolvedValue([]); (partitionRecords as jest.Mock).mockReturnValue({ + caseCorrespondenceRecords: [], + caseDeadlineRecords: [], caseEntityRecords: [], + caseWorksheetRecords: [], docketEntryRecords: [], irsPractitionerMappingRecords: [], otherRecords: [], @@ -66,8 +82,11 @@ describe('processStreamRecordsInteractor', () => { expect(processMessageEntries).not.toHaveBeenCalled(); expect(processUserCaseNoteEntries).not.toHaveBeenCalled(); expect(processPractitionerMappingEntries).not.toHaveBeenCalled(); + expect(processCaseDeadlineEntries).not.toHaveBeenCalled(); + expect(processCaseWorksheetEntries).not.toHaveBeenCalled(); + expect(processCaseCorrespondenceEntries).not.toHaveBeenCalled(); expect(processOtherEntries).not.toHaveBeenCalled(); - expect(applicationContext.logger.error).toHaveBeenCalledTimes(2); + expect(errorSpy).toHaveBeenCalledTimes(2); }); it('should log an error, throw an exception, and halt further execution when processCaseEntries fails', async () => { @@ -86,7 +105,7 @@ describe('processStreamRecordsInteractor', () => { expect(processMessageEntries).not.toHaveBeenCalled(); expect(processPractitionerMappingEntries).not.toHaveBeenCalled(); expect(processOtherEntries).not.toHaveBeenCalled(); - expect(applicationContext.logger.error).toHaveBeenCalledTimes(2); + expect(errorSpy).toHaveBeenCalledTimes(2); }); it('should log an error, throw an exception, and halt further execution when processDocketEntries fails', async () => { @@ -104,8 +123,11 @@ describe('processStreamRecordsInteractor', () => { expect(processWorkItemEntries).not.toHaveBeenCalled(); expect(processMessageEntries).not.toHaveBeenCalled(); expect(processPractitionerMappingEntries).not.toHaveBeenCalled(); + expect(processCaseDeadlineEntries).not.toHaveBeenCalled(); + expect(processCaseWorksheetEntries).not.toHaveBeenCalled(); + expect(processCaseCorrespondenceEntries).not.toHaveBeenCalled(); expect(processOtherEntries).not.toHaveBeenCalled(); - expect(applicationContext.logger.error).toHaveBeenCalledTimes(2); + expect(errorSpy).toHaveBeenCalledTimes(2); }); it('should log an error, throw an exception, and halt further execution when processWorkItemEntries fails', async () => { @@ -123,8 +145,11 @@ describe('processStreamRecordsInteractor', () => { expect(processWorkItemEntries).toHaveBeenCalled(); // the one that throws an error expect(processMessageEntries).not.toHaveBeenCalled(); expect(processPractitionerMappingEntries).not.toHaveBeenCalled(); + expect(processCaseDeadlineEntries).not.toHaveBeenCalled(); + expect(processCaseWorksheetEntries).not.toHaveBeenCalled(); + expect(processCaseCorrespondenceEntries).not.toHaveBeenCalled(); expect(processOtherEntries).not.toHaveBeenCalled(); - expect(applicationContext.logger.error).toHaveBeenCalledTimes(2); + expect(errorSpy).toHaveBeenCalledTimes(2); }); it('should log an error, throw an exception, and halt further execution when processMessageEntries fails', async () => { @@ -142,8 +167,11 @@ describe('processStreamRecordsInteractor', () => { expect(processWorkItemEntries).toHaveBeenCalled(); expect(processMessageEntries).toHaveBeenCalled(); // the one that throws an error expect(processPractitionerMappingEntries).not.toHaveBeenCalled(); + expect(processCaseDeadlineEntries).not.toHaveBeenCalled(); + expect(processCaseWorksheetEntries).not.toHaveBeenCalled(); + expect(processCaseCorrespondenceEntries).not.toHaveBeenCalled(); expect(processOtherEntries).not.toHaveBeenCalled(); - expect(applicationContext.logger.error).toHaveBeenCalledTimes(2); + expect(errorSpy).toHaveBeenCalledTimes(2); }); it('should log an error, throw an exception, and halt further execution when processPractitionerMappingEntries fails', async () => { @@ -163,8 +191,83 @@ describe('processStreamRecordsInteractor', () => { expect(processWorkItemEntries).toHaveBeenCalled(); expect(processMessageEntries).toHaveBeenCalled(); expect(processPractitionerMappingEntries).toHaveBeenCalled(); // the one that throws an error + expect(processCaseDeadlineEntries).not.toHaveBeenCalled(); + expect(processCaseWorksheetEntries).not.toHaveBeenCalled(); + expect(processCaseCorrespondenceEntries).not.toHaveBeenCalled(); + expect(processOtherEntries).not.toHaveBeenCalled(); + expect(errorSpy).toHaveBeenCalledTimes(2); + }); + + it('should log an error, throw an exception, and halt further execution when processCaseDeadlineEntries fails', async () => { + (processCaseDeadlineEntries as jest.Mock).mockRejectedValueOnce( + new Error(), + ); + + await expect( + processStreamRecordsInteractor(applicationContext, { + recordsToProcess: [], + }), + ).rejects.toThrow(); + + expect(processRemoveEntries).toHaveBeenCalled(); + expect(processCaseEntries).toHaveBeenCalled(); + expect(processDocketEntries).toHaveBeenCalled(); + expect(processWorkItemEntries).toHaveBeenCalled(); + expect(processMessageEntries).toHaveBeenCalled(); + expect(processPractitionerMappingEntries).toHaveBeenCalled(); + expect(processCaseDeadlineEntries).toHaveBeenCalled(); // the one that throws an error + expect(processCaseWorksheetEntries).not.toHaveBeenCalled(); + expect(processCaseCorrespondenceEntries).not.toHaveBeenCalled(); + expect(processOtherEntries).not.toHaveBeenCalled(); + expect(errorSpy).toHaveBeenCalledTimes(2); + }); + + it('should log an error, throw an exception, and halt further execution when processCaseWorksheetEntries fails', async () => { + (processCaseWorksheetEntries as jest.Mock).mockRejectedValueOnce( + new Error(), + ); + + await expect( + processStreamRecordsInteractor(applicationContext, { + recordsToProcess: [], + }), + ).rejects.toThrow(); + + expect(processRemoveEntries).toHaveBeenCalled(); + expect(processCaseEntries).toHaveBeenCalled(); + expect(processDocketEntries).toHaveBeenCalled(); + expect(processWorkItemEntries).toHaveBeenCalled(); + expect(processMessageEntries).toHaveBeenCalled(); + expect(processPractitionerMappingEntries).toHaveBeenCalled(); + expect(processCaseDeadlineEntries).toHaveBeenCalled(); + expect(processCaseWorksheetEntries).toHaveBeenCalled(); // the one that throws an error + expect(processCaseCorrespondenceEntries).not.toHaveBeenCalled(); + expect(processOtherEntries).not.toHaveBeenCalled(); + expect(errorSpy).toHaveBeenCalledTimes(2); + }); + + it('should log an error, throw an exception, and halt further execution when processCaseCorrespondenceEntries fails', async () => { + (processCaseCorrespondenceEntries as jest.Mock).mockRejectedValueOnce( + new Error(), + ); + + await expect( + processStreamRecordsInteractor(applicationContext, { + recordsToProcess: [], + }), + ).rejects.toThrow(); + + expect(processRemoveEntries).toHaveBeenCalled(); + expect(processCaseEntries).toHaveBeenCalled(); + expect(processDocketEntries).toHaveBeenCalled(); + expect(processWorkItemEntries).toHaveBeenCalled(); + expect(processMessageEntries).toHaveBeenCalled(); + expect(processPractitionerMappingEntries).toHaveBeenCalled(); + expect(processCaseDeadlineEntries).toHaveBeenCalled(); + expect(processCaseWorksheetEntries).toHaveBeenCalled(); + expect(processCaseCorrespondenceEntries).toHaveBeenCalled(); // the one that throws an error expect(processOtherEntries).not.toHaveBeenCalled(); - expect(applicationContext.logger.error).toHaveBeenCalledTimes(2); + expect(errorSpy).toHaveBeenCalledTimes(2); }); it('should log an error, throw an exception, and halt further execution when processOtherEntries fails', async () => { @@ -182,7 +285,10 @@ describe('processStreamRecordsInteractor', () => { expect(processWorkItemEntries).toHaveBeenCalled(); expect(processMessageEntries).toHaveBeenCalled(); expect(processPractitionerMappingEntries).toHaveBeenCalled(); + expect(processCaseDeadlineEntries).toHaveBeenCalled(); + expect(processCaseWorksheetEntries).toHaveBeenCalled(); + expect(processCaseCorrespondenceEntries).toHaveBeenCalled(); expect(processOtherEntries).toHaveBeenCalled(); // the one that throws an error - expect(applicationContext.logger.error).toHaveBeenCalledTimes(2); + expect(errorSpy).toHaveBeenCalledTimes(2); }); }); diff --git a/web-api/src/business/useCases/processStreamRecords/processStreamRecordsInteractor.ts b/web-api/src/business/useCases/processStreamRecords/processStreamRecordsInteractor.ts index 62bb172816d..d32d1b5127c 100644 --- a/web-api/src/business/useCases/processStreamRecords/processStreamRecordsInteractor.ts +++ b/web-api/src/business/useCases/processStreamRecords/processStreamRecordsInteractor.ts @@ -1,6 +1,10 @@ import { ServerApplicationContext } from '@web-api/applicationContext'; +import { getLogger } from '@web-api/utilities/logger/getLogger'; import { partitionRecords } from './processStreamUtilities'; +import { processCaseCorrespondenceEntries } from '@web-api/business/useCases/processStreamRecords/processCaseCorrespondenceEntries'; +import { processCaseDeadlineEntries } from '@web-api/business/useCases/processStreamRecords/processCaseDeadlineEntries'; import { processCaseEntries } from './processCaseEntries'; +import { processCaseWorksheetEntries } from '@web-api/business/useCases/processStreamRecords/processCaseWorksheetEntries'; import { processCompletionMarkers } from './processCompletionMarkers'; import { processDocketEntries } from './processDocketEntries'; import { processMessageEntries } from './processMessageEntries'; @@ -16,7 +20,10 @@ export const processStreamRecordsInteractor = async ( { recordsToProcess }: { recordsToProcess: DynamoDBRecord[] }, ): Promise => { const { + caseCorrespondenceRecords, + caseDeadlineRecords, caseEntityRecords, + caseWorksheetRecords, completionMarkers, docketEntryRecords, messageRecords, @@ -32,7 +39,7 @@ export const processStreamRecordsInteractor = async ( applicationContext, removeRecords, }).catch(err => { - applicationContext.logger.error('failed to processRemoveEntries', { + getLogger().error('failed to processRemoveEntries', { err, }); throw err; @@ -42,7 +49,7 @@ export const processStreamRecordsInteractor = async ( applicationContext, caseEntityRecords, }).catch(err => { - applicationContext.logger.error('failed to processCaseEntries', { + getLogger().error('failed to processCaseEntries', { err, }); throw err; @@ -52,7 +59,7 @@ export const processStreamRecordsInteractor = async ( applicationContext, docketEntryRecords, }).catch(err => { - applicationContext.logger.error('failed to processDocketEntries', { + getLogger().error('failed to processDocketEntries', { err, }); throw err; @@ -60,7 +67,7 @@ export const processStreamRecordsInteractor = async ( await processWorkItemEntries({ applicationContext, workItemRecords }).catch( err => { - applicationContext.logger.error('failed to process workItem records', { + getLogger().error('failed to process workItem records', { err, }); throw err; @@ -68,10 +75,9 @@ export const processStreamRecordsInteractor = async ( ); await processMessageEntries({ - applicationContext, messageRecords, }).catch(err => { - applicationContext.logger.error('failed to process message records', { + getLogger().error('failed to process message records', { err, }); throw err; @@ -94,12 +100,9 @@ export const processStreamRecordsInteractor = async ( applicationContext, practitionerMappingRecords, }).catch(err => { - applicationContext.logger.error( - 'failed to process practitioner mapping records', - { - err, - }, - ); + getLogger().error('failed to process practitioner mapping records', { + err, + }); throw err; }); @@ -108,16 +111,43 @@ export const processStreamRecordsInteractor = async ( completionMarkers, }); + await processCaseDeadlineEntries({ + caseDeadlineRecords, + }).catch(err => { + getLogger().error('failed to process case deadline records', { + err, + }); + throw err; + }); + + await processCaseWorksheetEntries({ + caseWorksheetRecords, + }).catch(err => { + getLogger().error('failed to process case correspondence records', { + err, + }); + throw err; + }); + + await processCaseCorrespondenceEntries({ + caseCorrespondenceRecords, + }).catch(err => { + getLogger().error('failed to process case correspondence records', { + err, + }); + throw err; + }); + await processOtherEntries({ applicationContext, otherRecords }).catch( err => { - applicationContext.logger.error('failed to processOtherEntries', { + getLogger().error('failed to processOtherEntries', { err, }); throw err; }, ); } catch (err) { - applicationContext.logger.error( + getLogger().error( 'processStreamRecordsInteractor failed to process the records', { err }, ); diff --git a/web-api/src/business/useCases/processStreamRecords/processStreamUtilities.ts b/web-api/src/business/useCases/processStreamRecords/processStreamUtilities.ts index 1b5cb1db0b1..ba44d038b83 100644 --- a/web-api/src/business/useCases/processStreamRecords/processStreamUtilities.ts +++ b/web-api/src/business/useCases/processStreamRecords/processStreamUtilities.ts @@ -55,15 +55,39 @@ export const partitionRecords = ( record.dynamodb.NewImage.entityName.S === 'UserCaseNote', ); - const [completionMarkers, otherRecords] = partition( + const [completionMarkers, nonCompletionMarkerRecords] = partition( nonUserCaseNoteRecords, record => record.dynamodb?.NewImage?.entityName && record.dynamodb.NewImage.entityName.S === 'CompletionMarker', ); + const [caseDeadlineRecords, nonCaseDeadlineRecords] = partition( + nonCompletionMarkerRecords, + record => + record.dynamodb?.NewImage?.entityName && + record.dynamodb.NewImage.entityName.S === 'CaseDeadline', + ); + + const [caseWorksheetRecords, nonCaseWorksheetRecords] = partition( + nonCaseDeadlineRecords, + record => + record.dynamodb?.NewImage?.entityName && + record.dynamodb.NewImage.entityName.S === 'CaseWorksheet', + ); + + const [caseCorrespondenceRecords, otherRecords] = partition( + nonCaseWorksheetRecords, + record => + record.dynamodb?.NewImage?.entityName && + record.dynamodb.NewImage.entityName.S == 'Correspondence', + ); + return { + caseCorrespondenceRecords, + caseDeadlineRecords, caseEntityRecords, + caseWorksheetRecords, completionMarkers, docketEntryRecords, messageRecords, diff --git a/web-api/src/business/useCases/serveCaseToIrs/serveCaseToIrsInteractor.test.ts b/web-api/src/business/useCases/serveCaseToIrs/serveCaseToIrsInteractor.test.ts index 9b89d7ba572..6bcc00d3dca 100644 --- a/web-api/src/business/useCases/serveCaseToIrs/serveCaseToIrsInteractor.test.ts +++ b/web-api/src/business/useCases/serveCaseToIrs/serveCaseToIrsInteractor.test.ts @@ -1,4 +1,5 @@ /* eslint-disable max-lines */ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/messages/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; diff --git a/web-api/src/business/useCases/trialSessions/addCaseToTrialSessionInteractor.test.ts b/web-api/src/business/useCases/trialSessions/addCaseToTrialSessionInteractor.test.ts index 16d3581ec6e..11c045d655e 100644 --- a/web-api/src/business/useCases/trialSessions/addCaseToTrialSessionInteractor.test.ts +++ b/web-api/src/business/useCases/trialSessions/addCaseToTrialSessionInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/messages/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; diff --git a/web-api/src/business/useCases/trialSessions/deleteTrialSessionInteractor.test.ts b/web-api/src/business/useCases/trialSessions/deleteTrialSessionInteractor.test.ts index 6c4ce4cf9e3..da41af184a8 100644 --- a/web-api/src/business/useCases/trialSessions/deleteTrialSessionInteractor.test.ts +++ b/web-api/src/business/useCases/trialSessions/deleteTrialSessionInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/messages/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; diff --git a/web-api/src/business/useCases/trialSessions/removeCaseFromTrialInteractor.test.ts b/web-api/src/business/useCases/trialSessions/removeCaseFromTrialInteractor.test.ts index 5abd1e7ece0..2f105ca9b7c 100644 --- a/web-api/src/business/useCases/trialSessions/removeCaseFromTrialInteractor.test.ts +++ b/web-api/src/business/useCases/trialSessions/removeCaseFromTrialInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/messages/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; diff --git a/web-api/src/business/useCases/trialSessions/setTrialSessionCalendarInteractor.test.ts b/web-api/src/business/useCases/trialSessions/setTrialSessionCalendarInteractor.test.ts index 1909c58a28b..a6fa4313860 100644 --- a/web-api/src/business/useCases/trialSessions/setTrialSessionCalendarInteractor.test.ts +++ b/web-api/src/business/useCases/trialSessions/setTrialSessionCalendarInteractor.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/messages/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; diff --git a/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.locking.test.ts b/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.locking.test.ts index 87d1a930da4..3755a7d64c2 100644 --- a/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.locking.test.ts +++ b/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.locking.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { MOCK_CASE } from '@shared/test/mockCase'; import { MOCK_LOCK } from '@shared/test/mockLock'; diff --git a/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.noticeGeneration.test.ts b/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.noticeGeneration.test.ts index 1ac8dc63abd..597e81985e3 100644 --- a/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.noticeGeneration.test.ts +++ b/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.noticeGeneration.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { diff --git a/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.test.ts b/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.test.ts index f14ada6c45a..80e57f1945b 100644 --- a/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.test.ts +++ b/web-api/src/business/useCases/trialSessions/updateTrialSessionInteractor.test.ts @@ -1,3 +1,5 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { MOCK_CASE } from '@shared/test/mockCase'; diff --git a/web-api/src/business/useCases/user/updatePetitionerInformationInteractor.test.ts b/web-api/src/business/useCases/user/updatePetitionerInformationInteractor.test.ts index 28fb246cf30..57d8481cbe8 100644 --- a/web-api/src/business/useCases/user/updatePetitionerInformationInteractor.test.ts +++ b/web-api/src/business/useCases/user/updatePetitionerInformationInteractor.test.ts @@ -1,4 +1,5 @@ /* eslint-disable max-lines */ +import '@web-api/persistence/postgres/caseDeadlines/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/messages/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; diff --git a/web-api/src/database-types.ts b/web-api/src/database-types.ts index 6fba61d63a1..802ec27dbbd 100644 --- a/web-api/src/database-types.ts +++ b/web-api/src/database-types.ts @@ -4,6 +4,9 @@ export interface Database { dwUserCaseNote: UserCaseNoteTable; dwMessage: MessageTable; dwCase: CaseTable; + dwCaseCorrespondence: CaseCorrespondenceTable; + dwCaseDeadline: CaseDeadlineTable; + dwCaseWorksheet: CaseWorksheetTable; dwWorkItem: WorkItemTable; } @@ -50,6 +53,47 @@ export type CaseKysely = Selectable; export type NewCaseKysely = Insertable; export type UpdateCaseKysely = Updateable; +export interface CaseCorrespondenceTable { + archived?: boolean; + correspondenceId: string; + documentTitle: string; + filedBy?: string; + filingDate: Date; + userId: string; + docketNumber: string; +} + +export type CaseCorrespondenceKysely = Selectable; +export type NewCaseCorrespondenceKysely = Insertable; +export type UpdateCaseCorrespondenceKysely = + Updateable; + +export interface CaseDeadlineTable { + associatedJudge: string; + associatedJudgeId?: string; + caseDeadlineId: string; + createdAt: Date; + deadlineDate: Date; + description: string; + docketNumber: string; + sortableDocketNumber: number; +} + +export type CaseDeadlineKysely = Selectable; +export type NewCaseDeadlineKysely = Insertable; +export type UpdateCaseDeadlineKysely = Updateable; + +export interface CaseWorksheetTable { + docketNumber: string; + finalBriefDueDate?: Date; + primaryIssue?: string; + statusOfMatter?: string; + judgeUserId?: string; +} + +export type CaseWorksheetKysely = Selectable; +export type NewCaseWorksheetKysely = Insertable; +export type UpdateCaseWorksheetKysely = Updateable; export interface WorkItemTable { assigneeId?: string; assigneeName?: string; diff --git a/web-api/src/database.ts b/web-api/src/database.ts index e82418d026d..32748fd1e2d 100644 --- a/web-api/src/database.ts +++ b/web-api/src/database.ts @@ -1,4 +1,9 @@ -import { CamelCasePlugin, Kysely, PostgresDialect } from 'kysely'; +import { + CamelCasePlugin, + CompiledQuery, + Kysely, + PostgresDialect, +} from 'kysely'; import { Database } from './database-types'; import { Pool } from 'pg'; import { Signer } from '@aws-sdk/rds-signer'; @@ -67,7 +72,7 @@ async function getToken(region: string, host: string) { return tokens[region]; } -async function createConnection({ +async function getConnection({ cb, dbKey, host, @@ -79,13 +84,18 @@ async function createConnection({ host: string; }): Promise { try { + if (dbInstances[dbKey] && (await isConnectionValid(dbInstances[dbKey]))) { + // If valid, use the existing connection + return await cb(dbInstances[dbKey]); + } + const token = await getToken(region, host); if (!token) { throw new Error('token does not exist'); } - dbInstances[dbKey] = await connect({ + dbInstances[dbKey] = connect({ ...POOL, host, password: token, @@ -95,17 +105,30 @@ async function createConnection({ } catch (err) { clearToken(region); const token = await getToken(region, host); - dbInstances[dbKey] = await connect({ + + dbInstances[dbKey] = connect({ ...POOL, host, password: token, }); + return await cb(dbInstances[dbKey]!); } } +async function isConnectionValid(db: Kysely): Promise { + try { + await db.executeQuery<{ result: 1 }>( + CompiledQuery.raw('select 1 as result', []), + ); + return true; + } catch (err) { + return false; + } +} + export function getDbReader(cb: (r: Kysely) => T): Promise { - return createConnection({ + return getConnection({ cb, dbKey: 'reader', host: @@ -117,7 +140,7 @@ export function getDbReader(cb: (r: Kysely) => T): Promise { } export function getDbWriter(cb: (r: Kysely) => T): Promise { - return createConnection({ + return getConnection({ cb, dbKey: 'writer', host: environment.rds.pool.host, diff --git a/web-api/src/getPersistenceGateway.ts b/web-api/src/getPersistenceGateway.ts index 02a3d922c72..73688ea21ce 100644 --- a/web-api/src/getPersistenceGateway.ts +++ b/web-api/src/getPersistenceGateway.ts @@ -9,7 +9,6 @@ import { bulkIndexRecords } from './persistence/elasticsearch/bulkIndexRecords'; import { caseAdvancedSearch } from './persistence/elasticsearch/caseAdvancedSearch'; import { casePublicSearch as casePublicSearchPersistence } from './persistence/elasticsearch/casePublicSearch'; import { createCase } from './persistence/dynamo/cases/createCase'; -import { createCaseDeadline } from './persistence/dynamo/caseDeadlines/createCaseDeadline'; import { createCaseTrialSortMappingRecords } from './persistence/dynamo/cases/createCaseTrialSortMappingRecords'; import { createChangeOfAddressJob } from './persistence/dynamo/jobs/ChangeOfAddress/createChangeOfAddressJob'; import { createJobStatus } from './persistence/dynamo/trialSessions/createJobStatus'; @@ -26,7 +25,6 @@ import { createTrialSession } from './persistence/dynamo/trialSessions/createTri import { createTrialSessionWorkingCopy } from './persistence/dynamo/trialSessions/createTrialSessionWorkingCopy'; import { createUserRecords } from './persistence/dynamo/users/createUserRecords'; import { decrementJobCounter } from './persistence/dynamo/trialSessions/decrementJobCounter'; -import { deleteCaseDeadline } from './persistence/dynamo/caseDeadlines/deleteCaseDeadline'; import { deleteCaseTrialSortMappingRecords } from './persistence/dynamo/cases/deleteCaseTrialSortMappingRecords'; import { deleteDocketEntry } from './persistence/dynamo/documents/deleteDocketEntry'; import { deleteDocketEntryWorksheetRecord } from '@web-api/persistence/dynamo/pendingMotion/deleteDocketEntryWorksheetRecord'; @@ -56,12 +54,9 @@ import { getBlockedCases } from './persistence/elasticsearch/getBlockedCases'; import { getBulkTrialSessionWorkingCopies } from './persistence/dynamo/trialSessions/getBulkTrialSessionWorkingCopies'; import { getCalendaredCasesForTrialSession } from './persistence/dynamo/trialSessions/getCalendaredCasesForTrialSession'; import { getCaseByDocketNumber } from './persistence/dynamo/cases/getCaseByDocketNumber'; -import { getCaseDeadlinesByDateRange } from './persistence/elasticsearch/caseDeadlines/getCaseDeadlinesByDateRange'; -import { getCaseDeadlinesByDocketNumber } from './persistence/dynamo/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { getCaseInventoryReport } from './persistence/elasticsearch/getCaseInventoryReport'; import { getCaseMetadataByDocketNumber } from './persistence/dynamo/cases/getCaseMetadataByDocketNumber'; import { getCaseMetadataWithCounsel } from './persistence/dynamo/cases/getCaseMetadataWithCounsel'; -import { getCaseWorksheetsByDocketNumber } from '@web-api/persistence/dynamo/caseWorksheet/getCaseWorksheetsByDocketNumber'; import { getCasesByDocketNumbers } from './persistence/dynamo/cases/getCasesByDocketNumbers'; import { getCasesByEmailTotal } from '@web-api/persistence/elasticsearch/getCasesByEmailTotal'; import { getCasesByLeadDocketNumber } from './persistence/dynamo/cases/getCasesByLeadDocketNumber'; @@ -136,9 +131,7 @@ import { setStoredApplicationHealth } from '@web-api/persistence/dynamo/deployTa import { setTrialSessionJobStatusForCase } from './persistence/dynamo/trialSessions/setTrialSessionJobStatusForCase'; import { setTrialSessionProcessingStatus } from './persistence/dynamo/trialSessions/setTrialSessionProcessingStatus'; import { updateCase } from './persistence/dynamo/cases/updateCase'; -import { updateCaseCorrespondence } from './persistence/dynamo/correspondence/updateCaseCorrespondence'; import { updateCaseHearing } from './persistence/dynamo/trialSessions/updateCaseHearing'; -import { updateCaseWorksheet } from '@web-api/persistence/dynamo/caseWorksheet/updateCaseWorksheet'; import { updateDocketEntry } from './persistence/dynamo/documents/updateDocketEntry'; import { updateDocketEntryPendingServiceStatus } from './persistence/dynamo/documents/updateDocketEntryPendingServiceStatus'; import { updateDocketEntryProcessingStatus } from './persistence/dynamo/documents/updateDocketEntryProcessingStatus'; @@ -201,7 +194,6 @@ const gatewayMethods = { bulkDeleteRecords, bulkIndexRecords, createCase, - createCaseDeadline, createCaseTrialSortMappingRecords, createJobStatus, createNewPetitionerUser, @@ -225,9 +217,7 @@ const gatewayMethods = { setTrialSessionJobStatusForCase, setTrialSessionProcessingStatus, updateCase, - updateCaseCorrespondence, updateCaseHearing, - updateCaseWorksheet, updateDocketEntry, updateDocketEntryPendingServiceStatus, updateDocketEntryProcessingStatus, @@ -248,7 +238,6 @@ const gatewayMethods = { createChangeOfAddressJob, createLock, decrementJobCounter, - deleteCaseDeadline, deleteCaseTrialSortMappingRecords, deleteDocketEntry, deleteDocketEntryWorksheetRecord, @@ -270,12 +259,9 @@ const gatewayMethods = { getBulkTrialSessionWorkingCopyNotes: getBulkTrialSessionWorkingCopies, getCalendaredCasesForTrialSession, getCaseByDocketNumber, - getCaseDeadlinesByDateRange, - getCaseDeadlinesByDocketNumber, getCaseInventoryReport, getCaseMetadataByDocketNumber, getCaseMetadataWithCounsel, - getCaseWorksheetsByDocketNumber, getCasesByDocketNumbers, getCasesByEmailTotal, getCasesByLeadDocketNumber, diff --git a/web-api/src/lambdas/caseDeadline/getCaseDeadlinesForCaseLambda.ts b/web-api/src/lambdas/caseDeadline/getCaseDeadlinesForCaseLambda.ts index 0ae0f2d30bd..2b832e9e02a 100644 --- a/web-api/src/lambdas/caseDeadline/getCaseDeadlinesForCaseLambda.ts +++ b/web-api/src/lambdas/caseDeadline/getCaseDeadlinesForCaseLambda.ts @@ -8,8 +8,8 @@ import { getCaseDeadlinesForCaseInteractor } from '@web-api/business/useCases/ca * @returns {Promise<*|undefined>} the api gateway response object containing the statusCode, body, and headers */ export const getCaseDeadlinesForCaseLambda = event => - genericHandler(event, async ({ applicationContext }) => { - return await getCaseDeadlinesForCaseInteractor(applicationContext, { + genericHandler(event, async () => { + return await getCaseDeadlinesForCaseInteractor({ docketNumber: event.pathParameters.docketNumber, }); }); diff --git a/web-api/src/lambdas/caseDeadline/updateCaseDeadlineLambda.ts b/web-api/src/lambdas/caseDeadline/updateCaseDeadlineLambda.ts index 531ad482094..cbace18c722 100644 --- a/web-api/src/lambdas/caseDeadline/updateCaseDeadlineLambda.ts +++ b/web-api/src/lambdas/caseDeadline/updateCaseDeadlineLambda.ts @@ -12,9 +12,8 @@ export const updateCaseDeadlineLambda = ( event, authorizedUser: UnknownAuthUser, ): Promise => - genericHandler(event, async ({ applicationContext }) => { + genericHandler(event, async () => { return await updateCaseDeadlineInteractor( - applicationContext, { ...JSON.parse(event.body), }, diff --git a/web-api/src/lambdas/caseWorksheet/updateCaseWorksheetLambda.ts b/web-api/src/lambdas/caseWorksheet/updateCaseWorksheetLambda.ts index 6eac6e3aa84..1beb3e39be4 100644 --- a/web-api/src/lambdas/caseWorksheet/updateCaseWorksheetLambda.ts +++ b/web-api/src/lambdas/caseWorksheet/updateCaseWorksheetLambda.ts @@ -6,9 +6,8 @@ export const updateCaseWorksheetLambda = ( event, authorizedUser: UnknownAuthUser, ) => - genericHandler(event, async ({ applicationContext }) => { + genericHandler(event, async () => { return await updateCaseWorksheetInteractor( - applicationContext, JSON.parse(event.body), authorizedUser, ); diff --git a/web-api/src/lambdas/migration/migration.test.ts b/web-api/src/lambdas/migration/migration.test.ts index 6e335236adc..326f646de15 100644 --- a/web-api/src/lambdas/migration/migration.test.ts +++ b/web-api/src/lambdas/migration/migration.test.ts @@ -20,11 +20,14 @@ describe('migration', () => { }); it('migrates items and generates dynamodb PutRequest objects with the resulting data', async () => { - const mockCase = marshall({ - ...MOCK_CASE, - pk: `case|${MOCK_CASE.docketNumber}`, - sk: `case|${MOCK_CASE.docketNumber}`, - }); + const mockCase = marshall( + { + ...MOCK_CASE, + pk: `case|${MOCK_CASE.docketNumber}`, + sk: `case|${MOCK_CASE.docketNumber}`, + }, + { removeUndefinedValues: true }, + ); const mockItems: Record[] = [mockCase]; const mockMigrateRecords = jest.fn().mockReturnValue(mockItems); const dynamodb = new DynamoDBClient({ diff --git a/web-api/src/lambdas/v1/getCaseLambda.test.ts b/web-api/src/lambdas/v1/getCaseLambda.test.ts index 049e311c526..f6284a33941 100644 --- a/web-api/src/lambdas/v1/getCaseLambda.test.ts +++ b/web-api/src/lambdas/v1/getCaseLambda.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { MOCK_CASE_WITH_TRIAL_SESSION } from '../../../../shared/src/test/mockCase'; diff --git a/web-api/src/lambdas/v1/getDocumentDownloadUrlLambda.test.ts b/web-api/src/lambdas/v1/getDocumentDownloadUrlLambda.test.ts index 1b2826d3265..8e56dc2e8ec 100644 --- a/web-api/src/lambdas/v1/getDocumentDownloadUrlLambda.test.ts +++ b/web-api/src/lambdas/v1/getDocumentDownloadUrlLambda.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { CASE_STATUS_TYPES } from '@shared/business/entities/EntityConstants'; diff --git a/web-api/src/lambdas/v2/getCaseLambda.test.ts b/web-api/src/lambdas/v2/getCaseLambda.test.ts index 35dc1711808..358e38a8a4b 100644 --- a/web-api/src/lambdas/v2/getCaseLambda.test.ts +++ b/web-api/src/lambdas/v2/getCaseLambda.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { MOCK_CASE_WITH_TRIAL_SESSION } from '../../../../shared/src/test/mockCase'; diff --git a/web-api/src/lambdas/v2/getDocumentDownloadUrlLambda.test.ts b/web-api/src/lambdas/v2/getDocumentDownloadUrlLambda.test.ts index 169ecda4103..ca02d224c60 100644 --- a/web-api/src/lambdas/v2/getDocumentDownloadUrlLambda.test.ts +++ b/web-api/src/lambdas/v2/getDocumentDownloadUrlLambda.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; import '@web-api/persistence/postgres/cases/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { diff --git a/web-api/src/persistence/dynamo/caseDeadlines/createCaseDeadline.test.ts b/web-api/src/persistence/dynamo/caseDeadlines/createCaseDeadline.test.ts deleted file mode 100644 index 4697f7a5d47..00000000000 --- a/web-api/src/persistence/dynamo/caseDeadlines/createCaseDeadline.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; -import { createCaseDeadline } from './createCaseDeadline'; - -describe('createCaseDeadline', () => { - const CASE_DEADLINE_ID = '6805d1ab-18d0-43ec-bafb-654e83405416'; - - const mockCaseDeadline = { - caseDeadlineId: CASE_DEADLINE_ID, - deadlineDate: '2019-03-01T21:42:29.073Z', - description: 'hello world', - docketNumber: '123-20', - } as any; - - it('attempts to persist the case deadline', async () => { - await createCaseDeadline({ - applicationContext, - caseDeadline: mockCaseDeadline, - }); - - expect( - applicationContext.getDocumentClient().put.mock.calls[0][0], - ).toMatchObject({ - Item: { - caseDeadlineId: CASE_DEADLINE_ID, - pk: `case-deadline|${CASE_DEADLINE_ID}`, - sk: `case-deadline|${CASE_DEADLINE_ID}`, - }, - }); - expect( - applicationContext.getDocumentClient().put.mock.calls[1][0], - ).toMatchObject({ - Item: { - pk: 'case|123-20', - sk: `case-deadline|${CASE_DEADLINE_ID}`, - }, - }); - }); -}); diff --git a/web-api/src/persistence/dynamo/caseDeadlines/createCaseDeadline.ts b/web-api/src/persistence/dynamo/caseDeadlines/createCaseDeadline.ts deleted file mode 100644 index 45dd3cf49eb..00000000000 --- a/web-api/src/persistence/dynamo/caseDeadlines/createCaseDeadline.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RawCaseDeadline } from '@shared/business/entities/CaseDeadline'; -import { put } from '../../dynamodbClientService'; - -export const createCaseDeadline = ({ - applicationContext, - caseDeadline, -}: { - applicationContext: IApplicationContext; - caseDeadline: RawCaseDeadline; -}) => { - const { caseDeadlineId, docketNumber } = caseDeadline; - return Promise.all([ - put({ - Item: { - ...caseDeadline, - pk: `case-deadline|${caseDeadlineId}`, - sk: `case-deadline|${caseDeadlineId}`, - }, - applicationContext, - }), - put({ - Item: { - pk: `case|${docketNumber}`, - sk: `case-deadline|${caseDeadlineId}`, - }, - applicationContext, - }), - ]); -}; diff --git a/web-api/src/persistence/dynamo/caseDeadlines/deleteCaseDeadline.test.ts b/web-api/src/persistence/dynamo/caseDeadlines/deleteCaseDeadline.test.ts deleted file mode 100644 index 8804ee9a916..00000000000 --- a/web-api/src/persistence/dynamo/caseDeadlines/deleteCaseDeadline.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; -import { deleteCaseDeadline } from './deleteCaseDeadline'; - -describe('deleteCaseDeadline', () => { - const CASE_DEADLINE_ID = '6805d1ab-18d0-43ec-bafb-654e83405416'; - - const mockCaseDeadline = { - caseDeadlineId: CASE_DEADLINE_ID, - deadlineDate: '2019-03-01T21:42:29.073Z', - description: 'hello world', - docketNumber: '123-20', - }; - - beforeEach(() => { - applicationContext - .getDocumentClient() - .get.mockResolvedValue({ Item: mockCaseDeadline }); - }); - - it('deletes the case deadline records', async () => { - await deleteCaseDeadline({ - applicationContext, - caseDeadlineId: CASE_DEADLINE_ID, - docketNumber: '456-20', - }); - - expect( - applicationContext.getDocumentClient().delete.mock.calls[0][0], - ).toMatchObject({ - Key: { - pk: `case-deadline|${CASE_DEADLINE_ID}`, - sk: `case-deadline|${CASE_DEADLINE_ID}`, - }, - }); - expect( - applicationContext.getDocumentClient().delete.mock.calls[1][0], - ).toMatchObject({ - Key: { - pk: 'case|456-20', - sk: `case-deadline|${CASE_DEADLINE_ID}`, - }, - }); - }); - - it('does not call delete function if original case deadline is not found', async () => { - applicationContext.getDocumentClient().get.mockResolvedValue({}); - - await deleteCaseDeadline({ - applicationContext, - caseDeadlineId: CASE_DEADLINE_ID, - docketNumber: '456-20', - }); - - expect( - applicationContext.getDocumentClient().delete, - ).not.toHaveBeenCalled(); - }); -}); diff --git a/web-api/src/persistence/dynamo/caseDeadlines/deleteCaseDeadline.ts b/web-api/src/persistence/dynamo/caseDeadlines/deleteCaseDeadline.ts deleted file mode 100644 index fc25528ca4e..00000000000 --- a/web-api/src/persistence/dynamo/caseDeadlines/deleteCaseDeadline.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { get, remove } from '../../dynamodbClientService'; - -/** - * deleteCaseDeadline - * - * @param {object} providers the providers object - * @param {object} providers.applicationContext the application context - * @param {string} providers.caseDeadlineId the id of the case deadline to delete - * @param {string} providers.docketNumber the docket number of the case the deadline is attached to - * @returns {Array} the promises for the persistence delete calls - */ -export const deleteCaseDeadline = async ({ - applicationContext, - caseDeadlineId, - docketNumber, -}: { - applicationContext: IApplicationContext; - caseDeadlineId: string; - docketNumber: string; -}) => { - const originalCaseDeadline = await get({ - Key: { - pk: `case-deadline|${caseDeadlineId}`, - sk: `case-deadline|${caseDeadlineId}`, - }, - applicationContext, - }); - - if (originalCaseDeadline) { - await Promise.all([ - remove({ - applicationContext, - key: { - pk: `case-deadline|${caseDeadlineId}`, - sk: `case-deadline|${caseDeadlineId}`, - }, - }), - remove({ - applicationContext, - key: { - pk: `case|${docketNumber}`, - sk: `case-deadline|${caseDeadlineId}`, - }, - }), - ]); - } -}; diff --git a/web-api/src/persistence/dynamo/caseDeadlines/getCaseDeadlinesByDocketNumber.test.ts b/web-api/src/persistence/dynamo/caseDeadlines/getCaseDeadlinesByDocketNumber.test.ts deleted file mode 100644 index 124facffcd8..00000000000 --- a/web-api/src/persistence/dynamo/caseDeadlines/getCaseDeadlinesByDocketNumber.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; -import { batchGet, query } from '../../dynamodbClientService'; -import { getCaseDeadlinesByDocketNumber } from './getCaseDeadlinesByDocketNumber'; - -jest.mock('../../dynamodbClientService', () => ({ - batchGet: jest.fn(), - query: jest.fn(), -})); - -const mockCaseDeadline = { - caseDeadlineId: '6805d1ab-18d0-43ec-bafb-654e83405416', - deadlineDate: '2019-03-01T21:42:29.073Z', - description: 'hello world', - docketNumber: '123-20', -}; - -describe('getCaseDeadlinesByDocketNumber', () => { - const mockBatchGet = batchGet as jest.Mock; - const mockQuery = query as jest.Mock; - - beforeEach(() => { - mockBatchGet.mockReturnValue([ - { - ...mockCaseDeadline, - pk: `case-deadline|${mockCaseDeadline.caseDeadlineId}`, - sk: `case-deadline|${mockCaseDeadline.caseDeadlineId}`, - }, - ]); - mockQuery.mockReturnValue([ - { - pk: `case|${mockCaseDeadline.docketNumber}`, - sk: `case-deadline|${mockCaseDeadline.caseDeadlineId}`, - }, - ]); - }); - - it('should return data as received from persistence', async () => { - const result = await getCaseDeadlinesByDocketNumber({ - applicationContext, - docketNumber: mockCaseDeadline.docketNumber, - }); - expect(result).toEqual([ - { - caseDeadlineId: '6805d1ab-18d0-43ec-bafb-654e83405416', - deadlineDate: '2019-03-01T21:42:29.073Z', - description: 'hello world', - docketNumber: '123-20', - pk: 'case-deadline|6805d1ab-18d0-43ec-bafb-654e83405416', - sk: 'case-deadline|6805d1ab-18d0-43ec-bafb-654e83405416', - }, - ]); - }); - - it('should attempt to do a batch get in the same ids that were returned in the mapping records', async () => { - await getCaseDeadlinesByDocketNumber({ - applicationContext, - docketNumber: mockCaseDeadline.docketNumber, - }); - expect(mockBatchGet.mock.calls[0][0].keys).toEqual([ - { - pk: 'case-deadline|6805d1ab-18d0-43ec-bafb-654e83405416', - sk: 'case-deadline|6805d1ab-18d0-43ec-bafb-654e83405416', - }, - ]); - }); -}); diff --git a/web-api/src/persistence/dynamo/caseDeadlines/getCaseDeadlinesByDocketNumber.ts b/web-api/src/persistence/dynamo/caseDeadlines/getCaseDeadlinesByDocketNumber.ts deleted file mode 100644 index 51c13a2ece9..00000000000 --- a/web-api/src/persistence/dynamo/caseDeadlines/getCaseDeadlinesByDocketNumber.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { getRecordsViaMapping } from '../helpers/getRecordsViaMapping'; - -/** - * getCaseDeadlinesByDocketNumber - * - * @param {object} providers the providers object - * @param {object} providers.applicationContext the application context - * @param {string} providers.docketNumber the docket number of the case to get the case deadlines for - * @returns {Promise} the promise of the persistence call to get the records - */ -export const getCaseDeadlinesByDocketNumber = ({ - applicationContext, - docketNumber, -}: { - applicationContext: IApplicationContext; - docketNumber: string; -}) => - getRecordsViaMapping({ - applicationContext, - pk: `case|${docketNumber}`, - prefix: 'case-deadline', - }); diff --git a/web-api/src/persistence/dynamo/caseWorksheet/getCaseWorksheetsByDocketNumber.ts b/web-api/src/persistence/dynamo/caseWorksheet/getCaseWorksheetsByDocketNumber.ts deleted file mode 100644 index f1c3607b544..00000000000 --- a/web-api/src/persistence/dynamo/caseWorksheet/getCaseWorksheetsByDocketNumber.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - CaseWorksheet, - RawCaseWorksheet, -} from '@shared/business/entities/caseWorksheet/CaseWorksheet'; -import { batchGet } from '../../dynamodbClientService'; - -export const getCaseWorksheetsByDocketNumber = async ({ - applicationContext, - docketNumbers, -}: { - applicationContext: IApplicationContext; - docketNumbers: string[]; -}): Promise => { - const result = await batchGet({ - applicationContext, - keys: docketNumbers.map(docketNumber => ({ - pk: `case|${docketNumber}`, - sk: `case-worksheet|${docketNumber}`, - })), - }); - - return result.map(item => new CaseWorksheet(item).toRawObject()); -}; diff --git a/web-api/src/persistence/dynamo/caseWorksheet/updateCaseWorksheet.ts b/web-api/src/persistence/dynamo/caseWorksheet/updateCaseWorksheet.ts deleted file mode 100644 index 1e720b53a53..00000000000 --- a/web-api/src/persistence/dynamo/caseWorksheet/updateCaseWorksheet.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { RawCaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; -import { TDynamoRecord } from '@web-api/persistence/dynamo/dynamoTypes'; -import { put } from '../../dynamodbClientService'; - -export const updateCaseWorksheet = async ({ - applicationContext, - caseWorksheet, - judgeUserId, -}: { - applicationContext: IApplicationContext; - caseWorksheet: RawCaseWorksheet; - judgeUserId: string; -}): Promise => { - return await put({ - Item: { - gsi1pk: `judge-case-worksheet|${judgeUserId}`, - pk: `case|${caseWorksheet.docketNumber}`, - sk: `case-worksheet|${caseWorksheet.docketNumber}`, - ...caseWorksheet, - }, - applicationContext, - }); -}; diff --git a/web-api/src/persistence/dynamo/cases/getCaseByDocketNumber.test.ts b/web-api/src/persistence/dynamo/cases/getCaseByDocketNumber.test.ts index d8d9c597b34..14a77150b1e 100644 --- a/web-api/src/persistence/dynamo/cases/getCaseByDocketNumber.test.ts +++ b/web-api/src/persistence/dynamo/cases/getCaseByDocketNumber.test.ts @@ -1,12 +1,23 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { CASE_STATUS_TYPES, ROLES, } from '../../../../../shared/src/business/entities/EntityConstants'; import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; +import { calculateDate } from '@shared/business/utilities/DateHandler'; +import { caseCorrespondenceEntity } from '@web-api/persistence/postgres/caseCorrespondences/mapper'; import { getCaseByDocketNumber } from './getCaseByDocketNumber'; +import { getCaseCorrespondenceByDocketNumber as getCaseCorrespondenceByDocketNumberMock } from '@web-api/persistence/postgres/caseCorrespondences/getCaseCorrespondenceByDocketNumber'; + +const getCaseCorrespondenceByDocketNumber = + getCaseCorrespondenceByDocketNumberMock as jest.Mock; describe('getCaseByDocketNumber', () => { + beforeEach(() => { + (getCaseCorrespondenceByDocketNumber as jest.Mock).mockResolvedValue([]); + }); + it('should return data as received from persistence', async () => { applicationContext.getDocumentClient().query.mockResolvedValue({ Items: [ @@ -39,6 +50,21 @@ describe('getCaseByDocketNumber', () => { }); it('should return case and its associated data', async () => { + getCaseCorrespondenceByDocketNumber.mockResolvedValue([ + caseCorrespondenceEntity({ + archived: false, + correspondenceId: 'abc-124', + filingDate: calculateDate({ dateString: '2024-11-06T21:05:08.191Z' }), + }), + caseCorrespondenceEntity({ + archived: true, + correspondenceId: 'abc-123', + filingDate: calculateDate({ + dateString: '2024-11-06T21:05:08.191Z', + }), + }), + ]); + applicationContext.getDocumentClient().query.mockResolvedValue({ Items: [ { @@ -75,18 +101,6 @@ describe('getCaseByDocketNumber', () => { pk: 'case|123-20', sk: 'docket-entry|124', }, - { - archived: true, - correspondenceId: 'abc-123', - pk: 'case|123-20', - sk: 'correspondence|123', - }, - { - archived: false, - correspondenceId: 'abc-124', - pk: 'case|123-20', - sk: 'correspondence|124', - }, { name: 'Judge Fieri', pk: 'case|123-20', @@ -107,6 +121,8 @@ describe('getCaseByDocketNumber', () => { { archived: true, correspondenceId: 'abc-123', + entityName: 'Correspondence', + filingDate: '2024-11-06T21:05:08.191Z', }, ], archivedDocketEntries: [ @@ -121,6 +137,8 @@ describe('getCaseByDocketNumber', () => { { archived: false, correspondenceId: 'abc-124', + entityName: 'Correspondence', + filingDate: '2024-11-06T21:05:08.191Z', }, ], docketEntries: [ diff --git a/web-api/src/persistence/dynamo/cases/getCaseByDocketNumber.ts b/web-api/src/persistence/dynamo/cases/getCaseByDocketNumber.ts index 4bd722aada2..cf192d9ba08 100644 --- a/web-api/src/persistence/dynamo/cases/getCaseByDocketNumber.ts +++ b/web-api/src/persistence/dynamo/cases/getCaseByDocketNumber.ts @@ -9,6 +9,7 @@ import { aggregateConsolidatedCaseItems, isCaseItem, } from '../helpers/aggregateCaseItems'; +import { getCaseCorrespondenceByDocketNumber } from '@web-api/persistence/postgres/caseCorrespondences/getCaseCorrespondenceByDocketNumber'; import { getWorkItemsByDocketNumber } from '@web-api/persistence/postgres/workitems/getWorkItemsByDocketNumber'; import { purgeDynamoKeys } from '@web-api/persistence/dynamo/helpers/purgeDynamoKeys'; import { queryFull } from '../../dynamodbClientService'; @@ -22,7 +23,7 @@ export const getCaseByDocketNumber = async ({ docketNumber: string; includeConsolidatedCases?: boolean; }): Promise => { - const [caseItems, workItems] = await Promise.all([ + const [caseItems, correspondenceItems, workItems] = await Promise.all([ queryFull({ ExpressionAttributeNames: { '#pk': 'pk', @@ -33,6 +34,9 @@ export const getCaseByDocketNumber = async ({ KeyConditionExpression: '#pk = :pk', applicationContext, }), + getCaseCorrespondenceByDocketNumber({ + docketNumber, + }), getWorkItemsByDocketNumber({ docketNumber, }), @@ -63,6 +67,11 @@ export const getCaseByDocketNumber = async ({ return purgeDynamoKeys({ ...aggregateCaseItems([ ...caseItems, + ...correspondenceItems.map(correspondenceItem => ({ + ...correspondenceItem, + pk: `case|${docketNumber}`, + sk: `correspondence|${correspondenceItem.correspondenceId}`, + })), ...workItems.map(workItem => ({ ...workItem, pk: `case|${docketNumber}`, diff --git a/web-api/src/persistence/dynamo/correspondence/updateCaseCorrespondence.test.ts b/web-api/src/persistence/dynamo/correspondence/updateCaseCorrespondence.test.ts deleted file mode 100644 index e818aef1247..00000000000 --- a/web-api/src/persistence/dynamo/correspondence/updateCaseCorrespondence.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Correspondence } from '../../../../../shared/src/business/entities/Correspondence'; -import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; -import { updateCaseCorrespondence } from './updateCaseCorrespondence'; - -describe('updateCaseCorrespondence', () => { - let putStub; - - beforeAll(() => { - putStub = jest.fn().mockResolvedValue(null); - - applicationContext.getDocumentClient.mockReturnValue({ - put: putStub, - }); - }); - - it('should update the specified correspondence record', async () => { - const mockGuid = applicationContext.getUniqueId(); - const mockCorrespondence = new Correspondence({ - archived: false, - correspondenceId: mockGuid, - documentTitle: 'My Correspondence', - filedBy: 'Docket clerk', - userId: mockGuid, - }); - - await updateCaseCorrespondence({ - applicationContext, - correspondence: mockCorrespondence, - docketNumber: '101-20', - }); - - expect( - applicationContext.getDocumentClient().put.mock.calls[0][0], - ).toMatchObject({ - Item: { - archived: false, - correspondenceId: mockGuid, - documentTitle: 'My Correspondence', - filedBy: 'Docket clerk', - pk: 'case|101-20', - sk: `correspondence|${mockGuid}`, - userId: mockGuid, - }, - }); - }); -}); diff --git a/web-api/src/persistence/dynamo/correspondence/updateCaseCorrespondence.ts b/web-api/src/persistence/dynamo/correspondence/updateCaseCorrespondence.ts deleted file mode 100644 index bb583599525..00000000000 --- a/web-api/src/persistence/dynamo/correspondence/updateCaseCorrespondence.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { put } from '../../dynamodbClientService'; - -/** - * updateCaseCorrespondence - * - * @param {object} providers the providers object - * @param {object} providers.applicationContext the application context - * @param {string} providers.docketNumber the docket number of the case the correspondence is attached to - * @param {string} providers.correspondence the correspondence document to update - * @returns {Promise} resolved promise upon completion of client request - */ -export const updateCaseCorrespondence = ({ - applicationContext, - correspondence, - docketNumber, -}: { - applicationContext: IApplicationContext; - correspondence: any; - docketNumber: string; -}) => - put({ - Item: { - ...correspondence, - pk: `case|${docketNumber}`, - sk: `correspondence|${correspondence.correspondenceId}`, - }, - applicationContext, - }); diff --git a/web-api/src/persistence/dynamo/trialSessions/getCalendaredCasesForTrialSession.test.ts b/web-api/src/persistence/dynamo/trialSessions/getCalendaredCasesForTrialSession.test.ts index cc37010e163..b5706367d4c 100644 --- a/web-api/src/persistence/dynamo/trialSessions/getCalendaredCasesForTrialSession.test.ts +++ b/web-api/src/persistence/dynamo/trialSessions/getCalendaredCasesForTrialSession.test.ts @@ -1,3 +1,4 @@ +import '@web-api/persistence/postgres/caseCorrespondences/mocks.jest'; import '@web-api/persistence/postgres/workitems/mocks.jest'; import { CASE_STATUS_TYPES } from '../../../../../shared/src/business/entities/EntityConstants'; import { MOCK_CASE } from '../../../../../shared/src/test/mockCase'; diff --git a/web-api/src/persistence/elasticsearch/caseDeadlines/getCaseDeadlinesByDateRange.test.ts b/web-api/src/persistence/elasticsearch/caseDeadlines/getCaseDeadlinesByDateRange.test.ts deleted file mode 100644 index a0c68c1a3b3..00000000000 --- a/web-api/src/persistence/elasticsearch/caseDeadlines/getCaseDeadlinesByDateRange.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { applicationContext } from '../../../../../shared/src/business/test/createTestApplicationContext'; -import { getCaseDeadlinesByDateRange } from './getCaseDeadlinesByDateRange'; -jest.mock('../searchClient'); -import { search } from '../searchClient'; - -describe('getCaseDeadlinesByDateRange', () => { - const START_DATE = '2019-08-25T05:00:00.000Z'; - const END_DATE = '2020-08-25T05:00:00.000Z'; - - it('returns results from the search client', async () => { - (search as jest.Mock).mockReturnValue({ - results: ['some', 'matches'], - total: 2, - }); - - const results = await getCaseDeadlinesByDateRange({ - applicationContext, - endDate: END_DATE, - startDate: START_DATE, - }); - - expect(search).toHaveBeenCalledTimes(1); - expect(results).toMatchObject({ foundDeadlines: ['some', 'matches'] }); - - const callParam = (search as jest.Mock).mock.calls[0][0]; - expect( - callParam.searchParameters.body.query.bool.filter[0].range[ - 'deadlineDate.S' - ].gte, - ).toEqual(`${START_DATE}||/h`); - expect( - callParam.searchParameters.body.query.bool.filter[0].range[ - 'deadlineDate.S' - ].lte, - ).toEqual(`${END_DATE}||/h`); - }); - - it('adds judge query to search client call if judge is provided', async () => { - await getCaseDeadlinesByDateRange({ - applicationContext, - endDate: END_DATE, - judge: 'Buch', - startDate: START_DATE, - }); - - const callParam = (search as jest.Mock).mock.calls[0][0]; - expect(callParam.searchParameters.body.query.bool.must[0]).toEqual({ - simple_query_string: { - default_operator: 'and', - fields: ['associatedJudge.S'], - query: '"Buch"', - }, - }); - }); -}); diff --git a/web-api/src/persistence/elasticsearch/caseDeadlines/getCaseDeadlinesByDateRange.ts b/web-api/src/persistence/elasticsearch/caseDeadlines/getCaseDeadlinesByDateRange.ts deleted file mode 100644 index d66dd319346..00000000000 --- a/web-api/src/persistence/elasticsearch/caseDeadlines/getCaseDeadlinesByDateRange.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { search } from '../searchClient'; - -export const getCaseDeadlinesByDateRange = async ({ - applicationContext, - endDate, - judge, - startDate, -}) => { - const queryArray: {}[] = []; - const filterArray = [ - { - range: { - 'deadlineDate.S': { - gte: `${startDate}||/h`, - lte: `${endDate}||/h`, - }, - }, - }, - ]; - - if (judge) { - queryArray.push({ - simple_query_string: { - default_operator: 'and', - fields: ['associatedJudge.S'], - query: `"${judge}"`, - }, - }); - } - - const query = { - body: { - query: { - bool: { - filter: filterArray, - must: queryArray, - }, - }, - sort: [ - { 'deadlineDate.S': { order: 'asc' } }, - { 'sortableDocketNumber.N': { order: 'asc' } }, - ], - }, - index: 'efcms-case-deadline', - size: 10000, - }; - - const { results } = await search({ - applicationContext, - searchParameters: query, - }); - - return { foundDeadlines: results }; -}; diff --git a/web-api/src/persistence/postgres/caseCorrespondences/getCaseCorrespondenceByDocketNumber.ts b/web-api/src/persistence/postgres/caseCorrespondences/getCaseCorrespondenceByDocketNumber.ts new file mode 100644 index 00000000000..3960e59a887 --- /dev/null +++ b/web-api/src/persistence/postgres/caseCorrespondences/getCaseCorrespondenceByDocketNumber.ts @@ -0,0 +1,21 @@ +import { Correspondence } from '@shared/business/entities/Correspondence'; +import { caseCorrespondenceEntity } from '@web-api/persistence/postgres/caseCorrespondences/mapper'; +import { getDbReader } from '@web-api/database'; + +export const getCaseCorrespondenceByDocketNumber = async ({ + docketNumber, +}: { + docketNumber: string; +}): Promise => { + const correspondence = await getDbReader(reader => + reader + .selectFrom('dwCaseCorrespondence as cc') + .leftJoin('dwCase as c', 'c.docketNumber', 'cc.docketNumber') + .where('cc.docketNumber', '=', docketNumber) + .selectAll() + .select('cc.docketNumber') + .execute(), + ); + + return correspondence.map(c => caseCorrespondenceEntity(c)); +}; diff --git a/web-api/src/persistence/postgres/caseCorrespondences/mapper.ts b/web-api/src/persistence/postgres/caseCorrespondences/mapper.ts new file mode 100644 index 00000000000..66bfc86dd04 --- /dev/null +++ b/web-api/src/persistence/postgres/caseCorrespondences/mapper.ts @@ -0,0 +1,11 @@ +import { Correspondence } from '@shared/business/entities/Correspondence'; +import { transformNullToUndefined } from '@web-api/persistence/postgres/utils/transformNullToUndefined'; + +export function caseCorrespondenceEntity(caseCorrespondence) { + return new Correspondence( + transformNullToUndefined({ + ...caseCorrespondence, + filingDate: caseCorrespondence.filingDate.toISOString(), + }), + ); +} diff --git a/web-api/src/persistence/postgres/caseCorrespondences/mocks.jest.ts b/web-api/src/persistence/postgres/caseCorrespondences/mocks.jest.ts new file mode 100644 index 00000000000..ec2bf28c363 --- /dev/null +++ b/web-api/src/persistence/postgres/caseCorrespondences/mocks.jest.ts @@ -0,0 +1,11 @@ +import { mockFactory } from '@shared/test/mockFactory'; + +jest.mock( + '@web-api/persistence/postgres/caseCorrespondences/getCaseCorrespondenceByDocketNumber', + () => mockFactory('getCaseCorrespondenceByDocketNumber', []), +); + +jest.mock( + '@web-api/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences', + () => mockFactory('upsertCaseCorrespondences'), +); diff --git a/web-api/src/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences.ts b/web-api/src/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences.ts new file mode 100644 index 00000000000..42e6053bf01 --- /dev/null +++ b/web-api/src/persistence/postgres/caseCorrespondences/upsertCaseCorrespondences.ts @@ -0,0 +1,37 @@ +import { RawCorrespondence } from '@shared/business/entities/Correspondence'; +import { calculateDate } from '@shared/business/utilities/DateHandler'; +import { getDbWriter } from '@web-api/database'; + +export const upsertCaseCorrespondences = async ( + correspondences: RawCorrespondence[], +) => { + const correspondencesToUpsert = correspondences.map(correspondence => { + return { + archived: correspondence.archived, + correspondenceId: correspondence.correspondenceId, + docketNumber: correspondence.docketNumber, + documentTitle: correspondence.documentTitle, + filedBy: correspondence.filedBy, + filingDate: calculateDate({ dateString: correspondence.filingDate }), + userId: correspondence.userId, + }; + }); + await getDbWriter(writer => + writer + .insertInto('dwCaseCorrespondence') + .values(correspondencesToUpsert) + .onConflict(oc => + oc.column('correspondenceId').doUpdateSet(c => { + return { + archived: c.ref('excluded.archived'), + docketNumber: c.ref('excluded.docketNumber'), + documentTitle: c.ref('excluded.documentTitle'), + filedBy: c.ref('excluded.filedBy'), + filingDate: c.ref('excluded.filingDate'), + userId: c.ref('excluded.userId'), + }; + }), + ) + .execute(), + ); +}; diff --git a/web-api/src/persistence/postgres/caseDeadlines/deleteCaseDeadline.ts b/web-api/src/persistence/postgres/caseDeadlines/deleteCaseDeadline.ts new file mode 100644 index 00000000000..73756d67d70 --- /dev/null +++ b/web-api/src/persistence/postgres/caseDeadlines/deleteCaseDeadline.ts @@ -0,0 +1,14 @@ +import { getDbWriter } from '@web-api/database'; + +export const deleteCaseDeadline = async ({ + caseDeadlineId, +}: { + caseDeadlineId: string; +}) => { + await getDbWriter(writer => + writer + .deleteFrom('dwCaseDeadline') + .where('caseDeadlineId', '=', caseDeadlineId) + .execute(), + ); +}; diff --git a/web-api/src/persistence/postgres/caseDeadlines/getCaseDeadlinesByDateRange.ts b/web-api/src/persistence/postgres/caseDeadlines/getCaseDeadlinesByDateRange.ts new file mode 100644 index 00000000000..9833b8c24cb --- /dev/null +++ b/web-api/src/persistence/postgres/caseDeadlines/getCaseDeadlinesByDateRange.ts @@ -0,0 +1,54 @@ +import { caseDeadlineEntity } from '@web-api/persistence/postgres/caseDeadlines/mapper'; +import { getDbReader } from '@web-api/database'; + +export const getCaseDeadlinesByDateRange = async ({ + endDate, + judge, + startDate, +}) => { + const { results: caseDeadlines, total: totalCount } = await getDbReader( + async reader => { + let deadlineQuery = reader + .selectFrom('dwCaseDeadline as cd') + .leftJoin('dwCase as c', 'c.docketNumber', 'cd.docketNumber') + .selectAll() + .select('cd.docketNumber') + .where('cd.deadlineDate', '>=', startDate) + .where('cd.deadlineDate', '<=', endDate); + + if (judge) { + deadlineQuery = deadlineQuery.where('associatedJudge', '=', judge); + } + + deadlineQuery = deadlineQuery + .orderBy('cd.deadlineDate', 'asc') + .orderBy('cd.sortableDocketNumber', 'asc'); + + const results = await deadlineQuery.execute(); + + let countQuery = reader + .selectFrom('dwCaseDeadline') + .select(reader.fn.count('docketNumber').as('totalCount')) + .where('deadlineDate', '>=', startDate) + .where('deadlineDate', '<=', endDate); + + if (judge) { + countQuery = countQuery.where('associatedJudge', '=', judge); + } + + const total = await countQuery.executeTakeFirst(); + + return { + results, + total: total?.totalCount || 0, + }; + }, + ); + + return { + foundDeadlines: caseDeadlines.map(caseDeadline => + caseDeadlineEntity(caseDeadline), + ), + totalCount, + }; +}; diff --git a/web-api/src/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber.ts b/web-api/src/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber.ts new file mode 100644 index 00000000000..ed724f19116 --- /dev/null +++ b/web-api/src/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber.ts @@ -0,0 +1,20 @@ +import { caseDeadlineEntity } from '@web-api/persistence/postgres/caseDeadlines/mapper'; +import { getDbReader } from '@web-api/database'; + +export const getCaseDeadlinesByDocketNumber = async ({ + docketNumber, +}: { + docketNumber: string; +}) => { + const caseDeadlines = await getDbReader(reader => + reader + .selectFrom('dwCaseDeadline as cd') + .leftJoin('dwCase as c', 'c.docketNumber', 'cd.docketNumber') + .where('cd.docketNumber', '=', docketNumber) + .selectAll() + .select('cd.docketNumber') + .execute(), + ); + + return caseDeadlines.map(caseDeadline => caseDeadlineEntity(caseDeadline)); +}; diff --git a/web-api/src/persistence/postgres/caseDeadlines/mapper.ts b/web-api/src/persistence/postgres/caseDeadlines/mapper.ts new file mode 100644 index 00000000000..6eea781036d --- /dev/null +++ b/web-api/src/persistence/postgres/caseDeadlines/mapper.ts @@ -0,0 +1,35 @@ +import { + CaseDeadline, + RawCaseDeadline, +} from '@shared/business/entities/CaseDeadline'; +import { NewCaseDeadlineKysely } from '@web-api/database-types'; +import { transformNullToUndefined } from '@web-api/persistence/postgres/utils/transformNullToUndefined'; + +function pickFields(deadline): NewCaseDeadlineKysely { + return { + associatedJudge: deadline.associatedJudge, + associatedJudgeId: deadline.associatedJudgeId, + caseDeadlineId: deadline.caseDeadlineId, + createdAt: deadline.createdAt, + deadlineDate: deadline.deadlineDate, + description: deadline.description, + docketNumber: deadline.docketNumber, + sortableDocketNumber: deadline.sortableDocketNumber, + }; +} + +export function toKyselyNewCaseDeadline( + deadline: RawCaseDeadline, +): NewCaseDeadlineKysely { + return pickFields(deadline); +} + +export function caseDeadlineEntity(caseDeadline) { + return new CaseDeadline( + transformNullToUndefined({ + ...caseDeadline, + createdAt: caseDeadline.createdAt.toISOString(), + deadlineDate: caseDeadline.deadlineDate?.toISOString(), + }), + ); +} diff --git a/web-api/src/persistence/postgres/caseDeadlines/mocks.jest.ts b/web-api/src/persistence/postgres/caseDeadlines/mocks.jest.ts new file mode 100644 index 00000000000..534d62e2fec --- /dev/null +++ b/web-api/src/persistence/postgres/caseDeadlines/mocks.jest.ts @@ -0,0 +1,21 @@ +import { mockFactory } from '@shared/test/mockFactory'; + +jest.mock( + '@web-api/persistence/postgres/caseDeadlines/upsertCaseDeadlines', + () => mockFactory('upsertCaseDeadlines'), +); + +jest.mock( + '@web-api/persistence/postgres/caseDeadlines/deleteCaseDeadline', + () => mockFactory('deleteCaseDeadline'), +); + +jest.mock( + '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDateRange', + () => mockFactory('getCaseDeadlinesByDateRange', []), +); + +jest.mock( + '@web-api/persistence/postgres/caseDeadlines/getCaseDeadlinesByDocketNumber', + () => mockFactory('getCaseDeadlinesByDocketNumber', []), +); diff --git a/web-api/src/persistence/postgres/caseDeadlines/upsertCaseDeadlines.ts b/web-api/src/persistence/postgres/caseDeadlines/upsertCaseDeadlines.ts new file mode 100644 index 00000000000..0f6ba80e115 --- /dev/null +++ b/web-api/src/persistence/postgres/caseDeadlines/upsertCaseDeadlines.ts @@ -0,0 +1,32 @@ +import { RawCaseDeadline } from '@shared/business/entities/CaseDeadline'; +import { + caseDeadlineEntity, + toKyselyNewCaseDeadline, +} from '@web-api/persistence/postgres/caseDeadlines/mapper'; +import { getDbWriter } from '@web-api/database'; + +export const upsertCaseDeadlines = async ( + caseDeadlinesToUpsert: RawCaseDeadline[], +) => { + const caseDeadlines = await getDbWriter(writer => + writer + .insertInto('dwCaseDeadline') + .values(caseDeadlinesToUpsert.map(cd => toKyselyNewCaseDeadline(cd))) + .onConflict(oc => + oc.column('caseDeadlineId').doUpdateSet(cd => { + return { + associatedJudge: cd.ref('excluded.associatedJudge'), + associatedJudgeId: cd.ref('excluded.associatedJudgeId'), + createdAt: cd.ref('excluded.createdAt'), + deadlineDate: cd.ref('excluded.deadlineDate'), + description: cd.ref('excluded.description'), + docketNumber: cd.ref('excluded.docketNumber'), + sortableDocketNumber: cd.ref('excluded.sortableDocketNumber'), + }; + }), + ) + .returningAll() + .execute(), + ); + return caseDeadlines.map(cd => caseDeadlineEntity(cd)); +}; diff --git a/web-api/src/persistence/postgres/caseWorksheets/getCaseWorksheetsByDocketNumber.ts b/web-api/src/persistence/postgres/caseWorksheets/getCaseWorksheetsByDocketNumber.ts new file mode 100644 index 00000000000..42ab551df14 --- /dev/null +++ b/web-api/src/persistence/postgres/caseWorksheets/getCaseWorksheetsByDocketNumber.ts @@ -0,0 +1,24 @@ +import { CaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; +import { caseWorksheetEntity } from '@web-api/persistence/postgres/caseWorksheets/mapper'; +import { getDbReader } from '@web-api/database'; +import { isEmpty } from 'lodash'; + +export const getCaseWorksheetsByDocketNumber = async ({ + docketNumbers, +}: { + docketNumbers: string[]; +}): Promise => { + if (isEmpty(docketNumbers)) return []; + + const caseWorksheets = await getDbReader(reader => + reader + .selectFrom('dwCaseWorksheet') + .where('docketNumber', 'in', docketNumbers) + .selectAll() + .execute(), + ); + + return caseWorksheets.map(caseWorkSheet => + caseWorksheetEntity(caseWorkSheet), + ); +}; diff --git a/web-api/src/persistence/postgres/caseWorksheets/mapper.ts b/web-api/src/persistence/postgres/caseWorksheets/mapper.ts new file mode 100644 index 00000000000..212de245012 --- /dev/null +++ b/web-api/src/persistence/postgres/caseWorksheets/mapper.ts @@ -0,0 +1,11 @@ +import { CaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; +import { transformNullToUndefined } from '@web-api/persistence/postgres/utils/transformNullToUndefined'; + +export function caseWorksheetEntity(caseWorksheet) { + return new CaseWorksheet( + transformNullToUndefined({ + ...caseWorksheet, + filingDate: caseWorksheet.finalBriefDueDate?.toISOString(), + }), + ); +} diff --git a/web-api/src/persistence/postgres/caseWorksheets/mocks.jest.ts b/web-api/src/persistence/postgres/caseWorksheets/mocks.jest.ts new file mode 100644 index 00000000000..ca8ecbcca30 --- /dev/null +++ b/web-api/src/persistence/postgres/caseWorksheets/mocks.jest.ts @@ -0,0 +1,11 @@ +import { mockFactory } from '@shared/test/mockFactory'; + +jest.mock( + '@web-api/persistence/postgres/caseWorksheets/getCaseWorksheetsByDocketNumber', + () => mockFactory('getCaseWorksheetsByDocketNumber'), +); + +jest.mock( + '@web-api/persistence/postgres/caseWorksheets/upsertCaseWorksheets', + () => mockFactory('upsertCaseWorksheets'), +); diff --git a/web-api/src/persistence/postgres/caseWorksheets/upsertCaseWorksheets.ts b/web-api/src/persistence/postgres/caseWorksheets/upsertCaseWorksheets.ts new file mode 100644 index 00000000000..f36d4d4a513 --- /dev/null +++ b/web-api/src/persistence/postgres/caseWorksheets/upsertCaseWorksheets.ts @@ -0,0 +1,40 @@ +import { + CaseWorksheet, + RawCaseWorksheet, +} from '@shared/business/entities/caseWorksheet/CaseWorksheet'; +import { calculateDate } from '@shared/business/utilities/DateHandler'; +import { getDbWriter } from '@web-api/database'; + +export const upsertCaseWorksheets = async ( + caseWorksheets: RawCaseWorksheet[], +): Promise => { + const caseWorksheetsToUpsert = caseWorksheets.map(cw => { + return { + docketNumber: cw.docketNumber, + finalBriefDueDate: calculateDate({ dateString: cw.finalBriefDueDate }), + judgeUserId: cw.judgeUserId, + primaryIssue: cw.primaryIssue, + statusOfMatter: cw.statusOfMatter, + }; + }); + + const results = await getDbWriter(writer => + writer + .insertInto('dwCaseWorksheet') + .values(caseWorksheetsToUpsert) + .onConflict(oc => + oc.column('docketNumber').doUpdateSet(cd => { + return { + docketNumber: cd.ref('excluded.docketNumber'), + finalBriefDueDate: cd.ref('excluded.finalBriefDueDate'), + judgeUserId: cd.ref('excluded.judgeUserId'), + primaryIssue: cd.ref('excluded.primaryIssue'), + statusOfMatter: cd.ref('excluded.statusOfMatter'), + }; + }), + ) + .execute(), + ); + + return results.map(cw => new CaseWorksheet(cw)); +}; diff --git a/web-api/src/persistence/postgres/utils/migrate/migrations/0005-case-deadline-correspondence-worksheet.ts b/web-api/src/persistence/postgres/utils/migrate/migrations/0005-case-deadline-correspondence-worksheet.ts new file mode 100644 index 00000000000..7e8fa9ff575 --- /dev/null +++ b/web-api/src/persistence/postgres/utils/migrate/migrations/0005-case-deadline-correspondence-worksheet.ts @@ -0,0 +1,41 @@ +import { Kysely } from 'kysely'; + +export async function up(db: Kysely): Promise { + await db.schema + .createTable('dwCaseCorrespondence') + .addColumn('correspondenceId', 'varchar', col => col.primaryKey()) + .addColumn('documentTitle', 'varchar', col => col.notNull()) + .addColumn('docketNumber', 'varchar', col => col.notNull()) + .addColumn('filedBy', 'varchar') + .addColumn('userId', 'varchar', col => col.notNull()) + .addColumn('archived', 'boolean') + .addColumn('filingDate', 'timestamptz', col => col.notNull()) + .execute(); + + await db.schema + .createTable('dwCaseDeadline') + .addColumn('caseDeadlineId', 'varchar', col => col.primaryKey()) + .addColumn('description', 'varchar', col => col.notNull()) + .addColumn('docketNumber', 'varchar', col => col.notNull()) + .addColumn('sortableDocketNumber', 'int8', col => col.notNull()) + .addColumn('associatedJudge', 'varchar', col => col.notNull()) + .addColumn('associatedJudgeId', 'varchar') + .addColumn('createdAt', 'timestamptz', col => col.notNull()) + .addColumn('deadlineDate', 'timestamptz', col => col.notNull()) + .execute(); + + await db.schema + .createTable('dwCaseWorksheet') + .addColumn('docketNumber', 'varchar', col => col.primaryKey()) + .addColumn('statusOfMatter', 'varchar') + .addColumn('primaryIssue', 'varchar') + .addColumn('judgeUserId', 'varchar') + .addColumn('finalBriefDueDate', 'timestamptz') + .execute(); +} + +export async function down(db: Kysely): Promise { + await db.schema.dropTable('dwCaseCorrespondence').execute(); + await db.schema.dropTable('dwCaseDeadline').execute(); + await db.schema.dropTable('dwCaseWorksheet').execute(); +} diff --git a/web-api/src/persistence/postgres/utils/seed/fixtures/caseDeadlines.ts b/web-api/src/persistence/postgres/utils/seed/fixtures/caseDeadlines.ts new file mode 100644 index 00000000000..d01ed851dab --- /dev/null +++ b/web-api/src/persistence/postgres/utils/seed/fixtures/caseDeadlines.ts @@ -0,0 +1,70 @@ +/* eslint-disable @miovision/disallow-date/no-new-date */ + +import { NewCaseDeadlineKysely } from '@web-api/database-types'; + +export const caseDeadlines: NewCaseDeadlineKysely[] = [ + { + associatedJudge: 'Chief Judge', + caseDeadlineId: '08855730-3047-4ca6-a9e7-16ff64c9dcaa', + createdAt: new Date('2019-08-22T12:46:01.052Z'), + deadlineDate: new Date('2019-08-22T04:00:00.000Z'), + description: 'Pre-trial memorandum due', + docketNumber: '104-19', + sortableDocketNumber: 19000104, + }, + { + associatedJudge: 'Chief Judge', + caseDeadlineId: '0f5a666d-63c5-4378-9cd6-0b2ae141280f', + createdAt: new Date('2019-08-22T12:49:10.949Z'), + deadlineDate: new Date('2019-08-23T04:00:00.000Z'), + description: 'This is a test deadline', + docketNumber: '106-19', + sortableDocketNumber: 19000106, + }, + { + associatedJudge: 'Chief Judge', + caseDeadlineId: '307fd0e4-eeed-41bc-bbc3-a9555fccc231', + createdAt: new Date('2019-08-22T12:51:32.434Z'), + deadlineDate: new Date('2019-08-22T04:00:00.000Z'), + description: 'Filing fee due', + docketNumber: '107-19', + sortableDocketNumber: 19000107, + }, + { + associatedJudge: 'Chief Judge', + caseDeadlineId: '95b46eae-70f0-45df-91de-febdc610fed9', + createdAt: new Date('2019-08-22T12:47:16.905Z'), + deadlineDate: new Date('2019-08-25T04:00:00.000Z'), + description: 'Final status report due to Judge Ashford', + docketNumber: '109-19', + sortableDocketNumber: 19000109, + }, + { + associatedJudge: 'Buch', + associatedJudgeId: 'dabbad02-18d0-43ec-bafb-654e83405416', + caseDeadlineId: 'ad1ddb24-f3c4-47b4-b10e-76d1d050b2ab', + createdAt: new Date('2020-01-01T01:02:15.185-04:00'), + deadlineDate: new Date('2020-01-24T00:00:00.000-05:00'), + description: 'Due date migrated from Blackstone', + docketNumber: '1338-20', + sortableDocketNumber: 20001338, + }, + { + associatedJudge: 'Chief Judge', + caseDeadlineId: 'e7aeadd8-b0d0-4826-af31-22c0d8c6c173', + createdAt: new Date('2020-01-01T01:02:15.185-04:00'), + deadlineDate: new Date('2020-01-24T00:00:00.000-05:00'), + description: 'Due date migrated from Blackstone', + docketNumber: '152-12', + sortableDocketNumber: 12000152, + }, + { + associatedJudge: 'Chief Judge', + caseDeadlineId: 'ff22fe63-4117-42ee-a66c-8cfd2062a057', + createdAt: new Date('2019-08-22T12:47:16.905Z'), + deadlineDate: new Date('2019-08-25T04:00:00.000Z'), + description: 'Final status report due to Judge Ashford', + docketNumber: '104-19', + sortableDocketNumber: 19000104, + }, +]; diff --git a/web-api/src/persistence/postgres/utils/seed/fixtures/caseWorksheets.ts b/web-api/src/persistence/postgres/utils/seed/fixtures/caseWorksheets.ts new file mode 100644 index 00000000000..6288b987ecd --- /dev/null +++ b/web-api/src/persistence/postgres/utils/seed/fixtures/caseWorksheets.ts @@ -0,0 +1,9 @@ +import { NewCaseWorksheetKysely } from '@web-api/database-types'; + +export const caseWorksheets: NewCaseWorksheetKysely[] = [ + { + docketNumber: '400-22', + judgeUserId: 'dabbad00-18d0-43ec-bafb-654e83405416', + primaryIssue: 'Trumpet!\nThe trumpet!\nMambo Number 5!', + }, +]; diff --git a/web-api/src/persistence/postgres/utils/seed/fixtures/correspodence.ts b/web-api/src/persistence/postgres/utils/seed/fixtures/correspodence.ts new file mode 100644 index 00000000000..bb3ad51dcbf --- /dev/null +++ b/web-api/src/persistence/postgres/utils/seed/fixtures/correspodence.ts @@ -0,0 +1,14 @@ +/* eslint-disable @miovision/disallow-date/no-new-date */ + +import { NewCaseCorrespondenceKysely } from '@web-api/database-types'; + +export const correspondence: NewCaseCorrespondenceKysely[] = [ + { + correspondenceId: 'f1aa4aa3-c214-424c-8870-d0049c5744d7', + docketNumber: '103-19', + documentTitle: 'Internal Memo', + filedBy: 'Test Petitionsclerk', + filingDate: new Date('2019-08-14T20:35:52.915Z'), + userId: '3805d1ab-18d0-43ec-bafb-654e83405416', + }, +]; diff --git a/web-api/src/persistence/postgres/utils/seed/seed.ts b/web-api/src/persistence/postgres/utils/seed/seed.ts index 7b6700af88e..e7d5897c2cb 100644 --- a/web-api/src/persistence/postgres/utils/seed/seed.ts +++ b/web-api/src/persistence/postgres/utils/seed/seed.ts @@ -1,9 +1,12 @@ +import { caseDeadlines } from '@web-api/persistence/postgres/utils/seed/fixtures/caseDeadlines'; +import { caseWorksheets } from '@web-api/persistence/postgres/utils/seed/fixtures/caseWorksheets'; +import { correspondence } from '@web-api/persistence/postgres/utils/seed/fixtures/correspodence'; import { getDbWriter } from '../../../../database'; import { messages } from './fixtures/messages'; import { workItems } from './fixtures/workItems'; export const seed = async () => { - await getDbWriter(writer => + const insertMessages = getDbWriter(writer => writer .insertInto('dwMessage') .values(messages) @@ -11,6 +14,37 @@ export const seed = async () => { .execute(), ); + const insertCaseDeadline = getDbWriter(writer => + writer + .insertInto('dwCaseDeadline') + .values(caseDeadlines) + .onConflict(oc => oc.column('caseDeadlineId').doNothing()) // ensure doesn't fail if exists + .execute(), + ); + + const insertCorrespondence = getDbWriter(writer => + writer + .insertInto('dwCaseCorrespondence') + .values(correspondence) + .onConflict(oc => oc.column('correspondenceId').doNothing()) // ensure doesn't fail if exists + .execute(), + ); + + const insertCaseWorksheet = getDbWriter(writer => + writer + .insertInto('dwCaseWorksheet') + .values(caseWorksheets) + .onConflict(oc => oc.column('docketNumber').doNothing()) // ensure doesn't fail if exists + .execute(), + ); + + await Promise.all([ + insertMessages, + insertCaseDeadline, + insertCorrespondence, + insertCaseWorksheet, + ]); + await getDbWriter(writer => writer .insertInto('dwWorkItem') diff --git a/web-api/storage/fixtures/seed/efcms-local.json b/web-api/storage/fixtures/seed/efcms-local.json index 20fa374c262..301991385e1 100644 --- a/web-api/storage/fixtures/seed/efcms-local.json +++ b/web-api/storage/fixtures/seed/efcms-local.json @@ -100,91 +100,6 @@ "sk": "case|101-20", "pk": "case-by-docket-number|7805d1ab-18d0-43ec-bafb-654e83405416" }, - { - "associatedJudge": "Chief Judge", - "createdAt": "2019-08-22T12:46:01.052Z", - "deadlineDate": "2019-08-22T04:00:00.000Z", - "entityName": "CaseDeadline", - "sk": "case-deadline|08855730-3047-4ca6-a9e7-16ff64c9dcaa", - "caseDeadlineId": "08855730-3047-4ca6-a9e7-16ff64c9dcaa", - "sortableDocketNumber": 19000104, - "description": "Pre-trial memorandum due", - "pk": "case-deadline|08855730-3047-4ca6-a9e7-16ff64c9dcaa", - "docketNumber": "104-19" - }, - { - "associatedJudge": "Chief Judge", - "createdAt": "2019-08-22T12:49:10.949Z", - "deadlineDate": "2019-08-23T04:00:00.000Z", - "entityName": "CaseDeadline", - "sk": "case-deadline|0f5a666d-63c5-4378-9cd6-0b2ae141280f", - "caseDeadlineId": "0f5a666d-63c5-4378-9cd6-0b2ae141280f", - "sortableDocketNumber": 19000106, - "description": "This is a test deadline", - "pk": "case-deadline|0f5a666d-63c5-4378-9cd6-0b2ae141280f", - "docketNumber": "106-19" - }, - { - "associatedJudge": "Chief Judge", - "createdAt": "2019-08-22T12:51:32.434Z", - "deadlineDate": "2019-08-22T04:00:00.000Z", - "entityName": "CaseDeadline", - "sk": "case-deadline|307fd0e4-eeed-41bc-bbc3-a9555fccc231", - "caseDeadlineId": "307fd0e4-eeed-41bc-bbc3-a9555fccc231", - "sortableDocketNumber": 19000107, - "description": "Filing fee due", - "pk": "case-deadline|307fd0e4-eeed-41bc-bbc3-a9555fccc231", - "docketNumber": "107-19" - }, - { - "associatedJudge": "Chief Judge", - "createdAt": "2019-08-22T12:47:16.905Z", - "deadlineDate": "2019-08-25T04:00:00.000Z", - "entityName": "CaseDeadline", - "sk": "case-deadline|95b46eae-70f0-45df-91de-febdc610fed9", - "caseDeadlineId": "95b46eae-70f0-45df-91de-febdc610fed9", - "sortableDocketNumber": 19000109, - "description": "Final status report due to Judge Ashford", - "pk": "case-deadline|95b46eae-70f0-45df-91de-febdc610fed9", - "docketNumber": "109-19" - }, - { - "associatedJudge": "Buch", - "createdAt": "2020-01-01T01:02:15.185-04:00", - "entityName": "CaseDeadline", - "deadlineDate": "2020-01-24T00:00:00.000-05:00", - "sk": "case-deadline|ad1ddb24-f3c4-47b4-b10e-76d1d050b2ab", - "caseDeadlineId": "ad1ddb24-f3c4-47b4-b10e-76d1d050b2ab", - "sortableDocketNumber": 20001338, - "description": "Due date migrated from Blackstone", - "pk": "case-deadline|ad1ddb24-f3c4-47b4-b10e-76d1d050b2ab", - "docketNumber": "1338-20", - "associatedJudgeId": "dabbad02-18d0-43ec-bafb-654e83405416" - }, - { - "associatedJudge": "Chief Judge", - "createdAt": "2020-01-01T01:02:15.185-04:00", - "entityName": "CaseDeadline", - "deadlineDate": "2020-01-24T00:00:00.000-05:00", - "sk": "case-deadline|e7aeadd8-b0d0-4826-af31-22c0d8c6c173", - "caseDeadlineId": "e7aeadd8-b0d0-4826-af31-22c0d8c6c173", - "sortableDocketNumber": 12000152, - "description": "Due date migrated from Blackstone", - "pk": "case-deadline|e7aeadd8-b0d0-4826-af31-22c0d8c6c173", - "docketNumber": "152-12" - }, - { - "associatedJudge": "Chief Judge", - "createdAt": "2019-08-22T12:47:16.905Z", - "deadlineDate": "2019-08-25T04:00:00.000Z", - "entityName": "CaseDeadline", - "sk": "case-deadline|ff22fe63-4117-42ee-a66c-8cfd2062a057", - "caseDeadlineId": "ff22fe63-4117-42ee-a66c-8cfd2062a057", - "sortableDocketNumber": 19000104, - "description": "Final status report due to Judge Ashford", - "pk": "case-deadline|ff22fe63-4117-42ee-a66c-8cfd2062a057", - "docketNumber": "104-19" - }, { "associatedJudge": "Chief Judge", "isSealed": false, @@ -7883,16 +7798,6 @@ "docketNumber": "103-19", "status": "New" }, - { - "numberOfPages": 1, - "filingDate": "2019-08-14T20:35:52.915Z", - "filedBy": "Test Petitionsclerk", - "sk": "correspondence|f1aa4aa3-c214-424c-8870-d0049c5744d7", - "correspondenceId": "f1aa4aa3-c214-424c-8870-d0049c5744d7", - "pk": "case|103-19", - "documentTitle": "Internal Memo", - "userId": "3805d1ab-18d0-43ec-bafb-654e83405416" - }, { "servedParties": [ { @@ -9235,14 +9140,6 @@ "servedAt": "2020-04-14T19:59:46.672Z", "docketNumber": "104-18" }, - { - "sk": "case-deadline|08855730-3047-4ca6-a9e7-16ff64c9dcaa", - "pk": "case|104-19" - }, - { - "sk": "case-deadline|ff22fe63-4117-42ee-a66c-8cfd2062a057", - "pk": "case|104-19" - }, { "associatedJudge": "Chief Judge", "procedureType": "Regular", @@ -12846,10 +12743,6 @@ "pk": "case|105-67", "email": "privatePractitioner@example.com" }, - { - "sk": "case-deadline|0f5a666d-63c5-4378-9cd6-0b2ae141280f", - "pk": "case|106-19" - }, { "associatedJudge": "Chief Judge", "procedureType": "Regular", @@ -13310,10 +13203,6 @@ "pk": "case|106-23", "email": "privatePractitioner@example.com" }, - { - "sk": "case-deadline|307fd0e4-eeed-41bc-bbc3-a9555fccc231", - "pk": "case|107-19" - }, { "associatedJudge": "Chief Judge", "isSealed": false, @@ -14061,10 +13950,6 @@ "servedAt": "2020-09-25T19:27:16.706Z", "docketNumber": "108-19" }, - { - "sk": "case-deadline|95b46eae-70f0-45df-91de-febdc610fed9", - "pk": "case|109-19" - }, { "associatedJudge": "Chief Judge", "procedureType": "Regular", @@ -16787,10 +16672,6 @@ "servedAt": "2021-10-29T13:42:43.037Z", "docketNumber": "129-20" }, - { - "sk": "case-deadline|ad1ddb24-f3c4-47b4-b10e-76d1d050b2ab", - "pk": "case|1338-20" - }, { "associatedJudge": "Chief Judge", "isSealed": false, @@ -17206,10 +17087,6 @@ "servedAt": "2019-08-25T05:00:00.000Z", "docketNumber": "101-18" }, - { - "sk": "case-deadline|e7aeadd8-b0d0-4826-af31-22c0d8c6c173", - "pk": "case|152-12" - }, { "associatedJudge": "Chief Judge", "isSealed": false, @@ -21252,14 +21129,6 @@ "docketNumber": "320-21", "addToCoversheet": false }, - { - "sk": "case-worksheet|400-22", - "pk": "case|400-22", - "docketNumber": "400-22", - "entityName": "CaseWorksheet", - "gsi1pk": "judge-case-worksheet|dabbad00-18d0-43ec-bafb-654e83405416", - "primaryIssue": "Trumpet!\nThe trumpet!\nMambo Number 5!" - }, { "associatedJudge": "Colvin", "isSealed": false, diff --git a/web-client/integration-tests/caseWorksheetsJourney.test.ts b/web-client/integration-tests/caseWorksheetsJourney.test.ts index ced22237e7b..667a07cfbc7 100644 --- a/web-client/integration-tests/caseWorksheetsJourney.test.ts +++ b/web-client/integration-tests/caseWorksheetsJourney.test.ts @@ -299,7 +299,7 @@ describe('Case Worksheets Journey', () => { docketNumber: cerebralTest.docketNumber, status: CASE_STATUS_TYPES.cav, worksheet: { - finalBriefDueDate: '2023-08-29', + finalBriefDueDate: '2023-08-29T04:00:00.000Z', statusOfMatter: CaseWorksheet.STATUS_OF_MATTER_OPTIONS[0], }, }); diff --git a/web-client/integration-tests/journey/docketClerkViewsAutoGeneratedCaseDeadline.ts b/web-client/integration-tests/journey/docketClerkViewsAutoGeneratedCaseDeadline.ts index 7c67d4d47fc..31e31fb0012 100644 --- a/web-client/integration-tests/journey/docketClerkViewsAutoGeneratedCaseDeadline.ts +++ b/web-client/integration-tests/journey/docketClerkViewsAutoGeneratedCaseDeadline.ts @@ -17,7 +17,7 @@ export const docketClerkViewsAutoGeneratedCaseDeadline = ({ }); expect(caseDetail.caseDeadlines[0].deadlineDate).toEqual( - '2050-02-02T00:00:00.000-05:00', + '2050-02-02T05:00:00.000Z', ); expect(caseDetail.caseDeadlines[0].description).toEqual( expectedDeadlineDescription, diff --git a/web-client/integration-tests/journey/petitionsClerkViewsDeadlineReport.ts b/web-client/integration-tests/journey/petitionsClerkViewsDeadlineReport.ts index 08fbab1cb29..65ecacada81 100644 --- a/web-client/integration-tests/journey/petitionsClerkViewsDeadlineReport.ts +++ b/web-client/integration-tests/journey/petitionsClerkViewsDeadlineReport.ts @@ -54,32 +54,32 @@ export const petitionsClerkViewsDeadlineReport = ( expect(deadlines).toMatchObject([ { associatedJudge: 'Buch', - deadlineDate: `${options.year}-01-${options.day}T00:00:00.000-05:00`, + deadlineDate: `${options.year}-01-${options.day}T05:00:00.000Z`, docketNumber: cerebralTest.createdDocketNumbers[0], }, { associatedJudge: CHIEF_JUDGE, - deadlineDate: `${options.year}-01-${options.day}T00:00:00.000-05:00`, + deadlineDate: `${options.year}-01-${options.day}T05:00:00.000Z`, docketNumber: cerebralTest.createdDocketNumbers[1], }, { associatedJudge: CHIEF_JUDGE, - deadlineDate: `${options.year}-01-${options.day}T00:00:00.000-05:00`, + deadlineDate: `${options.year}-01-${options.day}T05:00:00.000Z`, docketNumber: cerebralTest.createdDocketNumbers[2], }, { associatedJudge: 'Buch', - deadlineDate: `${options.year}-02-${options.day}T00:00:00.000-05:00`, + deadlineDate: `${options.year}-02-${options.day}T05:00:00.000Z`, docketNumber: cerebralTest.createdDocketNumbers[0], }, { associatedJudge: CHIEF_JUDGE, - deadlineDate: `${options.year}-02-${options.day}T00:00:00.000-05:00`, + deadlineDate: `${options.year}-02-${options.day}T05:00:00.000Z`, docketNumber: cerebralTest.createdDocketNumbers[1], }, { associatedJudge: CHIEF_JUDGE, - deadlineDate: `${options.year}-02-${options.day}T00:00:00.000-05:00`, + deadlineDate: `${options.year}-02-${options.day}T05:00:00.000Z`, docketNumber: cerebralTest.createdDocketNumbers[2], }, ]); @@ -104,12 +104,12 @@ export const petitionsClerkViewsDeadlineReport = ( expect(deadlines).toMatchObject([ { associatedJudge: 'Buch', - deadlineDate: `${options.year}-01-${options.day}T00:00:00.000-05:00`, + deadlineDate: `${options.year}-01-${options.day}T05:00:00.000Z`, docketNumber: cerebralTest.createdDocketNumbers[0], }, { associatedJudge: 'Buch', - deadlineDate: `${options.year}-02-${options.day}T00:00:00.000-05:00`, + deadlineDate: `${options.year}-02-${options.day}T05:00:00.000Z`, docketNumber: cerebralTest.createdDocketNumbers[0], }, ]); diff --git a/web-client/src/presenter/actions/CaseWorksheet/setAddEditCaseWorksheetModalStateAction.test.ts b/web-client/src/presenter/actions/CaseWorksheet/setAddEditCaseWorksheetModalStateAction.test.ts index d61a930d83c..0f3130d00a7 100644 --- a/web-client/src/presenter/actions/CaseWorksheet/setAddEditCaseWorksheetModalStateAction.test.ts +++ b/web-client/src/presenter/actions/CaseWorksheet/setAddEditCaseWorksheetModalStateAction.test.ts @@ -1,6 +1,7 @@ import { MOCK_CASE } from '@shared/test/mockCase'; import { RawCaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; import { applicationContextForClient as applicationContext } from '@web-client/test/createClientTestApplicationContext'; +import { judgeColvin } from '@shared/test/mockUsers'; import { presenter } from '@web-client/presenter/presenter-mock'; import { runAction } from '@web-client/presenter/test.cerebral'; import { setAddEditCaseWorksheetModalStateAction } from '@web-client/presenter/actions/CaseWorksheet/setAddEditCaseWorksheetModalStateAction'; @@ -12,6 +13,7 @@ describe('setAddEditCaseWorksheetModalStateAction', () => { const mockWorksheet: RawCaseWorksheet = { docketNumber: MOCK_CASE.docketNumber, entityName: 'CaseWorksheet', + judgeUserId: judgeColvin.userId, }; const { state } = await runAction(setAddEditCaseWorksheetModalStateAction, { diff --git a/web-client/src/presenter/actions/CaseWorksheet/setCaseWorksheetAction.test.ts b/web-client/src/presenter/actions/CaseWorksheet/setCaseWorksheetAction.test.ts index c448d338d6f..5f3a3eda50f 100644 --- a/web-client/src/presenter/actions/CaseWorksheet/setCaseWorksheetAction.test.ts +++ b/web-client/src/presenter/actions/CaseWorksheet/setCaseWorksheetAction.test.ts @@ -1,5 +1,6 @@ import { MOCK_CASE } from '@shared/test/mockCase'; import { RawCaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; +import { judgeColvin } from '@shared/test/mockUsers'; import { runAction } from '@web-client/presenter/test.cerebral'; import { setCaseWorksheetAction } from './setCaseWorksheetAction'; @@ -7,6 +8,7 @@ describe('setUpdatedCaseInStateAction', () => { const mockCaseWorksheet: RawCaseWorksheet = { docketNumber: MOCK_CASE.docketNumber, entityName: 'CaseWorksheet', + judgeUserId: judgeColvin.userId, primaryIssue: 'Superstition ain`t the way', }; diff --git a/web-client/src/presenter/actions/CaseWorksheet/updateCaseWorksheetAction.test.ts b/web-client/src/presenter/actions/CaseWorksheet/updateCaseWorksheetAction.test.ts index e7026efb740..5dbc1a2f7d0 100644 --- a/web-client/src/presenter/actions/CaseWorksheet/updateCaseWorksheetAction.test.ts +++ b/web-client/src/presenter/actions/CaseWorksheet/updateCaseWorksheetAction.test.ts @@ -2,6 +2,7 @@ import { CaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorks import { MOCK_CASE } from '@shared/test/mockCase'; import { MOCK_CASE_WORKSHEET } from '@shared/test/mockCaseWorksheet'; import { applicationContextForClient as applicationContext } from '@web-client/test/createClientTestApplicationContext'; +import { judgeColvin } from '@shared/test/mockUsers'; import { presenter } from '../../presenter-mock'; import { runAction } from '@web-client/presenter/test.cerebral'; import { updateCaseWorksheetAction } from './updateCaseWorksheetAction'; @@ -18,12 +19,19 @@ describe('updateCaseWorksheetAction', () => { .getUseCases() .updateCaseWorksheetInteractor.mockResolvedValue(MOCK_CASE_WORKSHEET); + applicationContext + .getUseCases() + .getJudgeInSectionInteractor.mockResolvedValue({ + userId: judgeColvin.userId, + }); + const { output } = await runAction(updateCaseWorksheetAction, { modules: { presenter, }, state: { form: mockForm, + user: { section: '', userId: '' }, }, }); diff --git a/web-client/src/presenter/actions/CaseWorksheet/updateCaseWorksheetAction.ts b/web-client/src/presenter/actions/CaseWorksheet/updateCaseWorksheetAction.ts index 79fac5bd030..55c6a7a4717 100644 --- a/web-client/src/presenter/actions/CaseWorksheet/updateCaseWorksheetAction.ts +++ b/web-client/src/presenter/actions/CaseWorksheet/updateCaseWorksheetAction.ts @@ -1,4 +1,8 @@ -import { RawCaseWorksheet } from '@shared/business/entities/caseWorksheet/CaseWorksheet'; +import { + CaseWorksheet, + RawCaseWorksheet, +} from '@shared/business/entities/caseWorksheet/CaseWorksheet'; +import { getJudgeForCurrentUserAction } from '@web-client/presenter/actions/getJudgeForCurrentUserAction'; import { state } from '@web-client/presenter/app.cerebral'; export const updateCaseWorksheetAction = async ({ @@ -9,15 +13,21 @@ export const updateCaseWorksheetAction = async ({ state.form, ); + const { judgeUser } = await getJudgeForCurrentUserAction({ + applicationContext, + get, + } as ActionProps); + const updatedWorksheet = await applicationContext .getUseCases() .updateCaseWorksheetInteractor(applicationContext, { - worksheet: { + worksheet: new CaseWorksheet({ docketNumber, finalBriefDueDate, + judgeUserId: judgeUser.userId, primaryIssue, statusOfMatter, - }, + }).toRawObject(), }); return { updatedWorksheet }; diff --git a/web-client/src/presenter/actions/validateCaseWorksheetAction.test.ts b/web-client/src/presenter/actions/validateCaseWorksheetAction.test.ts index 3b652b6a023..532cdfda452 100644 --- a/web-client/src/presenter/actions/validateCaseWorksheetAction.test.ts +++ b/web-client/src/presenter/actions/validateCaseWorksheetAction.test.ts @@ -1,5 +1,6 @@ import { MOCK_CASE } from '@shared/test/mockCase'; import { applicationContextForClient as applicationContext } from '@web-client/test/createClientTestApplicationContext'; +import { judgeColvin } from '@shared/test/mockUsers'; import { presenter } from '../presenter-mock'; import { runAction } from '@web-client/presenter/test.cerebral'; import { validateCaseWorksheetAction } from './validateCaseWorksheetAction'; @@ -18,6 +19,12 @@ describe('validateCaseWorksheetAction', () => { }; presenter.providers.applicationContext = applicationContext; + + applicationContext + .getUseCases() + .getJudgeInSectionInteractor.mockResolvedValue({ + userId: judgeColvin.userId, + }); }); it('should call the success path when the updated case worksheet is valid', async () => { @@ -36,6 +43,7 @@ describe('validateCaseWorksheetAction', () => { primaryIssue: 'This is a primary issue.', statusOfMatter: undefined, }, + user: { section: '', userId: '' }, }, }); @@ -64,6 +72,7 @@ describe('validateCaseWorksheetAction', () => { primaryIssue: 'This is a primary issue.', statusOfMatter: undefined, }, + user: { section: '', userId: '' }, }, }); diff --git a/web-client/src/presenter/actions/validateCaseWorksheetAction.ts b/web-client/src/presenter/actions/validateCaseWorksheetAction.ts index fb616126163..22cc43c8a79 100644 --- a/web-client/src/presenter/actions/validateCaseWorksheetAction.ts +++ b/web-client/src/presenter/actions/validateCaseWorksheetAction.ts @@ -1,6 +1,7 @@ +import { getJudgeForCurrentUserAction } from '@web-client/presenter/actions/getJudgeForCurrentUserAction'; import { state } from '@web-client/presenter/app.cerebral'; -export const validateCaseWorksheetAction = ({ +export const validateCaseWorksheetAction = async ({ applicationContext, get, path, @@ -9,12 +10,18 @@ export const validateCaseWorksheetAction = ({ state.form, ); + const { judgeUser } = await getJudgeForCurrentUserAction({ + applicationContext, + get, + } as ActionProps); + const errors = applicationContext .getUseCases() .validateCaseWorksheetInteractor({ caseWorksheet: { docketNumber, finalBriefDueDate, + judgeUserId: judgeUser.userId, primaryIssue, statusOfMatter, }, diff --git a/web-client/src/presenter/computeds/CaseWorksheets/caseWorksheetsHelper.ts b/web-client/src/presenter/computeds/CaseWorksheets/caseWorksheetsHelper.ts index 5cbb6fdc8df..d8739628d98 100644 --- a/web-client/src/presenter/computeds/CaseWorksheets/caseWorksheetsHelper.ts +++ b/web-client/src/presenter/computeds/CaseWorksheets/caseWorksheetsHelper.ts @@ -13,7 +13,7 @@ type CaseWorksheetTableRow = { daysSinceLastStatusChange: string; caseCaption: string; docketNumber: string; - docketNumberWithSuffix: string; + docketNumberWithSuffix?: string; formattedSubmittedCavStatusDate: string; finalBriefDueDateFormatted: string; status: string; diff --git a/web-client/src/presenter/computeds/JudgeActivityReport/judgeActivityReportHelper.test.ts b/web-client/src/presenter/computeds/JudgeActivityReport/judgeActivityReportHelper.test.ts index 0b57a01f377..8f0804a9f80 100644 --- a/web-client/src/presenter/computeds/JudgeActivityReport/judgeActivityReportHelper.test.ts +++ b/web-client/src/presenter/computeds/JudgeActivityReport/judgeActivityReportHelper.test.ts @@ -411,7 +411,7 @@ describe('judgeActivityReportHelper', () => { ...MOCK_SUBMITTED_CASE, caseStatusHistory: [ { - ...MOCK_SUBMITTED_CASE.caseStatusHistory[0], + ...MOCK_SUBMITTED_CASE.caseStatusHistory?.[0], date: '2023-05-11T14:19:28.717Z', }, ], @@ -422,7 +422,7 @@ describe('judgeActivityReportHelper', () => { ...MOCK_SUBMITTED_CASE, caseStatusHistory: [ { - ...MOCK_SUBMITTED_CASE.caseStatusHistory[0], + ...MOCK_SUBMITTED_CASE.caseStatusHistory?.[0], date: '2023-05-29T14:19:28.717Z', }, ], @@ -432,7 +432,7 @@ describe('judgeActivityReportHelper', () => { ...MOCK_SUBMITTED_CASE, caseStatusHistory: [ { - ...MOCK_SUBMITTED_CASE.caseStatusHistory[0], + ...MOCK_SUBMITTED_CASE.caseStatusHistory?.[0], date: '2023-05-15T14:19:28.717Z', }, ], @@ -535,7 +535,7 @@ describe('judgeActivityReportHelper', () => { associatedJudge: 'Colvin', caseStatusHistory: [ { - ...MOCK_SUBMITTED_CASE.caseStatusHistory[0], + ...MOCK_SUBMITTED_CASE.caseStatusHistory?.[0], date: '2015-05-11T14:19:28.717Z', }, ], @@ -546,7 +546,7 @@ describe('judgeActivityReportHelper', () => { associatedJudge: 'Ashford', caseStatusHistory: [ { - ...MOCK_SUBMITTED_CASE.caseStatusHistory[0], + ...MOCK_SUBMITTED_CASE.caseStatusHistory?.[0], date: '2023-05-11T14:19:28.717Z', }, ], @@ -557,7 +557,7 @@ describe('judgeActivityReportHelper', () => { associatedJudge: 'Colvin', caseStatusHistory: [ { - ...MOCK_SUBMITTED_CASE.caseStatusHistory[0], + ...MOCK_SUBMITTED_CASE.caseStatusHistory?.[0], date: '2023-05-11T14:19:28.717Z', }, ], @@ -568,7 +568,7 @@ describe('judgeActivityReportHelper', () => { associatedJudge: 'Colvin', caseStatusHistory: [ { - ...MOCK_SUBMITTED_CASE.caseStatusHistory[0], + ...MOCK_SUBMITTED_CASE.caseStatusHistory?.[0], date: '2017-05-11T14:19:28.717Z', }, ], diff --git a/web-client/src/presenter/computeds/caseStatusHistoryHelper.ts b/web-client/src/presenter/computeds/caseStatusHistoryHelper.ts index 61de8f331fc..af005dc3b4a 100644 --- a/web-client/src/presenter/computeds/caseStatusHistoryHelper.ts +++ b/web-client/src/presenter/computeds/caseStatusHistoryHelper.ts @@ -16,12 +16,12 @@ export const caseStatusHistoryHelper = ( const caseStatusHistory = get(state.caseDetail.caseStatusHistory); return { - formattedCaseStatusHistory: caseStatusHistory.map(history => ({ + formattedCaseStatusHistory: caseStatusHistory?.map(history => ({ ...history, formattedDateChanged: applicationContext .getUtilities() .formatDateString(history.date, 'MMDDYY'), })), - isTableDisplayed: caseStatusHistory.length > 0, + isTableDisplayed: caseStatusHistory && caseStatusHistory.length > 0, }; }; diff --git a/web-client/src/presenter/computeds/docketRecordHelper.ts b/web-client/src/presenter/computeds/docketRecordHelper.ts index 5bfa18e95dc..77eca8d9661 100644 --- a/web-client/src/presenter/computeds/docketRecordHelper.ts +++ b/web-client/src/presenter/computeds/docketRecordHelper.ts @@ -9,7 +9,7 @@ export const docketRecordHelper = ( countOfDocumentsForDownload: number; showBatchDownloadControls: boolean; showEditOrSealDocketRecordEntry: boolean; - showPrintableDocketRecord: boolean; + showPrintableDocketRecord?: boolean; sortLabelTextMobile: string; } => { const permissions = get(state.permissions); diff --git a/web-client/src/test/createClientTestApplicationContext.ts b/web-client/src/test/createClientTestApplicationContext.ts index 13591203837..5c1dd47e829 100644 --- a/web-client/src/test/createClientTestApplicationContext.ts +++ b/web-client/src/test/createClientTestApplicationContext.ts @@ -67,7 +67,6 @@ import { } from '@shared/business/utilities/generateChangeOfAddressTemplate'; import { getAllWebSocketConnections } from '@web-api/persistence/dynamo/notifications/getAllWebSocketConnections'; import { getCaseByDocketNumber } from '@web-api/persistence/dynamo/cases/getCaseByDocketNumber'; -import { getCaseDeadlinesByDocketNumber } from '@web-api/persistence/dynamo/caseDeadlines/getCaseDeadlinesByDocketNumber'; import { getCaseDocumentsIdsFilteredByDocumentType } from '@shared/business/utilities/getCaseDocumentsIdsFilteredByDocumentType'; import { getConstants } from '@web-client/getConstants'; import { getCropBox } from '@shared/business/utilities/getCropBox'; @@ -100,7 +99,6 @@ import { setServiceIndicatorsForCase } from '@shared/business/utilities/setServi import { setupPdfDocument } from '@shared/business/utilities/setupPdfDocument'; import { unsealDocketEntryInteractor } from '@shared/proxies/editDocketEntry/unsealDocketEntryProxy'; import { updateCase } from '@web-api/persistence/dynamo/cases/updateCase'; -import { updateCaseCorrespondence } from '@web-api/persistence/dynamo/correspondence/updateCaseCorrespondence'; import { updateDocketEntry } from '@web-api/persistence/dynamo/documents/updateDocketEntry'; import { updateUserRecords } from '@web-api/persistence/dynamo/users/createNewPractitionerUser'; import { uploadDocumentAndMakeSafeInteractor } from '@shared/business/useCases/uploadDocumentAndMakeSafeInteractor'; @@ -429,10 +427,7 @@ const createTestApplicationContext = () => { .mockImplementation(getAllWebSocketConnections), getCalendaredCasesForTrialSession: jest.fn(), getCaseByDocketNumber: jest.fn().mockImplementation(getCaseByDocketNumber), - getCaseDeadlinesByDateRange: jest.fn(), - getCaseDeadlinesByDocketNumber: jest - .fn() - .mockImplementation(getCaseDeadlinesByDocketNumber), + getCasesByFilters: jest.fn(), getDispatchNotification: jest.fn(), getDocument: jest.fn(), getDocumentQCInboxForSection: jest.fn(), @@ -452,7 +447,6 @@ const createTestApplicationContext = () => { getTrialSessionJobStatusForCase: jest.fn(), getUserById: jest.fn().mockImplementation(getUserByIdPersistence), getUserCaseMappingsByDocketNumber: jest.fn().mockReturnValue([]), - getWorkItemsByDocketNumber: jest.fn().mockReturnValue([]), incrementCounter, incrementKeyCount: jest.fn(), isEmailAvailable: jest.fn(), @@ -466,9 +460,6 @@ const createTestApplicationContext = () => { setPriorityOnAllWorkItems: jest.fn(), setTrialSessionJobStatusForCase: jest.fn(), updateCase: jest.fn().mockImplementation(updateCase), - updateCaseCorrespondence: jest - .fn() - .mockImplementation(updateCaseCorrespondence), updateCaseHearing: jest.fn(), updateDocketEntry: jest.fn().mockImplementation(updateDocketEntry), uploadPdfFromClient: jest.fn().mockImplementation(() => ''),