Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"max-len":["error", {
"code": 150,
"ignoreComments": true
}]
}],
"@typescript-eslint/no-unsafe-enum-comparison": "off"
}
}
6,909 changes: 2,156 additions & 4,753 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"polly-js": "^1.8.3"
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.550.0",
"@aws-sdk/client-dynamodb": "^3.359.0",
"@aws-sdk/client-lambda": "^3.362.0",
"@aws-sdk/client-sns": "^3.485.0",
Expand All @@ -54,14 +55,14 @@
"@aws-sdk/smithy-client": "^3.341.0",
"@aws-sdk/types": "^3.341.0",
"@aws-sdk/util-dynamodb": "^3.362.0",
"@dvsa/eslint-config-ts": "^3.0.0",
"@dvsa/eslint-config-ts": "^3.0.1",
"@types/aws-lambda": "^8.10.114",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.14.195",
"@types/node": "^16.18.34",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.57.1",
"@typescript-eslint/parser": "^5.57.1",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"ajv": "^8.12.0",
"archiver": "^5.3.1",
"aws-sam-webpack-plugin": "^0.13.0",
Expand Down
27 changes: 27 additions & 0 deletions src/handler/mot-update-vrm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { SQSEvent, SQSRecord } from 'aws-lambda';
import { SNSMessageBody } from '../models/updateVrm';
import { processRecord } from '../processors/processCherishedTransfer';
import { publish } from '../services/sns';
import logger from '../util/logger';

export const handler = async (event: SQSEvent): Promise<void> => {
logger.info('mot-update-vrm lambda triggered');

try {
const recordsToSend: SNSMessageBody[] = [];
const processRecordWrapper = async (record: SQSRecord): Promise<void> => {
const result = await processRecord(record);
recordsToSend.push(...result);
};

await Promise.all(event.Records.map(processRecordWrapper));
if (recordsToSend.length) {
await publish(JSON.stringify(recordsToSend), process.env.VRM_TRANSFERRED_ARN ?? '');
}

logger.info('All records processed in SQS event');
} catch (error) {
logger.error(`An error occurred during processing mot update vrm: ${(error as Error).message}`);
throw error;
}
};
11 changes: 6 additions & 5 deletions src/handler/updateVrm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import {
updateVehicle,
} from '../services/database';
import { donorVehicle } from '../services/donorVehicle';
import { publish } from '../services/sns';
import { getUserDetails } from '../services/user';
import { formatErrorMessage } from '../util/errorMessage';
import { addHttpHeaders } from '../util/httpHeaders';
import logger from '../util/logger';
import { validateUpdateVrmRequest, validateVrm, validateVrmExists } from '../validators/update';
import { formatErrorMessage } from '../util/errorMessage';
import { publish } from '../services/sns';

export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
try {
Expand Down Expand Up @@ -48,9 +48,10 @@ export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayPr

if (!thirdMark?.length) {
const newVrmExistsOnActiveRecord = await validateVrmExists(newVrm);
if (newVrmExistsOnActiveRecord) {
return newVrmExistsOnActiveRecord;
}
if (newVrmExistsOnActiveRecord) return newVrmExistsOnActiveRecord;
} else {
const thirdMarkVrmExistsOnActiveRecord = await validateVrmExists(thirdMark);
if (thirdMarkVrmExistsOnActiveRecord) return thirdMarkVrmExistsOnActiveRecord;
}

const [donorVehicleRecord, error] = await donorVehicle(newVrm, thirdMark) as [TechRecordType<'get'>, APIGatewayProxyResult];
Expand Down
4 changes: 4 additions & 0 deletions src/models/motCherishedTransfer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface MotCherishedTransfer {
vin: string;
vrm: string;
}
61 changes: 60 additions & 1 deletion src/processors/processCherishedTransfer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { TechRecordType } from '@dvsa/cvs-type-definitions/types/v3/tech-record/tech-record-verb';
import { SQSRecord } from 'aws-lambda';
import { setCreatedAuditDetails, setLastUpdatedAuditDetails } from '../services/audit';
import { UserDetails } from '../services/user';
import { StatusCode } from '../util/enum';
import { MotCherishedTransfer } from '../models/motCherishedTransfer';
import { getBySystemNumberAndCreatedTimestamp, searchByCriteria, updateVehicle } from '../services/database';
import { SearchCriteria } from '../models/search';
import logger from '../util/logger';

const SYSTEM_USER = 'CVS Automated Cherished Transfer';

export const processCherishedTransfer = (
userDetails: UserDetails,
Expand Down Expand Up @@ -52,12 +59,16 @@ export const processCherishedTransfer = (
StatusCode.ARCHIVED,
);

const newStatusCode = recipientRecord.techRecord_statusCode === StatusCode.CURRENT
? StatusCode.CURRENT
: recipientRecord.techRecord_statusCode as StatusCode;

const updatedRecipientNewRecord = setCreatedAuditDetails(
newRecord,
userDetails.username,
userDetails.msOid,
new Date().toISOString(),
recipientRecord.techRecord_statusCode as StatusCode,
newStatusCode,
);
if (updatedRecipientNewRecord.techRecord_vehicleType !== 'trl') {
updatedRecipientNewRecord.primaryVrm = newVrm.toUpperCase();
Expand All @@ -78,3 +89,51 @@ const formatSecondaryVrms = (record:TechRecordType<'get'>): Array<string> | unde
}
return undefined;
};

export const processRecord = async (cherishedTransfer: SQSRecord) => {
const parsedRecord = JSON.parse(cherishedTransfer.body) as MotCherishedTransfer;
const allRecords = await searchByCriteria(SearchCriteria.VIN, parsedRecord.vin);

if (!allRecords.length) {
logger.info(`No record found for VIN: ${parsedRecord.vin}`);
return [];
}
const allCurrentRecords = allRecords.filter(({ techRecord_statusCode }) => techRecord_statusCode === StatusCode.CURRENT);

if (!allCurrentRecords.length) {
logger.info(`No current record found for VIN: ${parsedRecord.vin}`);
return [];
}

if (allCurrentRecords.length > 1) {
logger.info(`Duplicate current records found for VIN ${parsedRecord.vin}`);
return [];
}
const currentRecord = allCurrentRecords[0];
if (currentRecord.primaryVrm === parsedRecord.vrm) {
logger.info(`No update needed for VRM ${parsedRecord.vrm} and VIN ${parsedRecord.vin}`);
return [];
}

const completeTechRecord: TechRecordType<'get'> = await getBySystemNumberAndCreatedTimestamp(
currentRecord.systemNumber,
currentRecord.createdTimestamp,
);

const {
recordsToArchive,
recordsToUpdate,
} = processCherishedTransfer(
{
msOid: SYSTEM_USER,
username: SYSTEM_USER,
email: '',
},
parsedRecord.vrm,
completeTechRecord,
);
await updateVehicle(recordsToArchive, recordsToUpdate);
logger.info(`Updated systemNumber ${currentRecord.systemNumber} with VRM ${parsedRecord.vrm}`);

return recordsToUpdate;
};
7 changes: 5 additions & 2 deletions src/services/sqs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { SQSClient, SendMessageCommand } from '@aws-sdk/client-sqs';
import {
SQSClient, SendMessageCommand,
} from '@aws-sdk/client-sqs';
import { SQSRequestBody } from '../models/sqsPayload';
import logger from '../util/logger';

Expand All @@ -14,7 +16,8 @@ export const addToSqs = async (messageBody: SQSRequestBody, queueUrl: string) =>
};

try {
await sqsClient.send(new SendMessageCommand(params));
const command = new SendMessageCommand(params);
await sqsClient.send(command);
return undefined;
} catch (err: unknown) {
logger.error(err);
Expand Down
8 changes: 8 additions & 0 deletions template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ Resources:
Path: !GetAtt LocalQueue.Arn
BatchSize: 10

MotUpdateVrm:
Type: 'AWS::Serverless::Function'
Properties:
CodeUri: src/handler/
Handler: mot-update-vrm.handler
Runtime: nodejs18.x
Timeout: 20

RemoveInvalidPrimaryVrms:
Type: 'AWS::Serverless::Function'
Properties:
Expand Down
58 changes: 58 additions & 0 deletions tests/resources/mot-vrm-update-event-multiple.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"Records": [
{
"attributes": {
"ApproximateFirstReceiveTimestamp": "1691599233730",
"ApproximateReceiveCount": "1",
"SenderId": "AROAQC27VTVQFNB6YB3PQ:75df3f853a5436f0871d40b179d4ba5e",
"SentTimestamp": "1691599233712"
},
"awsRegion": "eu-west-1",
"eventSource": "aws:sqs",
"body": "",
"eventSourceARN": "arn:aws:sqs:eu-west-1:006106226016:sync-test-result-info-cb2-8663-queue",
"level": "info",
"md5OfBody": "94860332cba78c4d0d888c6556e6f57b",
"message": "payload recieved from queue:",
"messageAttributes": {},
"messageId": "5695c906-9796-4a79-839c-c887cfd3ea5b",
"receiptHandle": "AQEBmrbVJpOCy7CxMt94wxfmXe9aJQ3spunsOq5XfsRRgFxYFmG1e0WPsH9EJ863z5+7wNjlC+ZExU0cWrcUeXlgvPrgTDchhr9etZXmC8DeeHe4WU7WI59tZwKgA9BBcnAstwxjVChVSAi+FBaL7rZwd6X3Kn8+bA46UJjF8wmrDit9pXqnRUtSSL9fUn/7eEsO6VQ/2UKbhRXIwmF3sBRsiuF5RXuXKukOtrWlK5fepAQJVngHc2NV8tcxnHDyiLBc+k/rpRuF3NR4OhT56bJW33LPWvl6Sl4C92NLzS3L5lnvMLUvQFoEE6aP3/IYZD29HxgmQON0mzsvnnvuXOWNa9ZBmBKl+01Z7Xd3W4w9jfSucPRf4EjsCRoDXUkpb5WlJ0xGnnyK3ouoCjLc943OabFeqT1ELyxmhJnWo08Vtaw="
},
{
"attributes": {
"ApproximateFirstReceiveTimestamp": "1691599233730",
"ApproximateReceiveCount": "1",
"SenderId": "AROAQC27VTVQFNB6YB3PQ:75df3f853a5436f0871d40b179d4ba5e",
"SentTimestamp": "1691599233712"
},
"awsRegion": "eu-west-1",
"eventSource": "aws:sqs",
"body": "",
"eventSourceARN": "arn:aws:sqs:eu-west-1:006106226016:sync-test-result-info-cb2-8663-queue",
"level": "info",
"md5OfBody": "94860332cba78c4d0d888c6556e6f57b",
"message": "payload recieved from queue:",
"messageAttributes": {},
"messageId": "5695c906-9796-4a79-839c-c887cfd3ea5b",
"receiptHandle": "AQEBmrbVJpOCy7CxMt94wxfmXe9aJQ3spunsOq5XfsRRgFxYFmG1e0WPsH9EJ863z5+7wNjlC+ZExU0cWrcUeXlgvPrgTDchhr9etZXmC8DeeHe4WU7WI59tZwKgA9BBcnAstwxjVChVSAi+FBaL7rZwd6X3Kn8+bA46UJjF8wmrDit9pXqnRUtSSL9fUn/7eEsO6VQ/2UKbhRXIwmF3sBRsiuF5RXuXKukOtrWlK5fepAQJVngHc2NV8tcxnHDyiLBc+k/rpRuF3NR4OhT56bJW33LPWvl6Sl4C92NLzS3L5lnvMLUvQFoEE6aP3/IYZD29HxgmQON0mzsvnnvuXOWNa9ZBmBKl+01Z7Xd3W4w9jfSucPRf4EjsCRoDXUkpb5WlJ0xGnnyK3ouoCjLc943OabFeqT1ELyxmhJnWo08Vtaw="
},
{
"attributes": {
"ApproximateFirstReceiveTimestamp": "1691599233730",
"ApproximateReceiveCount": "1",
"SenderId": "AROAQC27VTVQFNB6YB3PQ:75df3f853a5436f0871d40b179d4ba5e",
"SentTimestamp": "1691599233712"
},
"awsRegion": "eu-west-1",
"eventSource": "aws:sqs",
"body": "",
"eventSourceARN": "arn:aws:sqs:eu-west-1:006106226016:sync-test-result-info-cb2-8663-queue",
"level": "info",
"md5OfBody": "94860332cba78c4d0d888c6556e6f57b",
"message": "payload recieved from queue:",
"messageAttributes": {},
"messageId": "5695c906-9796-4a79-839c-c887cfd3ea5b",
"receiptHandle": "AQEBmrbVJpOCy7CxMt94wxfmXe9aJQ3spunsOq5XfsRRgFxYFmG1e0WPsH9EJ863z5+7wNjlC+ZExU0cWrcUeXlgvPrgTDchhr9etZXmC8DeeHe4WU7WI59tZwKgA9BBcnAstwxjVChVSAi+FBaL7rZwd6X3Kn8+bA46UJjF8wmrDit9pXqnRUtSSL9fUn/7eEsO6VQ/2UKbhRXIwmF3sBRsiuF5RXuXKukOtrWlK5fepAQJVngHc2NV8tcxnHDyiLBc+k/rpRuF3NR4OhT56bJW33LPWvl6Sl4C92NLzS3L5lnvMLUvQFoEE6aP3/IYZD29HxgmQON0mzsvnnvuXOWNa9ZBmBKl+01Z7Xd3W4w9jfSucPRf4EjsCRoDXUkpb5WlJ0xGnnyK3ouoCjLc943OabFeqT1ELyxmhJnWo08Vtaw="
}
]
}
22 changes: 22 additions & 0 deletions tests/resources/mot-vrm-update-event.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"Records": [
{
"attributes": {
"ApproximateFirstReceiveTimestamp": "1691599233730",
"ApproximateReceiveCount": "1",
"SenderId": "AROAQC27VTVQFNB6YB3PQ:75df3f853a5436f0871d40b179d4ba5e",
"SentTimestamp": "1691599233712"
},
"awsRegion": "eu-west-1",
"eventSource": "aws:sqs",
"body": "",
"eventSourceARN": "arn:aws:sqs:eu-west-1:006106226016:sync-test-result-info-cb2-8663-queue",
"level": "info",
"md5OfBody": "94860332cba78c4d0d888c6556e6f57b",
"message": "payload recieved from queue:",
"messageAttributes": {},
"messageId": "5695c906-9796-4a79-839c-c887cfd3ea5b",
"receiptHandle": "AQEBmrbVJpOCy7CxMt94wxfmXe9aJQ3spunsOq5XfsRRgFxYFmG1e0WPsH9EJ863z5+7wNjlC+ZExU0cWrcUeXlgvPrgTDchhr9etZXmC8DeeHe4WU7WI59tZwKgA9BBcnAstwxjVChVSAi+FBaL7rZwd6X3Kn8+bA46UJjF8wmrDit9pXqnRUtSSL9fUn/7eEsO6VQ/2UKbhRXIwmF3sBRsiuF5RXuXKukOtrWlK5fepAQJVngHc2NV8tcxnHDyiLBc+k/rpRuF3NR4OhT56bJW33LPWvl6Sl4C92NLzS3L5lnvMLUvQFoEE6aP3/IYZD29HxgmQON0mzsvnnvuXOWNa9ZBmBKl+01Z7Xd3W4w9jfSucPRf4EjsCRoDXUkpb5WlJ0xGnnyK3ouoCjLc943OabFeqT1ELyxmhJnWo08Vtaw="
}
]
}
Loading