Skip to content

Commit

Permalink
backend query insertion cleanup (#101)
Browse files Browse the repository at this point in the history
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
fzhao99 and pre-commit-ci[bot] authored Oct 31, 2024
1 parent e2c9aa6 commit 7c56baf
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 47 deletions.
2 changes: 1 addition & 1 deletion query-connector/src/app/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ export interface ValueSet {

export const DEFAULT_ERSD_VERSION = "3";

type DibbsConceptType = "labs" | "medications" | "conditions";
export type DibbsConceptType = "labs" | "medications" | "conditions";
export type ErsdConceptType =
| "ostc"
| "lotc"
Expand Down
6 changes: 3 additions & 3 deletions query-connector/src/app/database-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from "./constants";
import { encode } from "base-64";
import {
UserQueryInput,
QueryInput,
generateQueryInsertionSql,
generateQueryToValueSetInsertionSql,
} from "./query-building";
Expand Down Expand Up @@ -408,10 +408,10 @@ function logRejectedPromiseReasons<T>(

/**
* Function that orchestrates query insertion for the query building flow
* @param input - Values of the shape UserQueryInput needed for query insertion
* @param input - Values of the shape QueryInput needed for query insertion
* @returns - Success or failure status, with associated error message for frontend
*/
export async function insertQuery(input: UserQueryInput) {
export async function insertQuery(input: QueryInput) {
const { sql, values } = generateQueryInsertionSql(input);
const insertUserQueryPromise = dbClient.query(sql, values);
const errorArray = [];
Expand Down
13 changes: 6 additions & 7 deletions query-connector/src/app/query-building.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { UUID, randomUUID } from "crypto";
import { Concept, ValueSet } from "./constants";
import { ValueSet } from "./constants";

// TODO: Potentially merge this / infer this from the type created via the
// database creation workstream
export type UserQueryInput = {
export type QueryInput = {
queryName: string;
author: string;
valueSets: ValueSet[];
concepts?: Concept[];
timeWindowUnit?: string; // TODO: should probably type this more strongly
timeWindowNumber?: Number;
};
Expand All @@ -19,10 +18,10 @@ const DEFAULT_TIME_WINDOW = {

/**
* Function that generates SQL needed for the query building flow
* @param input - Values of the shape UserQueryInput needed for query insertion
* @param input - Values of the shape QueryInput needed for query insertion
* @returns [sql, values] needed for query building insertion
*/
export function generateQueryInsertionSql(input: UserQueryInput) {
export function generateQueryInsertionSql(input: QueryInput) {
const id = randomUUID();
const dateCreated = new Date().toISOString();
const dateLastModified = new Date().toISOString();
Expand All @@ -46,13 +45,13 @@ export function generateQueryInsertionSql(input: UserQueryInput) {
/**
* Function that generates SQL for the query_to_valueset join table needed for
* query building.
* @param input - Values of the shape UserQueryInput needed for query insertion
* @param input - Values of the shape QueryInput needed for query insertion
* @param queryId - ID of the query that's already been created to associate with
* a given valueset
* @returns An array of {sql, values} to be inserted by the join insertion flow
*/
export function generateQueryToValueSetInsertionSql(
input: UserQueryInput,
input: QueryInput,
queryId: UUID,
) {
const joinInsertionSqlArray = input.valueSets.map((v) => {
Expand Down
2 changes: 1 addition & 1 deletion query-connector/src/app/query/SelectQuery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const SelectQuery: React.FC<SelectQueryProps> = ({
<CustomizeQuery
useCaseQueryResponse={resultsQueryResponse}
queryType={selectedQuery}
queryValuesets={queryValueSets}
queryValueSets={queryValueSets}
setQueryValuesets={setQueryValueSets}
goBack={() => setShowCustomizeQuery(false)}
></CustomizeQuery>
Expand Down
69 changes: 34 additions & 35 deletions query-connector/src/app/query/components/CustomizeQuery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import React, { useState, useEffect } from "react";
import { Button } from "@trussworks/react-uswds";
import {
DibbsConceptType,
DibbsValueSetType,
USE_CASES,
ValueSet,
Expand All @@ -16,14 +17,18 @@ import CustomizeQueryAccordionHeader from "./customizeQuery/CustomizeQueryAccord
import CustomizeQueryAccordionBody from "./customizeQuery/CustomizeQueryAccordionBody";
import Accordion from "../designSystem/Accordion";
import CustomizeQueryNav from "./customizeQuery/CustomizeQueryNav";
import { mapValueSetsToValueSetTypes } from "./customizeQuery/customizeQueryUtils";
import {
GroupedValueSet,
mapValueSetsToValueSetTypes,
} from "./customizeQuery/customizeQueryUtils";
import Backlink from "./backLink/Backlink";
import { RETURN_LABEL } from "../stepIndicator/StepIndicator";
import { countDibbsConceptTypeToVsMapItems } from "./utils";

interface CustomizeQueryProps {
useCaseQueryResponse: UseCaseQueryResponse;
queryType: USE_CASES;
queryValuesets: ValueSet[];
queryValueSets: ValueSet[];
setQueryValuesets: (queryVS: ValueSet[]) => void;
goBack: () => void;
}
Expand All @@ -33,54 +38,48 @@ interface CustomizeQueryProps {
* @param root0 - The properties object.
* @param root0.useCaseQueryResponse - The response from the query service.
* @param root0.queryType - The type of the query.
* @param root0.queryValuesets - The pre-fetched value sets from the DB.
* @param root0.queryValueSets - The pre-fetched value sets from the DB.
* @param root0.setQueryValuesets - Function to update tracked custom query state.
* @param root0.goBack - Back button to go from "customize-queries" to "search" component.
* @returns The CustomizeQuery component.
*/
const CustomizeQuery: React.FC<CustomizeQueryProps> = ({
useCaseQueryResponse,
queryType,
queryValuesets,
queryValueSets: queryValueSets,
setQueryValuesets,
goBack,
}) => {
const [activeTab, setActiveTab] = useState<DibbsValueSetType>("labs");
const { labs, conditions, medications } =
mapValueSetsToValueSetTypes(queryValuesets);
const [valueSetOptions, setValueSetOptions] = useState({
labs: labs,
conditions: conditions,
medications: medications,

const [valueSetOptions, setValueSetOptions] = useState<{
[dibbsConceptType in DibbsConceptType]: {
[vsNameAuthorSystem: string]: GroupedValueSet;
};
}>({
labs: {},
conditions: {},
medications: {},
});

useEffect(() => {
const { labs, conditions, medications } =
mapValueSetsToValueSetTypes(queryValueSets);

setValueSetOptions({
labs: labs,
conditions: conditions,
medications: medications,
});
}, [queryValueSets]);

// Compute counts of each tab-type
const countLabs = Object.values(valueSetOptions.labs).reduce(
(runningSum, gvs) => {
gvs.items.forEach((vs) => {
runningSum += vs.concepts.length;
});
return runningSum;
},
0,
);
const countConditions = Object.values(valueSetOptions.conditions).reduce(
(runningSum, gvs) => {
gvs.items.forEach((vs) => {
runningSum += vs.concepts.length;
});
return runningSum;
},
0,
const countLabs = countDibbsConceptTypeToVsMapItems(valueSetOptions.labs);
const countConditions = countDibbsConceptTypeToVsMapItems(
valueSetOptions.conditions,
);
const countMedications = Object.values(valueSetOptions.medications).reduce(
(runningSum, gvs) => {
gvs.items.forEach((vs) => {
runningSum += vs.concepts.length;
});
return runningSum;
},
0,
const countMedications = countDibbsConceptTypeToVsMapItems(
valueSetOptions.medications,
);

// Keeps track of which side nav tab to display to users
Expand Down
18 changes: 18 additions & 0 deletions query-connector/src/app/query/components/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { GroupedValueSet } from "./customizeQuery/customizeQueryUtils";

/**
* Utility function to count the number of labs / meds / conditions that we display
* on the customize query page
* @param obj a grouped ValueSet dictionary that we render as an individual accordion
* @returns A count of the number of items in each of the DibbsConceptTypes
*/
export const countDibbsConceptTypeToVsMapItems = (obj: {
[vsNameAuthorSystem: string]: GroupedValueSet;
}) => {
return Object.values(obj).reduce((runningSum, gvs) => {
gvs.items.forEach((vs) => {
runningSum += vs.concepts.length;
});
return runningSum;
}, 0);
};

0 comments on commit 7c56baf

Please sign in to comment.