Skip to content

Commit

Permalink
fix(package-actions): Consolidate package checks for now (#281)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Haube authored Jan 2, 2024
1 parent 37e9867 commit 21a821f
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 86 deletions.
55 changes: 2 additions & 53 deletions src/packages/shared-types/actions.ts
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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<typeof ActionAvailabilityCheck>,
checker: IPackageCheck,
user: CognitoUserAttributes,
/** Keep excess parameters to a minimum **/
...any: any[]
Expand Down
12 changes: 0 additions & 12 deletions src/packages/shared-types/planType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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),
});
1 change: 1 addition & 0 deletions src/packages/shared-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Original file line number Diff line number Diff line change
@@ -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)
: [];
};
8 changes: 2 additions & 6 deletions src/packages/shared-utils/package-actions/rules.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
71 changes: 71 additions & 0 deletions src/packages/shared-utils/packageCheck.ts
Original file line number Diff line number Diff line change
@@ -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<typeof PackageCheck>;
13 changes: 3 additions & 10 deletions src/services/ui/src/pages/detail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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 (
Expand Down

0 comments on commit 21a821f

Please sign in to comment.