All files / lib/lambda/submit submitSplitSPA.ts

92.85% Statements 26/28
72.22% Branches 13/18
100% Functions 2/2
92.85% Lines 26/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105                          1x 3x 3x 1x   2x 1x       1x               1x   1x                                       1x           1x       1x 7x 1x         6x 6x 6x   5x 5x 1x           4x 1x           3x   1x 1x 1x                      
import { response } from "libs/handler-lib";
import { APIGatewayEvent } from "aws-lambda";
import { getPackage } from "libs/api/package";
import { produceMessage } from "libs/api/kafka";
import { ItemResult } from "shared-types/opensearch/main";
import { events } from "shared-types/events";
import { getNextSplitSPAId } from "./getNextSplitSPAId";
import { z } from "zod";
 
/** @typedef {object} json
 * @property {object} body
 * @property {string} body.packageId
 */
const sendSubmitSplitSPAMessage = async (currentPackage: ItemResult) => {
  const topicName = process.env.topicName as string;
  if (!topicName) {
    throw new Error("Topic name is not defined");
  }
  const newId = await getNextSplitSPAId(currentPackage._id);
  Iif (!newId) {
    throw new Error("Error getting next Split SPA Id");
  }
 
  const currentTime = Date.now();
 
  // ID and changeMade are excluded; the rest of the object has to be spread into the new package
  const {
    id: _id,
    changeMade: _changeMade,
    origin: _origin,
    ...remainingFields
  } = currentPackage._source;
 
  await produceMessage(
    topicName,
    newId,
    JSON.stringify({
      id: newId,
      idToBeUpdated: currentPackage._id,
      ...remainingFields,
      makoChangedDate: currentTime,
      changedDate: currentTime,
      timestamp: currentTime,
      statusDate: currentTime,
      origin: "OneMAC",
      changeMade: "OneMAC Admin has added a package to OneMAC.",
      changeReason: "Per request from CMS, this package was added to OneMAC.",
      mockEvent: "new-medicaid-submission",
      isAdminChange: true,
      adminChangeType: "split-spa",
    }),
  );
 
  return response({
    statusCode: 200,
    body: { message: `New Medicaid Split SPA ${newId} has been created.` },
  });
};
 
const splitSPAEventBodySchema = z.object({
  packageId: events["new-medicaid-submission"].baseSchema.shape.id,
});
 
export const handler = async (event: APIGatewayEvent) => {
  if (!event.body) {
    return response({
      statusCode: 400,
      body: { message: "Event body required" },
    });
  }
  try {
    const body = typeof event.body === "string" ? JSON.parse(event.body) : event.body;
    const { packageId } = splitSPAEventBodySchema.parse(body);
 
    const currentPackage = await getPackage(packageId);
    if (!currentPackage || currentPackage.found == false) {
      return response({
        statusCode: 404,
        body: { message: "No record found for the given id" },
      });
    }
 
    if (currentPackage._source.authority !== "Medicaid SPA") {
      return response({
        statusCode: 400,
        body: { message: "Record must be a Medicaid SPA" },
      });
    }
 
    return sendSubmitSplitSPAMessage(currentPackage);
  } catch (err) {
    console.error("Error has occured modifying package:", err);
    Eif (err instanceof z.ZodError) {
      return response({
        statusCode: 400,
        body: { message: err.errors },
      });
    }
    return response({
      statusCode: 500,
      body: { message: err.message || "Internal Server Error" },
    });
  }
};