feature/IO-2282-VSSTA-Integration: - Finish Integration

This commit is contained in:
Dave Richer
2025-04-15 12:40:33 -04:00
parent 35a7222f5e
commit f09cb7b247

View File

@@ -5,25 +5,34 @@ const { GET_JOB_BY_RO_NUMBER_AND_SHOP_ID, INSERT_NEW_DOCUMENT } = require("../..
const { InstanceRegion } = require("../../utils/instanceMgr");
const client = require("../../graphql-client/graphql-client").client;
const S3_BUCKET = process.env.IMGPROXY_DESTINATION_BUCKET;
const S3_BUCKET = process.env?.IMGPROXY_DESTINATION_BUCKET;
/**
* @description VSSTA integration route
* @type {string[]}
*/
const requiredParams = [
"shop_id",
"ro_nbr",
"pdf_download_link",
"company_api_key",
"scan_type",
"scan_time",
"technician",
"year",
"make",
"model"
];
const vsstaIntegrationRoute = async (req, res) => {
const { logger } = req;
try {
const requiredParams = [
"shop_id",
"ro_nbr",
"pdf_download_link",
"company_api_key",
"scan_type",
"scan_time",
"technician",
"year",
"make",
"model"
];
if (!S3_BUCKET) {
logger.log("vssta-integration-missing-bucket", "error", "api", "vssta");
return res.status(500).json({ error: "Improper configuration" });
}
try {
const missingParams = requiredParams.filter((param) => !req.body[param]);
if (missingParams.length > 0) {
@@ -54,25 +63,24 @@ const vsstaIntegrationRoute = async (req, res) => {
const job = jobResult.jobs[0];
logger.logger.info(`Found job with ID ${job.id} for RO number ${ro_nbr}`);
// 2. Download the PDF from the provided link
logger.logger.info(`Downloading PDF from ${pdf_download_link}`);
// 2. Download the base64-encoded PDF string from the provided link
const pdfResponse = await axios.get(pdf_download_link, {
responseType: "arraybuffer"
// headers: {
// "auth:token": company_api_key
// }
responseType: "text", // Expect base64 string
headers: {
"auth-token": company_api_key
}
});
// 3. Generate key for S3
// 3. Decode the base64 string to a PDF buffer
const base64String = pdfResponse.data.replace(/^data:application\/pdf;base64,/, "");
const pdfBuffer = Buffer.from(base64String, "base64");
// 4. Generate key for S3
const timestamp = Date.now();
const fileName = `VSSTA_${scan_type}_Scan_${timestamp}.pdf`;
const s3Key = `${job.shopid}/${job.id}/${fileName.replace(/[^A-Z0-9]+/gi, "_")}-${timestamp}.pdf`;
// 4. Generate presigned URL for S3 upload
logger.logger.info(`Generating presigned URL for S3 key ${s3Key}`);
// 5. Generate presigned URL for S3 upload
const s3Client = new S3Client({ region: InstanceRegion() });
const putCommand = new PutObjectCommand({
@@ -84,45 +92,42 @@ const vsstaIntegrationRoute = async (req, res) => {
const presignedUrl = await getSignedUrl(s3Client, putCommand, { expiresIn: 360 });
// 5. Upload file to S3
logger.logger.info(`Uploading PDF to S3 with key ${s3Key}`);
await axios.put(presignedUrl, pdfResponse.data, {
// 6. Upload the decoded PDF to S3
await axios.put(presignedUrl, pdfBuffer, {
headers: { "Content-Type": "application/pdf" }
});
// 6. Create document record in database
// 7. Create document record in database
const documentMeta = {
jobid: job.id, // Matches jobid (uuid, nullable)
uploaded_by: "VSSTA Integration", // Matches uploaded_by (text)
name: fileName, // Matches name (text, nullable)
key: s3Key, // Matches key (text, default: '0'::text)
// type: determineFileType("application/pdf"), // Matches type (text, nullable), using determineFileType
// Ask Patrick why determineFileType just returns image...
type: "application/pdf", // Matches type (text, nullable),
extension: "pdf", // Matches extension (text, nullable)
bodyshopid: job.shopid, // Matches bodyshopid (uuid, nullable)
size: pdfResponse.data.length, // Matches size (integer, default: 0)
takenat: scan_time // Matches takenat (timestamp with time zone, nullable)
jobid: job.id,
uploaded_by: "VSSTA Integration",
name: fileName,
key: s3Key,
type: "application/pdf",
extension: "pdf",
bodyshopid: job.shopid,
size: pdfBuffer.length,
takenat: scan_time
};
const documentInsert = await client.request(INSERT_NEW_DOCUMENT, {
docInput: [documentMeta]
});
if (documentInsert.insert_documents?.returning?.length > 0) {
logger.logger.info(`Document created with ID ${documentInsert.insert_documents.returning[0].id}`);
return res.status(200).json({
message: "VSSTA integration successful",
documentId: documentInsert.insert_documents.returning[0].id
});
} else {
// Reversed flow: check for error case
if (!documentInsert.insert_documents?.returning?.length) {
logger.log(`vssta-integration-failed-to-create-document-record`, "error", "api", "vssta", {
params: missingParams
});
return res.status(500).json({ error: "Failed to create document record" });
}
// Success case
logger.logger.info(`Document created with ID ${documentInsert.insert_documents.returning[0].id}`);
return res.status(200).json({
message: "VSSTA integration successful",
documentId: documentInsert.insert_documents.returning[0].id
});
} catch (error) {
logger.log(`vssta-integration-general`, "error", "api", "vssta", {
error: error?.message,