diff --git a/builder-api/src/main/java/org/acme/controller/EligibilityCheckResource.java b/builder-api/src/main/java/org/acme/controller/EligibilityCheckResource.java index 193c7aa6..397846da 100644 --- a/builder-api/src/main/java/org/acme/controller/EligibilityCheckResource.java +++ b/builder-api/src/main/java/org/acme/controller/EligibilityCheckResource.java @@ -12,6 +12,8 @@ import org.acme.constants.CheckStatus; import org.acme.model.domain.EligibilityCheck; import org.acme.model.dto.CheckDmnRequest; +import org.acme.model.dto.CreateCheckRequest; +import org.acme.model.dto.UpdateCheckRequest; import org.acme.persistence.EligibilityCheckRepository; import org.acme.persistence.StorageService; import org.acme.service.DmnService; @@ -21,7 +23,7 @@ import java.util.Map; import java.util.Optional; -@Path("/api") +@Path("/api/custom-checks") public class EligibilityCheckResource { @Inject @@ -33,94 +35,12 @@ public class EligibilityCheckResource { @Inject DmnService dmnService; - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Path("/save-check-dmn") - public Response updateCheckDmn(@Context SecurityIdentity identity, CheckDmnRequest saveDmnRequest){ - String checkId = saveDmnRequest.id; - String dmnModel = saveDmnRequest.dmnModel; - if (checkId == null || checkId.isBlank()){ - return Response.status(Response.Status.BAD_REQUEST) - .entity("Error: Missing required data: checkId") - .build(); - } - - String userId = AuthUtils.getUserId(identity); - Optional checkOpt = eligibilityCheckRepository.getWorkingCustomCheck(userId, checkId); - if (checkOpt.isEmpty()){ - return Response.status(Response.Status.NOT_FOUND).build(); - } - - EligibilityCheck check = checkOpt.get(); - if (!check.getOwnerId().equals(userId)){ - return Response.status(Response.Status.UNAUTHORIZED).build(); - } - - try { - String filePath = storageService.getCheckDmnModelPath(checkId); - storageService.writeStringToStorage(filePath, dmnModel, "application/xml"); - Log.info("Saved DMN model of check " + checkId + " to storage"); - - // TODO: Need to figure out if we are allowing DMN versions to be mutable. If so, we need to update a - // last_saved field so that we know the check was updated and needs to be recompiled on evaluation - - return Response.ok().build(); - } catch (Exception e){ - Log.info(("Failed to save DMN model for check " + checkId)); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); - } - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Path("/validate-check-dmn") - public Response validateCheckDmn(@Context SecurityIdentity identity, CheckDmnRequest validateDmnRequest){ - String checkId = validateDmnRequest.id; - String dmnModel = validateDmnRequest.dmnModel; - if (checkId == null || checkId.isBlank()){ - return Response.status(Response.Status.BAD_REQUEST) - .entity("Error: Missing required data: checkId") - .build(); - } - - String userId = AuthUtils.getUserId(identity); - Optional checkOpt = eligibilityCheckRepository.getWorkingCustomCheck(userId, checkId); - if (checkOpt.isEmpty()){ - return Response.status(Response.Status.NOT_FOUND).build(); - } - - EligibilityCheck check = checkOpt.get(); - if (!check.getOwnerId().equals(userId)){ - return Response.status(Response.Status.UNAUTHORIZED).build(); - } - - if (dmnModel == null || dmnModel.isBlank()){ - return Response.ok(Map.of("errors", List.of("DMN Definition cannot be empty"))).build(); - } - - try { - HashMap dmnDependenciesMap = new HashMap(); - List validationErrors = dmnService.validateDmnXml(dmnModel, dmnDependenciesMap, check.getName(), check.getName()); - if (!validationErrors.isEmpty()) { - validationErrors = validationErrors.stream() - .map(error -> error.replaceAll("\\(.*?\\)", "")) - .collect(java.util.stream.Collectors.toList()); - - return Response.ok(Map.of("errors", validationErrors)).build(); - } - - return Response.ok(Map.of("errors", List.of())).build(); - } catch (Exception e){ - Log.info(("Failed to save DMN model for check " + checkId)); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); - } - } + // ========== Collection Endpoints ========== // By default, returns the most recent versions of all published checks owned by the calling user // If the query parameter 'working' is set to true, // then all the working check objects owned by the user are returned @GET - @Path("/custom-checks") public Response getCustomChecks( @Context SecurityIdentity identity, @QueryParam("working") Boolean working @@ -143,8 +63,34 @@ public Response getCustomChecks( return Response.ok(checks, MediaType.APPLICATION_JSON).build(); } + @POST + public Response createCustomCheck(@Context SecurityIdentity identity, + CreateCheckRequest request) { + String userId = AuthUtils.getUserId(identity); + + // Build EligibilityCheck from allowed fields only + EligibilityCheck newCheck = new EligibilityCheck( + request.name, + request.module, + request.description, + request.parameterDefinitions, + userId + ); + + try { + eligibilityCheckRepository.saveNewWorkingCustomCheck(newCheck); + return Response.ok(newCheck, MediaType.APPLICATION_JSON).build(); + } catch (Exception e){ + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(Map.of("error", "Could not save Check")) + .build(); + } + } + + // ========== Single Resource Endpoints ========== + @GET - @Path("/custom-checks/{checkId}") + @Path("/{checkId}") public Response getCustomCheck(@Context SecurityIdentity identity, @PathParam("checkId") String checkId) { String userId = AuthUtils.getUserId(identity); if (userId == null) { @@ -177,55 +123,125 @@ public Response getCustomCheck(@Context SecurityIdentity identity, @PathParam("c return Response.ok(check, MediaType.APPLICATION_JSON).build(); } - @POST - @Path("/custom-checks") - public Response createCustomCheck(@Context SecurityIdentity identity, - EligibilityCheck newCheck) { + @PATCH + @Path("/{checkId}") + public Response updateCustomCheck(@Context SecurityIdentity identity, + @PathParam("checkId") String checkId, + UpdateCheckRequest request){ String userId = AuthUtils.getUserId(identity); - //TODO: Add validations for user provided data - newCheck.setOwnerId(userId); - if (newCheck.getVersion().isEmpty()){ - newCheck.setVersion("1.0.0"); + // Check if the check exists and is not archived + Optional existingCheckOpt = eligibilityCheckRepository.getWorkingCustomCheck(userId, checkId); + if (existingCheckOpt.isEmpty()) { + return Response.status(Response.Status.NOT_FOUND).build(); + } + + EligibilityCheck existingCheck = existingCheckOpt.get(); + + // Authorization: verify ownership using existing record (not from request) + if (!userId.equals(existingCheck.getOwnerId())){ + return Response.status(Response.Status.UNAUTHORIZED).build(); } + + // Partial update: only update fields that are provided (non-null) + if (request.description != null) { + existingCheck.setDescription(request.description); + } + if (request.parameterDefinitions != null) { + existingCheck.setParameterDefinitions(request.parameterDefinitions); + } + try { - eligibilityCheckRepository.saveNewWorkingCustomCheck(newCheck); - return Response.ok(newCheck, MediaType.APPLICATION_JSON).build(); + eligibilityCheckRepository.updateWorkingCustomCheck(existingCheck); + return Response.ok().entity(existingCheck).build(); } catch (Exception e){ - return Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(Map.of("error", "Could not save Check")) + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(Map.of("error", "could not update Check")) .build(); } } + // ========== Sub-Resource Endpoints: DMN ========== + @PUT - @Path("/custom-checks") - public Response updateCustomCheck(@Context SecurityIdentity identity, - EligibilityCheck updateCheck){ - // Authorization + @Consumes(MediaType.APPLICATION_JSON) + @Path("/{checkId}/dmn") + public Response saveCheckDmn(@Context SecurityIdentity identity, + @PathParam("checkId") String checkId, + CheckDmnRequest saveDmnRequest){ + String dmnModel = saveDmnRequest.dmnModel; + String userId = AuthUtils.getUserId(identity); - if (!userId.equals(updateCheck.getOwnerId())){ + Optional checkOpt = eligibilityCheckRepository.getWorkingCustomCheck(userId, checkId); + if (checkOpt.isEmpty()){ + return Response.status(Response.Status.NOT_FOUND).build(); + } + + EligibilityCheck check = checkOpt.get(); + if (!check.getOwnerId().equals(userId)){ return Response.status(Response.Status.UNAUTHORIZED).build(); } - // Check if the check exists and is not archived - Optional existingCheckOpt = eligibilityCheckRepository.getWorkingCustomCheck(userId, updateCheck.getId()); - if (existingCheckOpt.isEmpty()) { + try { + String filePath = storageService.getCheckDmnModelPath(checkId); + storageService.writeStringToStorage(filePath, dmnModel, "application/xml"); + Log.info("Saved DMN model of check " + checkId + " to storage"); + + // TODO: Need to figure out if we are allowing DMN versions to be mutable. If so, we need to update a + // last_saved field so that we know the check was updated and needs to be recompiled on evaluation + + return Response.ok().build(); + } catch (Exception e){ + Log.info(("Failed to save DMN model for check " + checkId)); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Path("/{checkId}/dmn/validate") + public Response validateCheckDmn(@Context SecurityIdentity identity, + @PathParam("checkId") String checkId, + CheckDmnRequest validateDmnRequest){ + String dmnModel = validateDmnRequest.dmnModel; + + String userId = AuthUtils.getUserId(identity); + Optional checkOpt = eligibilityCheckRepository.getWorkingCustomCheck(userId, checkId); + if (checkOpt.isEmpty()){ return Response.status(Response.Status.NOT_FOUND).build(); } + EligibilityCheck check = checkOpt.get(); + if (!check.getOwnerId().equals(userId)){ + return Response.status(Response.Status.UNAUTHORIZED).build(); + } + + if (dmnModel == null || dmnModel.isBlank()){ + return Response.ok(Map.of("errors", List.of("DMN Definition cannot be empty"))).build(); + } + try { - eligibilityCheckRepository.updateWorkingCustomCheck(updateCheck); - return Response.ok().entity(updateCheck).build(); + HashMap dmnDependenciesMap = new HashMap(); + List validationErrors = dmnService.validateDmnXml(dmnModel, dmnDependenciesMap, check.getName(), check.getName()); + if (!validationErrors.isEmpty()) { + validationErrors = validationErrors.stream() + .map(error -> error.replaceAll("\\(.*?\\)", "")) + .collect(java.util.stream.Collectors.toList()); + + return Response.ok(Map.of("errors", validationErrors)).build(); + } + + return Response.ok(Map.of("errors", List.of())).build(); } catch (Exception e){ - return Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(Map.of("error", "could not update Check")) - .build(); + Log.info(("Failed to validate DMN model for check " + checkId)); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } } + // ========== Sub-Resource Endpoints: Actions ========== + @POST - @Path("/publish-check/{checkId}") + @Path("/{checkId}/publish") public Response publishCustomCheck(@Context SecurityIdentity identity, @PathParam("checkId") String checkId){ String userId = AuthUtils.getUserId(identity); @@ -292,26 +308,8 @@ public Response publishCustomCheck(@Context SecurityIdentity identity, @PathPara return Response.ok(check, MediaType.APPLICATION_JSON).build(); } - private String incrementMajorVersion(String version) { - int[] v = normalize(version); - v[0]++; // increment major - v[1] = 0; // reset minor - v[2] = 0; // reset patch - return v[0] + "." + v[1] + "." + v[2]; - } - - private int[] normalize(String version) { - String[] parts = version.split("\\."); - int[] nums = new int[]{0, 0, 0}; - - for (int i = 0; i < parts.length && i < 3; i++) { - nums[i] = Integer.parseInt(parts[i]); - } - return nums; - } - @POST - @Path("/custom-checks/{checkId}/archive") + @Path("/{checkId}/archive") public Response archiveCustomCheck(@Context SecurityIdentity identity, @PathParam("checkId") String checkId) { String userId = AuthUtils.getUserId(identity); if (userId == null) { @@ -346,9 +344,11 @@ public Response archiveCustomCheck(@Context SecurityIdentity identity, @PathPara } } + // ========== Sub-Resource Endpoints: Related Resources ========== + /* Endpoint for returning all Published Check Versions related to a given Working Eligibility Check */ @GET - @Path("/custom-checks/{checkId}/published-check-versions") + @Path("/{checkId}/versions") public Response getPublishedVersionsOfWorkingCheck(@Context SecurityIdentity identity, @PathParam("checkId") String checkId){ String userId = AuthUtils.getUserId(identity); Optional checkOpt = eligibilityCheckRepository.getWorkingCustomCheck(userId, checkId); @@ -363,8 +363,6 @@ public Response getPublishedVersionsOfWorkingCheck(@Context SecurityIdentity ide return Response.status(Response.Status.UNAUTHORIZED).build(); } - // Update workingCheck so that the incremented version number is saved - check.setVersion(incrementMajorVersion(check.getVersion())); try { List publishedChecks = eligibilityCheckRepository.getPublishedCheckVersions(check); @@ -375,4 +373,24 @@ public Response getPublishedVersionsOfWorkingCheck(@Context SecurityIdentity ide .build(); } } + + // ========== Private Helper Methods ========== + + private String incrementMajorVersion(String version) { + int[] v = normalize(version); + v[0]++; // increment major + v[1] = 0; // reset minor + v[2] = 0; // reset patch + return v[0] + "." + v[1] + "." + v[2]; + } + + private int[] normalize(String version) { + String[] parts = version.split("\\."); + int[] nums = new int[]{0, 0, 0}; + + for (int i = 0; i < parts.length && i < 3; i++) { + nums[i] = Integer.parseInt(parts[i]); + } + return nums; + } } diff --git a/builder-api/src/main/java/org/acme/model/domain/EligibilityCheck.java b/builder-api/src/main/java/org/acme/model/domain/EligibilityCheck.java index c664ded4..af3e1053 100644 --- a/builder-api/src/main/java/org/acme/model/domain/EligibilityCheck.java +++ b/builder-api/src/main/java/org/acme/model/domain/EligibilityCheck.java @@ -20,6 +20,24 @@ public class EligibilityCheck { private String evaluationUrl; private Boolean isArchived; + public EligibilityCheck() { + } + + public EligibilityCheck( + String name, + String module, + String description, + List parameterDefinitions, + String ownerId + ) { + this.name = name; + this.module = module; + this.description = description; + this.parameterDefinitions = parameterDefinitions; + this.ownerId = ownerId; + this.version = "1.0.0"; + } + public String getId() { return this.id; } diff --git a/builder-api/src/main/java/org/acme/model/dto/CheckDmnRequest.java b/builder-api/src/main/java/org/acme/model/dto/CheckDmnRequest.java index ab0962ad..bb2cf099 100644 --- a/builder-api/src/main/java/org/acme/model/dto/CheckDmnRequest.java +++ b/builder-api/src/main/java/org/acme/model/dto/CheckDmnRequest.java @@ -1,6 +1,5 @@ package org.acme.model.dto; public class CheckDmnRequest { - public String id; public String dmnModel; } diff --git a/builder-api/src/main/java/org/acme/model/dto/CreateCheckRequest.java b/builder-api/src/main/java/org/acme/model/dto/CreateCheckRequest.java new file mode 100644 index 00000000..656f0e0d --- /dev/null +++ b/builder-api/src/main/java/org/acme/model/dto/CreateCheckRequest.java @@ -0,0 +1,11 @@ +package org.acme.model.dto; + +import org.acme.model.domain.ParameterDefinition; +import java.util.List; + +public class CreateCheckRequest { + public String name; + public String module; + public String description; + public List parameterDefinitions; +} diff --git a/builder-api/src/main/java/org/acme/model/dto/UpdateCheckRequest.java b/builder-api/src/main/java/org/acme/model/dto/UpdateCheckRequest.java new file mode 100644 index 00000000..befaeaa1 --- /dev/null +++ b/builder-api/src/main/java/org/acme/model/dto/UpdateCheckRequest.java @@ -0,0 +1,9 @@ +package org.acme.model.dto; + +import org.acme.model.domain.ParameterDefinition; +import java.util.List; + +public class UpdateCheckRequest { + public String description; + public List parameterDefinitions; +} diff --git a/builder-api/src/main/resources/application.properties b/builder-api/src/main/resources/application.properties index 5126db2a..ce88f93d 100644 --- a/builder-api/src/main/resources/application.properties +++ b/builder-api/src/main/resources/application.properties @@ -1,6 +1,6 @@ quarkus.http.cors.enabled=true quarkus.http.cors.origins=* -quarkus.http.cors.methods=GET,POST,PUT,DELETE +quarkus.http.cors.methods=GET,POST,PUT,PATCH,DELETE quarkus.http.cors.headers=Authorization,Content-Type quarkus.datasource.db-kind=sqlite diff --git a/builder-frontend/src/api/check.ts b/builder-frontend/src/api/check.ts index da2f6f6f..f80bfa65 100644 --- a/builder-frontend/src/api/check.ts +++ b/builder-frontend/src/api/check.ts @@ -1,6 +1,6 @@ import { authFetch } from "@/api/auth"; -import type { EligibilityCheck, OptionalBoolean } from "@/types"; +import type { EligibilityCheck, OptionalBoolean, CreateCheckRequest, UpdateCheckRequest } from "@/types"; const apiUrl = import.meta.env.VITE_API_URL; @@ -54,7 +54,7 @@ export const fetchCheck = async ( } }; -export const addCheck = async (check: EligibilityCheck) => { +export const addCheck = async (check: CreateCheckRequest): Promise => { const url = apiUrl + "/custom-checks"; try { const response = await authFetch(url, { @@ -63,7 +63,12 @@ export const addCheck = async (check: EligibilityCheck) => { "Content-Type": "application/json", Accept: "application/json", }, - body: JSON.stringify(check), + body: JSON.stringify({ + name: check.name, + module: check.module, + description: check.description, + parameterDefinitions: check.parameterDefinitions, + }), }); if (!response.ok) { @@ -77,16 +82,21 @@ export const addCheck = async (check: EligibilityCheck) => { } }; -export const updateCheck = async (check: EligibilityCheck) => { - const url = apiUrl + "/custom-checks"; +export const updateCheck = async (checkId: string, updates: UpdateCheckRequest): Promise => { + const url = apiUrl + `/custom-checks/${checkId}`; try { + // Build request body with only non-undefined fields (partial update) + const body: UpdateCheckRequest = {}; + if (updates.description !== undefined) body.description = updates.description; + if (updates.parameterDefinitions !== undefined) body.parameterDefinitions = updates.parameterDefinitions; + const response = await authFetch(url, { - method: "PUT", + method: "PATCH", headers: { "Content-Type": "application/json", Accept: "application/json", }, - body: JSON.stringify(check), + body: JSON.stringify(body), }); if (!response.ok) { @@ -101,15 +111,15 @@ export const updateCheck = async (check: EligibilityCheck) => { }; export const saveCheckDmn = async (checkId: string, dmnModel: string) => { - const url = apiUrl + "/save-check-dmn"; + const url = apiUrl + `/custom-checks/${checkId}/dmn`; try { const response = await authFetch(url, { - method: "POST", + method: "PUT", headers: { "Content-Type": "application/json", Accept: "application/json", }, - body: JSON.stringify({ id: checkId, dmnModel: dmnModel }), + body: JSON.stringify({ dmnModel: dmnModel }), }); if (!response.ok) { @@ -125,7 +135,7 @@ export const validateCheckDmn = async ( checkId: string, dmnModel: string ): Promise => { - const url = apiUrl + "/validate-check-dmn"; + const url = apiUrl + `/custom-checks/${checkId}/dmn/validate`; try { const response = await authFetch(url, { method: "POST", @@ -133,7 +143,7 @@ export const validateCheckDmn = async ( "Content-Type": "application/json", Accept: "application/json", }, - body: JSON.stringify({ id: checkId, dmnModel: dmnModel }), + body: JSON.stringify({ dmnModel: dmnModel }), }); if (!response.ok) { @@ -143,7 +153,7 @@ export const validateCheckDmn = async ( const data = await response.json(); return data.errors; } catch (error) { - console.error("Error validation DMN for check:", error); + console.error("Error validating DMN for check:", error); throw error; // rethrow so you can handle it in your component if needed } }; @@ -203,7 +213,7 @@ export const evaluateWorkingCheck = async ( export const getRelatedPublishedChecks = async ( checkId: string ): Promise => { - const url = apiUrl + `/custom-checks/${checkId}/published-check-versions`; + const url = apiUrl + `/custom-checks/${checkId}/versions`; try { const response = await authFetch(url, { method: "GET", @@ -226,7 +236,7 @@ export const getRelatedPublishedChecks = async ( export const publishCheck = async ( checkId: string ): Promise => { - const url = apiUrl + `/publish-check/${checkId}`; + const url = apiUrl + `/custom-checks/${checkId}/publish`; try { const response = await authFetch(url, { method: "POST", diff --git a/builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckDetail/eligibilityCheckDetailResource.ts b/builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckDetail/eligibilityCheckDetailResource.ts index 8f4a0f15..c85591da 100644 --- a/builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckDetail/eligibilityCheckDetailResource.ts +++ b/builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckDetail/eligibilityCheckDetailResource.ts @@ -68,16 +68,15 @@ const eligibilityCheckDetailResource = ( }); const addParameter = async (parameterDef: ParameterDefinition) => { - const updatedCheck: EligibilityCheckDetail = { - ...eligibilityCheck, - parameterDefinitions: [ - ...(eligibilityCheck.parameterDefinitions || []), - parameterDef, - ], - }; + const updatedParameterDefinitions = [ + ...(eligibilityCheck.parameterDefinitions || []), + parameterDef, + ]; setActionInProgress(true); try { - await updateCheck(updatedCheck); + await updateCheck(eligibilityCheck.id, { + parameterDefinitions: updatedParameterDefinitions, + }); await refetch(); } catch (e) { console.error("Failed to add parameter", e); @@ -92,14 +91,12 @@ const eligibilityCheckDetailResource = ( const updatedParameters = [...eligibilityCheck.parameterDefinitions]; updatedParameters[parameterIndex] = parameterDef; console.log("updatedParameters", updatedParameters); - const updatedCheck: EligibilityCheckDetail = { - ...eligibilityCheck, - parameterDefinitions: updatedParameters, - }; setActionInProgress(true); try { - await updateCheck(updatedCheck); + await updateCheck(eligibilityCheck.id, { + parameterDefinitions: updatedParameters, + }); await refetch(); } catch (e) { console.error("Failed to update parameter", e); @@ -110,14 +107,12 @@ const eligibilityCheckDetailResource = ( const removeParameter = async (parameterIndex: number) => { const updatedParameters = [...eligibilityCheck.parameterDefinitions]; updatedParameters.splice(parameterIndex, 1); - const updatedCheck: EligibilityCheckDetail = { - ...eligibilityCheck, - parameterDefinitions: updatedParameters, - }; setActionInProgress(true); try { - await updateCheck(updatedCheck); + await updateCheck(eligibilityCheck.id, { + parameterDefinitions: updatedParameters, + }); await refetch(); } catch (e) { console.error("Failed to remove parameter", e); diff --git a/builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckResource.ts b/builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckResource.ts index c01126a2..72110774 100644 --- a/builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckResource.ts +++ b/builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckResource.ts @@ -1,13 +1,13 @@ import { createResource, createEffect, Accessor, createSignal } from "solid-js"; import { createStore } from "solid-js/store"; -import type { EligibilityCheck } from "@/types"; +import type { EligibilityCheck, CreateCheckRequest } from "@/types"; import { addCheck, archiveCheck, fetchUserDefinedChecks } from "@/api/check"; export interface EligibilityCheckResource { checks: () => EligibilityCheck[]; actions: { - addNewCheck: (check: EligibilityCheck) => Promise; + addNewCheck: (check: CreateCheckRequest) => Promise; removeCheck: (checkIdToRemove: string) => Promise; }; actionInProgress: Accessor; @@ -32,7 +32,7 @@ const eligibilityCheckResource = (): EligibilityCheckResource => { }); // Actions - const addNewCheck = async (check: EligibilityCheck) => { + const addNewCheck = async (check: CreateCheckRequest) => { setActionInProgress(true); try { await addCheck(check); diff --git a/builder-frontend/src/components/homeScreen/eligibilityCheckList/modals/CheckModal.tsx b/builder-frontend/src/components/homeScreen/eligibilityCheckList/modals/CheckModal.tsx index 054d834e..2117c6ef 100644 --- a/builder-frontend/src/components/homeScreen/eligibilityCheckList/modals/CheckModal.tsx +++ b/builder-frontend/src/components/homeScreen/eligibilityCheckList/modals/CheckModal.tsx @@ -1,6 +1,6 @@ import { createStore } from "solid-js/store"; -import type { EligibilityCheck } from "@/types"; +import type { CreateCheckRequest } from "@/types"; type CheckValues = { name: string; @@ -11,7 +11,7 @@ const EditCheckModal = ({ modalAction, closeModal, }: { - modalAction: (check: EligibilityCheck) => Promise; + modalAction: (check: CreateCheckRequest) => Promise; closeModal: () => void; }) => { const [newCheck, setNewCheck] = createStore({ @@ -84,17 +84,10 @@ const EditCheckModal = ({ console.log("Please fill in all fields."); return; } - const check: EligibilityCheck = { - id: - newCheck.module.toLowerCase() + - "-" + - newCheck.name.toLowerCase().replace(/\s+/g, "_"), + const check: CreateCheckRequest = { name: newCheck.name, - version: "1.0.0", - module: newCheck.module, description: newCheck.description, - inputDefinition: {}, parameterDefinitions: [], }; await modalAction(check); diff --git a/builder-frontend/src/types.ts b/builder-frontend/src/types.ts index a26ee560..18004185 100644 --- a/builder-frontend/src/types.ts +++ b/builder-frontend/src/types.ts @@ -49,6 +49,19 @@ export interface EligibilityCheckDetail extends EligibilityCheck { dmnModel: string; } +// Request types for EligibilityCheck API endpoints +export interface CreateCheckRequest { + name: string; + module: string; + description: string; + parameterDefinitions: ParameterDefinition[]; +} + +export interface UpdateCheckRequest { + description?: string; + parameterDefinitions?: ParameterDefinition[]; +} + // Parameter Types export type ParameterDefinition = | StringParameter