Skip to content

Commit

Permalink
decouple healthPlanFormData types
Browse files Browse the repository at this point in the history
  • Loading branch information
mojotalantikite committed Aug 22, 2024
1 parent b824331 commit cc9e551
Show file tree
Hide file tree
Showing 38 changed files with 562 additions and 57 deletions.
10 changes: 8 additions & 2 deletions packages/common-code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@
"build": "tsc"
},
"dependencies": {
"@mc-review/constants": "workspace:*",
"@mc-review/types": "workspace:*",
"@mc-review/gql-helpers": "workspace:*",
"url-parse": "^1.5.10",
"dayjs": "^1.10.5"
"dayjs": "^1.10.5",
"zod": "^3.10.1"
},
"devDependencies": {
"@types/url-parse": "^1.4.3"
"@types/url-parse": "^1.4.3",
"@types/jest": "^29.5.6",
"@types/node": "^20.14.12"
}
}
10 changes: 5 additions & 5 deletions packages/common-code/src/ContractType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Contract, ContractRevision } from '../gen/gqlClient'
import { getLastContractSubmission } from '../gqlHelpers/contractsAndRates'
import { Contract, ContractRevision } from './gen/gqlClient'
import { getLastContractSubmission } from '@mc-review/gql-helpers'

const getContractRev = (contract: Contract): ContractRevision | undefined => {
if (contract.draftRevision) {
Expand All @@ -10,10 +10,9 @@ const getContractRev = (contract: Contract): ContractRevision | undefined => {
}
const isContractOnly = (contract: Contract): boolean => {
const contractRev = getContractRev(contract)
return contractRev?.formData?.submissionType === 'CONTRACT_ONLY'
return contractRev?.formData?.submissionType === 'CONTRACT_ONLY'
}


const isBaseContract = (contract: Contract): boolean => {
const contractRev = getContractRev(contract)
return contractRev?.formData?.contractType === 'BASE'
Expand All @@ -35,7 +34,8 @@ const isContractAndRates = (contract: Contract): boolean => {
}

const isContractWithProvisions = (contract: Contract): boolean =>
isContractAmendment(contract) || (isBaseContract(contract) && !isCHIPOnly(contract))
isContractAmendment(contract) ||
(isBaseContract(contract) && !isCHIPOnly(contract))

const isSubmitted = (contract: Contract): boolean =>
contract.status === 'SUBMITTED'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ZodError } from 'zod'
import { mcreviewproto } from '../../../gen/healthPlanFormDataProto'
import { mcreviewproto } from '../../gen/healthPlanFormDataProto'
import {
basicLockedHealthPlanFormData,
basicHealthPlanFormData,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ZodError } from 'zod'
import { mcreviewproto } from '../../../gen/healthPlanFormDataProto'
import { mcreviewproto } from '../../gen/healthPlanFormDataProto'
import {
basicLockedHealthPlanFormData,
basicHealthPlanFormData,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mcreviewproto } from '../../../gen/healthPlanFormDataProto'
import { mcreviewproto } from '../../gen/healthPlanFormDataProto'
import {
unlockedHealthPlanFormDataZodSchema,
lockedHealthPlanFormDataZodSchema,
Expand Down Expand Up @@ -338,12 +338,11 @@ function parseRateInfos(

if (rateInfos.length > 0) {
rateInfos.forEach((rateInfo) => {

/**
* Not adding more to the proto schema, instead additional actuaries are added to the actuaryContacts array
* from index 1.
*/
const certifyingActuary = rateInfo?.actuaryContacts?.slice(0,1)
const certifyingActuary = rateInfo?.actuaryContacts?.slice(0, 1)
const additionalActuaries = rateInfo.actuaryContacts?.slice(1)

const rate: RecursivePartial<RateInfoType> = {
Expand Down Expand Up @@ -372,12 +371,8 @@ function parseRateInfos(
rateCertificationName: parseRateCertificationName(
rateInfo?.rateCertificationName
),
actuaryContacts: parseActuaryContacts(
certifyingActuary
),
addtlActuaryContacts: parseActuaryContacts(
additionalActuaries
),
actuaryContacts: parseActuaryContacts(certifyingActuary),
addtlActuaryContacts: parseActuaryContacts(additionalActuaries),
actuaryCommunicationPreference: enumToDomain(
mcreviewproto.ActuaryCommunicationType,
rateInfo?.actuaryCommunicationPreference
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Right now when we use proto data directly after it is deserialized to typescript
toLatestVersion is an quick example of this kind of data translation function - it makes a proto compatible change
and updates the data in a proto to match the latest schema
*/
import { mcreviewproto } from '../../../gen/healthPlanFormDataProto'
import { mcreviewproto } from '../../gen/healthPlanFormDataProto'

const CURRENT_PROTO_VERSION = 4

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mcreviewproto, google } from '../../../gen/healthPlanFormDataProto'
import { mcreviewproto, google } from '../../gen/healthPlanFormDataProto'
import {
UnlockedHealthPlanFormDataType,
LockedHealthPlanFormDataType,
Expand Down Expand Up @@ -200,14 +200,15 @@ const toProtoBuffer = (
rateInfos:
domainData.rateInfos && domainData.rateInfos.length
? domainData.rateInfos.map((rateInfo) => {

/**
* Not adding more to the proto schema, we will combine certifying actuaries with additional actuaries
* in the same array, where certifying actuary is at index 0 and additional actuaries are from index
* 1 and beyond.
*/
const combinedActuaries =
rateInfo?.actuaryContacts.concat(rateInfo?.addtlActuaryContacts ?? []) ?? []
/**
* Not adding more to the proto schema, we will combine certifying actuaries with additional actuaries
* in the same array, where certifying actuary is at index 0 and additional actuaries are from index
* 1 and beyond.
*/
const combinedActuaries =
rateInfo?.actuaryContacts.concat(
rateInfo?.addtlActuaryContacts ?? []
) ?? []

return {
id: rateInfo.id,
Expand Down
14 changes: 14 additions & 0 deletions packages/document-helpers/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "@mc-review/document-helpers",
"version": "1.0.0",
"description": "",
"main": "build/index.js",
"scripts": {
"build": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@mc-review/common-code": "workspace:*",
"typescript": "^4.9.5"
}
}
14 changes: 14 additions & 0 deletions packages/document-helpers/src/getAllDocuments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { HealthPlanFormDataType } from '../common-code/healthPlanFormDataType'

const getAllDocuments = (pkg: HealthPlanFormDataType) => {
let allDocuments = [...pkg.contractDocuments, ...pkg.documents]
if (pkg.rateInfos.length > 0) {
pkg.rateInfos.forEach((rateInfo) => {
allDocuments = allDocuments.concat(rateInfo.rateDocuments)
allDocuments = allDocuments.concat(rateInfo.supportingDocuments)
})
}
return allDocuments
}

export { getAllDocuments }
2 changes: 2 additions & 0 deletions packages/document-helpers/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { makeDocumentDateTable } from './makeDocumentDateLookupTable'
export { makeDocumentS3KeyLookup } from './makeDocumentKeyLookupList'
120 changes: 120 additions & 0 deletions packages/document-helpers/src/makeDocumentDateLookupTable.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { makeDocumentDateTable } from './makeDocumentDateLookupTable'
import {
mockDraftHealthPlanPackage,
mockSubmittedHealthPlanPackageWithRevision,
} from '@mc-review/test-helpers'
import { UnlockedHealthPlanFormDataType } from '../common-code/healthPlanFormDataType'
import { TextEncoder, TextDecoder } from 'util'
import { buildRevisionsLookup } from '../gqlHelpers/fetchHealthPlanPackageWrapper'

Object.assign(global, { TextDecoder, TextEncoder })

describe('makeDocumentDateTable', () => {
it('should make a proper lookup table', () => {
const submission = mockSubmittedHealthPlanPackageWithRevision({
currentSubmitInfo: {
updatedAt: new Date('2022-03-28T17:56:32.953Z'),
},
previousSubmitInfo: {
updatedAt: new Date('2022-03-25T21:14:43.057Z'),
},
initialSubmitInfo: {
updatedAt: new Date('2022-03-25T21:13:20.420Z'),
},
})
const revisionsLookup = buildRevisionsLookup(submission)
if (revisionsLookup instanceof Error) {
throw revisionsLookup
}
const lookupTable = makeDocumentDateTable(revisionsLookup)
expect(lookupTable).toEqual({
fakesha: new Date('2022-03-25T21:13:20.420Z'),
fakesha1: new Date('2022-03-28T17:56:32.953Z'),
fakesha2: new Date('2022-03-25T21:13:20.420Z'),
fakesha3: new Date('2022-03-25T21:13:20.420Z'),
fakesha4: new Date('2022-03-25T21:13:20.420Z'),
fakesha5: new Date('2022-03-25T21:13:20.420Z'),
previousSubmissionDate: new Date('2022-03-25T21:14:43.057Z'),
})
})

it('should return no document dates for submission still in initial draft', () => {
const submission = mockDraftHealthPlanPackage()
const revisionsLookup = buildRevisionsLookup(submission)
if (revisionsLookup instanceof Error) {
throw revisionsLookup
}
const lookupTable = makeDocumentDateTable(revisionsLookup)

expect(lookupTable).toEqual({
previousSubmissionDate: null,
})
})

it('should use earliest document added date based that revisions submit date', () => {
const docs: Partial<UnlockedHealthPlanFormDataType> = {
documents: [
{
s3URL: 's3://bucketname/testDateDoc/testDateDoc.pdf',
name: 'Test Date Doc',
sha256: 'fakesha',
},
],
contractDocuments: [
{
s3URL: 's3://bucketname/key/replaced-contract.pdf',
name: 'replaced contract',
sha256: 'fakesha1',
},
],
rateInfos: [
{
rateDocuments: [],
supportingDocuments: [],
actuaryContacts: [],
packagesWithSharedRateCerts: [],
},
],
}
const submission = mockSubmittedHealthPlanPackageWithRevision({
currentSubmissionData: {
...docs,
},
currentSubmitInfo: {
updatedAt: new Date('2022-03-10T00:00:00.000Z'),
},
previousSubmissionData: {
...docs,
},
previousSubmitInfo: {
updatedAt: new Date('2022-02-10T00:00:00.000Z'),
},
initialSubmissionData: {
...docs,
contractDocuments: [
{
s3URL: 's3://bucketname/key/original-contract.pdf',
name: 'original contract',
sha256: 'fakesha2',
},
],
},
initialSubmitInfo: {
updatedAt: new Date('2022-01-10T00:00:00.000Z'),
},
})

const revisionsLookup = buildRevisionsLookup(submission)
if (revisionsLookup instanceof Error) {
throw revisionsLookup
}
const lookupTable = makeDocumentDateTable(revisionsLookup)

expect(lookupTable).toEqual({
fakesha: new Date('2022-01-10T00:00:00.000Z'),
fakesha1: new Date('2022-02-10T00:00:00.000Z'),
fakesha2: new Date('2022-01-10T00:00:00.00'),
previousSubmissionDate: new Date('2022-02-10T00:00:00.000Z'),
})
})
})
52 changes: 52 additions & 0 deletions packages/document-helpers/src/makeDocumentDateLookupTable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {
ExpandedRevisionsType,
RevisionsLookupType,
} from '../gqlHelpers/fetchHealthPlanPackageWrapper'
import { getAllDocuments } from './getAllDocuments'

// DocumentDateLookupTableType - { document lookup key string : date string for "date added" }
type DocumentDateLookupTableType = {
previousSubmissionDate: string | null
[key: string]: string | null
}

// getDateAdded - picks out the submit info updatedAt date for a revision
// value is undefined if document not yet submitted
const getDateAdded = (
revisionData: ExpandedRevisionsType
): string | undefined => {
return revisionData.submitInfo?.updatedAt
}
// makeDateTable - generates unique document keys and their "date added"
// used for date added column on UploadedDocumentsTable displayed in SubmissionSummary and ReviewSubmit
// documents without a submitted date are excluded from list
// logic for unique document keys comes from getDocumentKey - This can be simplified once we have doc.sha everywhere
function makeDocumentDateTable(
revisionsLookup: RevisionsLookupType
): DocumentDateLookupTableType {
const lookupTable: DocumentDateLookupTableType = {
previousSubmissionDate: null, // the last time there was a submission on this package
}
const listOfRevisionLookups = Object.keys(revisionsLookup)
listOfRevisionLookups.forEach(
(revisionId: string, index) => {
const revision = revisionsLookup[revisionId]

const submitDate = revision.submitInfo?.updatedAt
if (submitDate && (listOfRevisionLookups.length === 1 || index === 1)) { // if we have a package with only one submitted revision, use that - otherwise use whatever in is the 1 index because thats the last submitted
lookupTable['previousSubmissionDate'] = submitDate
}

const allDocuments = getAllDocuments(revision.formData)
allDocuments.forEach((doc) => {
const documentKey = doc.sha256 ? doc.sha256 : doc.s3URL
const dateAdded = getDateAdded(revision)
if (dateAdded) lookupTable[documentKey] = dateAdded
})
}
)
return lookupTable
}

export { makeDocumentDateTable }
export type { DocumentDateLookupTableType }
Loading

0 comments on commit cc9e551

Please sign in to comment.