Enterprise-CMCS/macpro-mako

View on GitHub
lib/packages/shared-utils/package-check.ts

Summary

Maintainability
A
1 hr
Test Coverage
A
100%
import {
  Action,
  ActionType,
  Authority,
  CognitoUserAttributes,
  opensearch,
  SEATOOL_STATUS,
} from "shared-types";

const checkAuthority = (authority: Authority | string | null, validAuthorities: string[]) =>
  !authority ? false : validAuthorities.includes(authority.toLowerCase());

const checkStatus = (seatoolStatus: string, authorized: string | string[]) =>
  typeof authorized === "string"
    ? seatoolStatus === authorized
    : authorized.includes(seatoolStatus);

/** A object of booleans and methods handling common conditions
 * for business logic. */
export const PackageCheck = ({
  seatoolStatus,
  raiRequestedDate,
  raiReceivedDate,
  raiWithdrawnDate,
  raiWithdrawEnabled,
  authority,
  actionType,
  // appkParentId,
  // appkParent,
  initialIntakeNeeded,
  submissionDate,
  leadAnalystName,
  locked,
}: opensearch.main.Document) => {
  const secondClockStatuses = [
    SEATOOL_STATUS.PENDING,
    SEATOOL_STATUS.PENDING_APPROVAL,
    SEATOOL_STATUS.PENDING_CONCURRENCE,
  ];

  const planChecks = {
    isSpa: checkAuthority(authority, [Authority.MED_SPA, Authority.CHIP_SPA]),
    isWaiver: checkAuthority(authority, [Authority["1915b"], Authority["1915c"]]),
    isAppk: false,
    isAppkChild: false,
    /** Keep excess methods to a minimum with `is` **/
    authorityIs: (validAuthorities: string[]) => checkAuthority(authority, validAuthorities),
    hasCpoc: !!leadAnalystName,
  };
  const statusChecks = {
    /** Is in any of our pending statuses, sans Pending-RAI **/
    isInActivePendingStatus: checkStatus(seatoolStatus, [
      ...secondClockStatuses,
      SEATOOL_STATUS.PENDING_OFF_THE_CLOCK,
    ]),
    /** Is in a second clock status and RAI has been received **/
    isInSecondClock:
      !planChecks.authorityIs([Authority.CHIP_SPA]) &&
      checkStatus(seatoolStatus, secondClockStatuses) &&
      !!raiRequestedDate &&
      !!raiReceivedDate &&
      !raiWithdrawnDate,
    /** Is in any status except Package Withdrawn **/
    isNotWithdrawn: !checkStatus(seatoolStatus, SEATOOL_STATUS.WITHDRAWN),
    /** Added for elasticity, but common checks should always bubble up as
     * object attributes! **/
    hasStatus: (authorizedStatuses: string | string[]) =>
      checkStatus(seatoolStatus, authorizedStatuses),
    /** If submission date exists */
    hasSubmissionDate: submissionDate !== undefined,
    isLocked: locked,
  };
  const subStatusChecks = {
    /** Is in any of our pending statuses, sans Pending-RAI **/
    needsIntake: initialIntakeNeeded,
  };
  const raiChecks = {
    /** There is an RAI and it does not have a response **/
    hasRequestedRai: !!raiRequestedDate && !raiReceivedDate,
    /** There is an RAI **/
    hasLatestRai: !!raiRequestedDate,
    /** There is an RAI, it has a response, and it has not been withdrawn **/
    hasRaiResponse: !!raiRequestedDate && !!raiReceivedDate && !raiWithdrawnDate,
    /** Latest RAI has a response and/or has been withdrawn **/
    hasCompletedRai: !!raiRequestedDate && !!raiReceivedDate,
    /** Latest RAI has a response and/or has been withdrawn **/
    hasRaiWithdrawal: !!raiWithdrawnDate,
    /** RAI Withdraw has been enabled **/
    hasEnabledRaiWithdraw: raiWithdrawEnabled,
  };

  const actionTypeChecks = {
    isInitialOrRenewal: actionType === "New" || actionType === "Renew",
    isTempExtension: actionType === "Extend",
    actionIs: (action: ActionType) => actionType === action,
  };

  return {
    ...planChecks,
    ...statusChecks,
    ...subStatusChecks,
    ...raiChecks,
    ...actionTypeChecks,
  };
};

export type IPackageCheck = ReturnType<typeof PackageCheck>;

export type ActionRule = {
  action: Action;
  check: (
    checker: IPackageCheck,
    user: CognitoUserAttributes,
    /** Keep excess parameters to a minimum **/
    ...any: any[]
  ) => boolean;
};