From 21a821fb283350a50237e74fb44c740acff8e748 Mon Sep 17 00:00:00 2001 From: Kevin Haube Date: Tue, 2 Jan 2024 10:42:11 -0500 Subject: [PATCH] fix(package-actions): Consolidate package checks for now (#281) --- src/packages/shared-types/actions.ts | 55 +------------- src/packages/shared-types/planType.ts | 12 ---- src/packages/shared-utils/index.ts | 1 + .../package-actions/getAvailableActions.ts | 9 ++- .../shared-utils/package-actions/rules.ts | 8 +-- src/packages/shared-utils/packageCheck.ts | 71 +++++++++++++++++++ src/services/ui/src/pages/detail/index.tsx | 13 +--- 7 files changed, 83 insertions(+), 86 deletions(-) create mode 100644 src/packages/shared-utils/packageCheck.ts diff --git a/src/packages/shared-types/actions.ts b/src/packages/shared-types/actions.ts index 6b51464c8f..c07c2e2a31 100644 --- a/src/packages/shared-types/actions.ts +++ b/src/packages/shared-types/actions.ts @@ -1,8 +1,5 @@ -import { OsMainSourceItem } from "./opensearch"; import { CognitoUserAttributes } from "./user"; -import { getLatestRai } from "shared-utils"; -import { SEATOOL_STATUS } from "./statusHelper"; -import { PlanType, PlanTypeCheck } from "./planType"; +import { IPackageCheck } from "shared-utils"; export enum Action { ISSUE_RAI = "issue-rai", @@ -13,58 +10,10 @@ export enum Action { WITHDRAW_PACKAGE = "withdraw-package", } -const secondClockStatuses = [ - SEATOOL_STATUS.PENDING, - SEATOOL_STATUS.PENDING_APPROVAL, - SEATOOL_STATUS.PENDING_CONCURRENCE, -]; - -const checkStatus = (seatoolStatus: string, authorized: string | string[]) => - typeof authorized === "string" - ? seatoolStatus === authorized - : authorized.includes(seatoolStatus); - -export const ActionAvailabilityCheck = ({ - seatoolStatus, - rais, - raiWithdrawEnabled, - planType, -}: OsMainSourceItem) => { - const latestRai = getLatestRai(rais); - return { - /** 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: - !PlanTypeCheck(planType).is([PlanType.CHIP_SPA]) && - checkStatus(seatoolStatus, secondClockStatuses) && - latestRai?.status === "received", - /** Latest RAI is requested and status is Pending-RAI **/ - hasRequestedRai: - latestRai?.status === "requested" && - checkStatus(seatoolStatus, SEATOOL_STATUS.PENDING_RAI), - /** Latest RAI is not null **/ - hasLatestRai: latestRai !== null, - /** Latest RAI has been responded to **/ - hasRaiResponse: latestRai?.status === "received", - /** RAI Withdraw has been enabled **/ - hasEnabledRaiWithdraw: raiWithdrawEnabled, - /** 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), - }; -}; - export type ActionRule = { action: Action; check: ( - checker: ReturnType, + checker: IPackageCheck, user: CognitoUserAttributes, /** Keep excess parameters to a minimum **/ ...any: any[] diff --git a/src/packages/shared-types/planType.ts b/src/packages/shared-types/planType.ts index 9996460839..9efe9e707b 100644 --- a/src/packages/shared-types/planType.ts +++ b/src/packages/shared-types/planType.ts @@ -2,15 +2,3 @@ export enum PlanType { MED_SPA = "medicaid spa", CHIP_SPA = "chip spa", } - -const checkPlan = (planType: PlanType | null, validPlanTypes: PlanType[]) => - !planType - ? false - : validPlanTypes.includes(planType.toLowerCase() as PlanType); - -export const PlanTypeCheck = (planType: PlanType | null) => ({ - isSpa: checkPlan(planType, [PlanType.MED_SPA, PlanType.CHIP_SPA]), - isWaiver: checkPlan(planType, []), - /** Keep excess methods to a minimum with `is` **/ - is: (validPlanTypes: PlanType[]) => checkPlan(planType, validPlanTypes), -}); diff --git a/src/packages/shared-utils/index.ts b/src/packages/shared-utils/index.ts index 79be861967..fcc7b63a22 100644 --- a/src/packages/shared-utils/index.ts +++ b/src/packages/shared-utils/index.ts @@ -4,3 +4,4 @@ export { isStateUser } from "./is-state-user"; export * from "./rai-helper"; export * from "./regex"; export * from "./package-actions/getAvailableActions"; +export * from "./packageCheck"; diff --git a/src/packages/shared-utils/package-actions/getAvailableActions.ts b/src/packages/shared-utils/package-actions/getAvailableActions.ts index b5f3ee96de..20f433b592 100644 --- a/src/packages/shared-utils/package-actions/getAvailableActions.ts +++ b/src/packages/shared-utils/package-actions/getAvailableActions.ts @@ -1,18 +1,17 @@ import { - ActionAvailabilityCheck, CognitoUserAttributes, OsMainSourceItem, - PlanTypeCheck, PlanType, } from "../../shared-types"; import rules from "./rules"; +import { PackageCheck } from "../packageCheck"; export const getAvailableActions = ( user: CognitoUserAttributes, result: OsMainSourceItem ) => { - const actionChecker = ActionAvailabilityCheck(result); - return PlanTypeCheck(result.planType).is([PlanType.MED_SPA]) - ? rules.filter((r) => r.check(actionChecker, user)).map((r) => r.action) + const checks = PackageCheck(result); + return checks.planTypeIs([PlanType.MED_SPA]) + ? rules.filter((r) => r.check(checks, user)).map((r) => r.action) : []; }; diff --git a/src/packages/shared-utils/package-actions/rules.ts b/src/packages/shared-utils/package-actions/rules.ts index 04aa200579..95631ec472 100644 --- a/src/packages/shared-utils/package-actions/rules.ts +++ b/src/packages/shared-utils/package-actions/rules.ts @@ -1,10 +1,6 @@ -import { - Action, - ActionAvailabilityCheck, - ActionRule, - SEATOOL_STATUS, -} from "../../shared-types"; +import { Action, ActionRule, SEATOOL_STATUS } from "../../shared-types"; import { isCmsUser, isStateUser } from "../user-helper"; +import { PackageCheck } from "../packageCheck"; const arIssueRai: ActionRule = { action: Action.ISSUE_RAI, diff --git a/src/packages/shared-utils/packageCheck.ts b/src/packages/shared-utils/packageCheck.ts new file mode 100644 index 0000000000..9afcbf44c7 --- /dev/null +++ b/src/packages/shared-utils/packageCheck.ts @@ -0,0 +1,71 @@ +import { OsMainSourceItem, PlanType, SEATOOL_STATUS } from "../shared-types"; +import { getLatestRai } from "./rai-helper"; + +const secondClockStatuses = [ + SEATOOL_STATUS.PENDING, + SEATOOL_STATUS.PENDING_APPROVAL, + SEATOOL_STATUS.PENDING_CONCURRENCE, +]; + +const checkPlan = (planType: PlanType | null, validPlanTypes: PlanType[]) => + !planType + ? false + : validPlanTypes.includes(planType.toLowerCase() as PlanType); + +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, + rais, + raiWithdrawEnabled, + planType, +}: OsMainSourceItem) => { + const latestRai = getLatestRai(rais); + const planChecks = { + isSpa: checkPlan(planType, [PlanType.MED_SPA, PlanType.CHIP_SPA]), + isWaiver: checkPlan(planType, []), + /** Keep excess methods to a minimum with `is` **/ + planTypeIs: (validPlanTypes: PlanType[]) => + checkPlan(planType, validPlanTypes), + }; + 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.planTypeIs([PlanType.CHIP_SPA]) && + checkStatus(seatoolStatus, secondClockStatuses) && + latestRai?.status === "received", + /** 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), + }; + const raiChecks = { + /** Latest RAI is requested and status is Pending-RAI **/ + hasRequestedRai: latestRai?.status === "requested", + /** Latest RAI is not null **/ + hasLatestRai: latestRai !== null, + /** Latest RAI has been responded to **/ + hasRaiResponse: latestRai?.status === "received", + /** RAI Withdraw has been enabled **/ + hasEnabledRaiWithdraw: raiWithdrawEnabled, + }; + return { + ...planChecks, + ...statusChecks, + ...raiChecks, + }; +}; + +export type IPackageCheck = ReturnType; diff --git a/src/services/ui/src/pages/detail/index.tsx b/src/services/ui/src/pages/detail/index.tsx index 7baa4d605f..3ef2578300 100644 --- a/src/services/ui/src/pages/detail/index.tsx +++ b/src/services/ui/src/pages/detail/index.tsx @@ -11,15 +11,8 @@ import { RaiList, } from "@/components"; import { useGetUser } from "@/api/useGetUser"; -import { - Action, - ActionAvailabilityCheck, - ItemResult, - OsMainSourceItem, - PlanType, - PlanTypeCheck, - UserRoles, -} from "shared-types"; +import { Action, ItemResult, OsMainSourceItem, UserRoles } from "shared-types"; +import { PackageCheck } from "shared-utils"; import { useQuery } from "@/hooks"; import { useGetItem } from "@/api"; import { BreadCrumbs } from "@/components/BreadCrumb"; @@ -48,7 +41,7 @@ const DetailCardWrapper = ({ ); const StatusCard = (data: OsMainSourceItem) => { const transformedStatuses = getStatus(data.seatoolStatus); - const checker = ActionAvailabilityCheck(data); + const checker = PackageCheck(data); const { data: user } = useGetUser(); return (