From 62a89201a2ff1051ce5c13cd93553643e7b6cce2 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Tue, 31 May 2022 05:47:30 -0400 Subject: [PATCH 1/8] initial met reqs db --- .../endpoint/controllers/DataController.java | 44 +------ .../davinci/endpoint/rems/DatabaseInit.java | 62 +++++++--- .../rems/controller/RemsController.java | 69 +++++++++++ .../endpoint/rems/database/fhir/RemsFhir.java | 2 +- .../database/rems}/Rems.java | 33 ++++-- .../database/rems}/RemsRepository.java | 2 +- .../database/rems}/RemsService.java | 2 +- .../database/rems}/RemsServiceImpl.java | 2 +- .../database/requirement/MetRequirement.java | 107 ++++++++++++++++++ .../requirement/MetRequirementRepository.java | 23 ++++ .../database/requirement/Requirement.java | 43 ++++--- 11 files changed, 304 insertions(+), 85 deletions(-) rename server/src/main/java/org/hl7/davinci/endpoint/{database => rems/database/rems}/Rems.java (60%) rename server/src/main/java/org/hl7/davinci/endpoint/{database => rems/database/rems}/RemsRepository.java (91%) rename server/src/main/java/org/hl7/davinci/endpoint/{database => rems/database/rems}/RemsService.java (77%) rename server/src/main/java/org/hl7/davinci/endpoint/{database => rems/database/rems}/RemsServiceImpl.java (92%) create mode 100644 server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java create mode 100644 server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirementRepository.java diff --git a/server/src/main/java/org/hl7/davinci/endpoint/controllers/DataController.java b/server/src/main/java/org/hl7/davinci/endpoint/controllers/DataController.java index 0a1eabac6..509fee2a6 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/controllers/DataController.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/controllers/DataController.java @@ -44,8 +44,8 @@ public class DataController { @Autowired private ClientRepository clientRepository; - @Autowired - private RemsRepository remsRepository; + // @Autowired + // private RemsRepository remsRepository; @Autowired private YamlConfig myConfig; @@ -165,44 +165,4 @@ public RedirectView reload(@RequestParam String vsac_api_key) { return new RedirectView(newUrl); } - public void updateComplianceBundleStatus(String uid) { - try { - TimeUnit.SECONDS.sleep(30); - } - catch(Exception e) - { - System.out.println(e); - } - Rems rems = remsRepository.findById(uid).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, uid + " not found")); - rems.setStatus("Approved"); - remsRepository.save(rems); - } - - public void updateComplianceBundleStatusInBackground (final String uid) { - Thread t = new Thread(() -> updateComplianceBundleStatus(uid)); - t.start(); - } - - @PostMapping(value = "/api/rems") - @CrossOrigin - public ResponseEntity postRems(@RequestBody String jsonData) { - JsonNode remsObject = JacksonUtil.toJsonNode(jsonData); - String id = UUID.randomUUID().toString().replace("-", ""); - - Rems complianceBundle = new Rems(); - complianceBundle.setCase_number(id); - complianceBundle.setComplianceBundle(remsObject); - complianceBundle.setStatus("Pending"); - remsRepository.save(complianceBundle); - updateComplianceBundleStatusInBackground(id); - return ResponseEntity.ok().body(complianceBundle); - - } - - @CrossOrigin - @GetMapping("/api/rems/{id}") - public ResponseEntity getRems(@PathVariable String id) { - Rems rems = remsRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, id + " not found")); - return ResponseEntity.ok().body(rems); - } } diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java index 71e78fc9f..06d04b2e4 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java @@ -46,22 +46,56 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re return args -> { log.info("Preloading turalio"); Drug turalio = new Drug(); - - String questionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); - Requirement requirement = new Requirement(); - RemsFhir remsFhir = new RemsFhir(); - remsFhir.setResourceType(ResourceType.Questionnaire.toString()); - JsonNode questionnaireResource = JacksonUtil.toJsonNode(questionnaire); - remsFhir.setResource(questionnaireResource); - remsFhir.setId("q1"); - remsFhirRepository.save(remsFhir); - requirement.setRequirement(remsFhir); - requirement.setDescription("complete questionnaire"); - turalio.addRequirement(requirement); turalio.setId("turalio"); + + // patient enrollment form requirement + String patientQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); + Requirement patientEnrollmentRequirement = new Requirement(); + RemsFhir patientEnrollmentResource = new RemsFhir(); + patientEnrollmentResource.setResourceType(ResourceType.Questionnaire.toString()); + JsonNode patientQuestionnaireResource = JacksonUtil.toJsonNode(patientQuestionnaire); + patientEnrollmentResource.setResource(patientQuestionnaireResource); + patientEnrollmentResource.setId("turalio-patient-enrollment"); + remsFhirRepository.save(patientEnrollmentResource); + patientEnrollmentRequirement.setRequirement(patientEnrollmentResource); + patientEnrollmentRequirement.setDescription("complete patient enrollment questionnaire"); + patientEnrollmentRequirement.setDrug(turalio); + turalio.addRequirement(patientEnrollmentRequirement); + + // prescriber enrollment form requirement + String prescriberQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); + Requirement prescriberEnrollmentRequirement = new Requirement(); + RemsFhir prescriberEnrollmentResource = new RemsFhir(); + prescriberEnrollmentResource.setResourceType(ResourceType.Questionnaire.toString()); + JsonNode prescriberQuestionnaireResource = JacksonUtil.toJsonNode(prescriberQuestionnaire); + prescriberEnrollmentResource.setResource(prescriberQuestionnaireResource); + prescriberEnrollmentResource.setId("turalio-prescriber-enrollment"); + remsFhirRepository.save(prescriberEnrollmentResource); + prescriberEnrollmentRequirement.setRequirement(prescriberEnrollmentResource); + prescriberEnrollmentRequirement.setDescription("complete prescriber enrollment questionnaire"); + prescriberEnrollmentRequirement.setDrug(turalio); + turalio.addRequirement(prescriberEnrollmentRequirement); + + // prescriber knowledge assessment / certification sub-requirement + String prescriberKnowledgeQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); + Requirement prescriberCertificationRequirement = new Requirement(); + RemsFhir prescriberKnowledgeResource = new RemsFhir(); + prescriberKnowledgeResource.setResourceType(ResourceType.Questionnaire.toString()); + JsonNode prescriberKnowledgeQuestionnaireResource = JacksonUtil.toJsonNode(prescriberKnowledgeQuestionnaire); + prescriberKnowledgeResource.setResource(prescriberKnowledgeQuestionnaireResource); + prescriberKnowledgeResource.setId("turalio-prescriber-knowledge-check"); + remsFhirRepository.save(prescriberKnowledgeResource); + prescriberCertificationRequirement.setRequirement(prescriberKnowledgeResource); + prescriberCertificationRequirement.setDescription("complete prescriber knowledge check"); + prescriberCertificationRequirement.setDrug(turalio); + prescriberCertificationRequirement.setParent(prescriberEnrollmentRequirement); + turalio.addRequirement(prescriberCertificationRequirement); + repository.save(turalio); - requirement.setDrug(turalio); - requirementRepository.save(requirement); + requirementRepository.save(patientEnrollmentRequirement); + requirementRepository.save(prescriberEnrollmentRequirement); + requirementRepository.save(prescriberCertificationRequirement); + }; } } \ No newline at end of file diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java index a9b9ae3d9..e66933c81 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java @@ -1,9 +1,18 @@ package org.hl7.davinci.endpoint.rems.controller; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.fasterxml.jackson.databind.JsonNode; +import com.vladmihalcea.hibernate.type.json.internal.JacksonUtil; + import org.hl7.davinci.endpoint.Application; import org.hl7.davinci.endpoint.rems.database.drugs.Drug; import org.hl7.davinci.endpoint.rems.database.drugs.DrugsRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.hl7.davinci.endpoint.rems.database.rems.Rems; +import org.hl7.davinci.endpoint.rems.database.rems.RemsRepository; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; @@ -11,6 +20,19 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; +import org.springframework.http.ResponseEntity; +import org.springframework.web.servlet.view.RedirectView; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import org.springframework.web.server.ResponseStatusException; +import org.springframework.http.HttpStatus; +import java.util.Arrays; + import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.logging.Logger; @@ -25,6 +47,9 @@ public class RemsController { @Autowired private DrugsRepository drugsRepository; + @Autowired + private RemsRepository remsRepository; + @GetMapping(value = "/rems/{id}") @CrossOrigin public ResponseEntity getRequirements(HttpServletRequest request, @PathVariable String id) throws IOException { @@ -41,4 +66,48 @@ private ResponseEntity processRequirements(Drug drug) { .contentType(MediaType.parseMediaType(MediaType.APPLICATION_JSON_VALUE)) .body(drug); } + + public void updateRemsRequestStatus(String uid) { + try { + TimeUnit.SECONDS.sleep(30); + } + catch(Exception e) + { + System.out.println(e); + } + Rems rems = remsRepository.findById(uid).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, uid + " not found")); + rems.setStatus("Approved"); + remsRepository.save(rems); + } + + public void updateRemsRequestStatusInBackground (final String uid) { + Thread t = new Thread(() -> updateRemsRequestStatus(uid)); + t.start(); + } + + @PostMapping(value = "/api/rems") + @CrossOrigin + public ResponseEntity postRems(@RequestBody String jsonData) { + JsonNode remsObject = JacksonUtil.toJsonNode(jsonData); + String id = UUID.randomUUID().toString().replace("-", ""); + + Rems remsRequest = new Rems(); + remsRequest.setCase_number(id); + remsRequest.setStatus("Pending"); + + + + remsRepository.save(remsRequest); + updateRemsRequestStatusInBackground(id); + return ResponseEntity.ok().body(remsRequest); + + } + + @CrossOrigin + @GetMapping("/api/rems/{id}") + public ResponseEntity getRems(@PathVariable String id) { + Rems rems = remsRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, id + " not found")); + return ResponseEntity.ok().body(rems); + } + } \ No newline at end of file diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/fhir/RemsFhir.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/fhir/RemsFhir.java index 945788f29..2c06e6062 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/fhir/RemsFhir.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/fhir/RemsFhir.java @@ -22,7 +22,7 @@ public class RemsFhir { private String createdAt; @Type(type = "json") - @Column(columnDefinition = "json", name = "complianceBundle", nullable = false, length = 10000000) + @Column(columnDefinition = "json", name = "resource", nullable = false, length = 10000000) private JsonNode resource; diff --git a/server/src/main/java/org/hl7/davinci/endpoint/database/Rems.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java similarity index 60% rename from server/src/main/java/org/hl7/davinci/endpoint/database/Rems.java rename to server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java index 60511251e..924f53ec4 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/database/Rems.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java @@ -1,4 +1,9 @@ -package org.hl7.davinci.endpoint.database; +package org.hl7.davinci.endpoint.rems.database.rems; +import org.hl7.davinci.endpoint.rems.database.requirement.MetRequirement; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.*; + import javax.persistence.Column; import javax.persistence.Entity; @@ -18,13 +23,13 @@ public class Rems { @Column(name = "case_number", nullable = false, length = 100) private String case_number; - @Type(type = "json") - @Column(columnDefinition = "json", name = "complianceBundle", nullable = false, length = 10000000) - private JsonNode complianceBundle; @Column(name = "status", nullable = false, length = 100) private String status; + @OneToMany(mappedBy="remsRequest") + private List metRequirements = new ArrayList<>(); + public void Rems() {} public String getCase_number() { @@ -35,14 +40,6 @@ public void setCase_number(String id) { this.case_number = id; } - public JsonNode getComplianceBundle() { - return this.complianceBundle; - } - - public void setComplianceBundle(JsonNode jsonParam) { - this.complianceBundle = jsonParam; - } - public String getStatus() { return this.status; } @@ -50,4 +47,16 @@ public String getStatus() { public void setStatus(String statusParam) { this.status = statusParam; } + + public List getMetRequirements() { + return this.metRequirements; +} + +public void setResource(List metRequirements) { + this.metRequirements = metRequirements; +} + +public void addMetRequirement(MetRequirement metRequirement) { + this.metRequirements.add(metRequirement); +} } diff --git a/server/src/main/java/org/hl7/davinci/endpoint/database/RemsRepository.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/RemsRepository.java similarity index 91% rename from server/src/main/java/org/hl7/davinci/endpoint/database/RemsRepository.java rename to server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/RemsRepository.java index df21ac22e..2e641987b 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/database/RemsRepository.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/RemsRepository.java @@ -1,4 +1,4 @@ -package org.hl7.davinci.endpoint.database; +package org.hl7.davinci.endpoint.rems.database.rems; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; diff --git a/server/src/main/java/org/hl7/davinci/endpoint/database/RemsService.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/RemsService.java similarity index 77% rename from server/src/main/java/org/hl7/davinci/endpoint/database/RemsService.java rename to server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/RemsService.java index ad2bb034d..04cc1a8bb 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/database/RemsService.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/RemsService.java @@ -1,4 +1,4 @@ -package org.hl7.davinci.endpoint.database; +package org.hl7.davinci.endpoint.rems.database.rems; public interface RemsService { Iterable findAll(); diff --git a/server/src/main/java/org/hl7/davinci/endpoint/database/RemsServiceImpl.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/RemsServiceImpl.java similarity index 92% rename from server/src/main/java/org/hl7/davinci/endpoint/database/RemsServiceImpl.java rename to server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/RemsServiceImpl.java index b8070b859..dc4c06e06 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/database/RemsServiceImpl.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/RemsServiceImpl.java @@ -1,4 +1,4 @@ -package org.hl7.davinci.endpoint.database; +package org.hl7.davinci.endpoint.rems.database.rems; import org.springframework.beans.factory.annotation.Autowired; diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java new file mode 100644 index 000000000..0bb209919 --- /dev/null +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java @@ -0,0 +1,107 @@ +package org.hl7.davinci.endpoint.rems.database.requirement; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.hl7.davinci.endpoint.rems.database.drugs.Drug; +import org.hl7.davinci.endpoint.rems.database.fhir.RemsFhir; +import org.hl7.davinci.endpoint.rems.database.rems.Rems; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.*; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +@Entity +@Table(name = "metRequirement") +public class MetRequirement { + @Id + @GeneratedValue + @Column(name = "id", nullable = false) + private Integer id; + + @Column(name = "createdAt", nullable = false) + private String createdAt; + + @Column(name = "completed", nullable = false) + private boolean completed ; + + // FHIR resource which defines the requirement (task, questionnaire, etc) + @JoinColumn(name = "completedRequirement", nullable = false) + @OneToOne + private RemsFhir completedRequirement; + + @ManyToOne + @JoinColumn(name="REQUIREMENT_ID") + @JsonIgnore + private Requirement requirement; + + @ManyToOne + @JoinColumn(name="REMS_REQUEST") + @JsonIgnore + private Rems remsRequest; + + @OneToMany(mappedBy="parentMetRequirement") + private List childMetRequirements = new ArrayList<>(); + + @ManyToOne + @JoinColumn(name="PARENT_MET_REQUIREMENT") + @JsonIgnore + private MetRequirement parentMetRequirement; + + public MetRequirement() { + this.createdAt = ZonedDateTime.now().format(DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" )); + this.completed = false; + } + + public RemsFhir getCompletedRequirement() { + return this.completedRequirement; + } + + public void setCompletedRequirement(RemsFhir requirement) { + this.completedRequirement = requirement; + } + + public String getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + public boolean isCompleted() { + return completed; + } + + public void setCompleted(boolean completed) { + this.completed = completed; + } + + public Requirement getRequirement() { + return requirement; + } + + public void setRequirement(Requirement requirement) { + this.requirement = requirement; + } + + public List getChildren() { + return this.childMetRequirements; + } + + public void setChildren(List requirements) { + this.childMetRequirements = requirements; + } + + public void addChild(MetRequirement requirement) { + this.childMetRequirements.add(requirement); + } + + public MetRequirement getParent() { + return this.parentMetRequirement; + } + + public void setParent(MetRequirement requirement) { + this.parentMetRequirement = requirement; + } + +} diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirementRepository.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirementRepository.java new file mode 100644 index 000000000..d375b937f --- /dev/null +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirementRepository.java @@ -0,0 +1,23 @@ +package org.hl7.davinci.endpoint.rems.database.requirement; + +import java.util.List; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; +import org.springframework.stereotype.Repository; +import org.springframework.web.bind.annotation.CrossOrigin; + + +@RepositoryRestResource +@CrossOrigin(origins = "http://localhost:4200") +@Repository +public interface MetRequirementRepository extends CrudRepository { + + @Query( + "SELECT r FROM MetRequirement r") + List findAll(); + +} + + diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java index d1db8fa98..428e44b38 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import org.hl7.davinci.endpoint.rems.database.drugs.Drug; import org.hl7.davinci.endpoint.rems.database.fhir.RemsFhir; +import java.util.ArrayList; +import java.util.List; import javax.persistence.*; import java.time.ZonedDateTime; @@ -18,9 +20,6 @@ public class Requirement { @Column(name = "createdAt", nullable = false) private String createdAt; - @Column(name = "completed", nullable = false) - private boolean completed ; - @Column(name = "description", nullable = true) private String description; @@ -34,9 +33,16 @@ public class Requirement { @JsonIgnore private Drug drug; + @OneToMany(mappedBy="parentRequirement") + private List childRequirements = new ArrayList<>(); + + @ManyToOne + @JoinColumn(name="PARENT_REQUIREMENT") + @JsonIgnore + private Requirement parentRequirement; + public Requirement() { this.createdAt = ZonedDateTime.now().format(DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" )); - this.completed = false; } public RemsFhir getRequirement() { @@ -55,15 +61,6 @@ public void setCreatedAt(String createdAt) { this.createdAt = createdAt; } - public boolean isCompleted() { - return completed; - } - - public void setCompleted(boolean completed) { - this.completed = completed; - } - - public String getDescription() { return description; } @@ -80,4 +77,24 @@ public void setDrug(Drug drug) { this.drug = drug; } + public List getChildren() { + return this.childRequirements; + } + + public void setChildren(List requirements) { + this.childRequirements = requirements; + } + + public void addChild(Requirement requirement) { + this.childRequirements.add(requirement); + } + + public Requirement getParent() { + return this.parentRequirement; + } + + public void setParent(Requirement requirement) { + this.parentRequirement = requirement; + } + } From 1730b2b895eb289e0afdcece737d91ac3226c8ca Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Tue, 31 May 2022 14:40:58 -0400 Subject: [PATCH 2/8] met requirements schemas --- .../davinci/endpoint/rems/DatabaseInit.java | 36 +++++++--------- .../rems/controller/RemsController.java | 43 ++++++++++++++++++- .../endpoint/rems/database/drugs/Drug.java | 2 +- .../rems/database/drugs/DrugsRepository.java | 4 ++ .../endpoint/rems/database/rems/Rems.java | 16 ++++++- .../database/requirement/MetRequirement.java | 8 ++-- .../database/requirement/Requirement.java | 19 +++++++- 7 files changed, 97 insertions(+), 31 deletions(-) diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java index 06d04b2e4..3c034c817 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java @@ -47,6 +47,8 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re log.info("Preloading turalio"); Drug turalio = new Drug(); turalio.setId("turalio"); + turalio.setCodeSystem("http://www.nlm.nih.gov/research/umls/rxnorm"); + turalio.setCode("2183126"); // patient enrollment form requirement String patientQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); @@ -62,6 +64,18 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re patientEnrollmentRequirement.setDrug(turalio); turalio.addRequirement(patientEnrollmentRequirement); + // prescriber knowledge assessment / certification sub-requirement + String prescriberKnowledgeQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); + Requirement prescriberCertificationRequirement = new Requirement(); + RemsFhir prescriberKnowledgeResource = new RemsFhir(); + prescriberKnowledgeResource.setResourceType(ResourceType.Questionnaire.toString()); + JsonNode prescriberKnowledgeQuestionnaireResource = JacksonUtil.toJsonNode(prescriberKnowledgeQuestionnaire); + prescriberKnowledgeResource.setResource(prescriberKnowledgeQuestionnaireResource); + prescriberKnowledgeResource.setId("turalio-prescriber-knowledge-check"); + remsFhirRepository.save(prescriberKnowledgeResource); + prescriberCertificationRequirement.setRequirement(prescriberKnowledgeResource); + prescriberCertificationRequirement.setDescription("complete prescriber knowledge check"); + // prescriber enrollment form requirement String prescriberQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); Requirement prescriberEnrollmentRequirement = new Requirement(); @@ -74,28 +88,10 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re prescriberEnrollmentRequirement.setRequirement(prescriberEnrollmentResource); prescriberEnrollmentRequirement.setDescription("complete prescriber enrollment questionnaire"); prescriberEnrollmentRequirement.setDrug(turalio); + prescriberEnrollmentRequirement.addChild(prescriberCertificationRequirement); turalio.addRequirement(prescriberEnrollmentRequirement); - // prescriber knowledge assessment / certification sub-requirement - String prescriberKnowledgeQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); - Requirement prescriberCertificationRequirement = new Requirement(); - RemsFhir prescriberKnowledgeResource = new RemsFhir(); - prescriberKnowledgeResource.setResourceType(ResourceType.Questionnaire.toString()); - JsonNode prescriberKnowledgeQuestionnaireResource = JacksonUtil.toJsonNode(prescriberKnowledgeQuestionnaire); - prescriberKnowledgeResource.setResource(prescriberKnowledgeQuestionnaireResource); - prescriberKnowledgeResource.setId("turalio-prescriber-knowledge-check"); - remsFhirRepository.save(prescriberKnowledgeResource); - prescriberCertificationRequirement.setRequirement(prescriberKnowledgeResource); - prescriberCertificationRequirement.setDescription("complete prescriber knowledge check"); - prescriberCertificationRequirement.setDrug(turalio); - prescriberCertificationRequirement.setParent(prescriberEnrollmentRequirement); - turalio.addRequirement(prescriberCertificationRequirement); - - repository.save(turalio); - requirementRepository.save(patientEnrollmentRequirement); - requirementRepository.save(prescriberEnrollmentRequirement); - requirementRepository.save(prescriberCertificationRequirement); - + repository.save(turalio);; }; } } \ No newline at end of file diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java index e66933c81..85e9fc050 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java @@ -6,6 +6,8 @@ import com.google.gson.JsonParser; import com.fasterxml.jackson.databind.JsonNode; import com.vladmihalcea.hibernate.type.json.internal.JacksonUtil; +import org.hl7.davinci.endpoint.rems.database.requirement.MetRequirement; +import org.hl7.davinci.endpoint.rems.database.requirement.Requirement; import org.hl7.davinci.endpoint.Application; import org.hl7.davinci.endpoint.rems.database.drugs.Drug; @@ -85,16 +87,39 @@ public void updateRemsRequestStatusInBackground (final String uid) { t.start(); } - @PostMapping(value = "/api/rems") + @PostMapping(value = "/rems") @CrossOrigin public ResponseEntity postRems(@RequestBody String jsonData) { JsonNode remsObject = JacksonUtil.toJsonNode(jsonData); String id = UUID.randomUUID().toString().replace("-", ""); - + + JsonNode params = getResource(remsObject, remsObject.get("entry").get(0).get("resource").get("focus").get("parameters").get("reference").textValue()); + + String prescriptionReference = ""; + for (JsonNode param : params.get("parameter")) { + if (param.get("name").textValue().equals("prescription")) { + prescriptionReference = param.get("reference").textValue(); + } + } + + JsonNode presciption = getResource(remsObject, prescriptionReference); + String prescriptionSystem = presciption.get("medicationCodeableConcept").get("coding").get(0).get("system").textValue(); + String prescriptionCode = presciption.get("medicationCodeableConcept").get("coding").get(0).get("code").textValue(); + Drug drug = drugsRepository.findDrugByCode(prescriptionSystem, prescriptionCode).get(0); + + + Rems remsRequest = new Rems(); remsRequest.setCase_number(id); remsRequest.setStatus("Pending"); + remsRequest.setResource(remsObject); + // sub requirements don't seem to be working, this loop will need to change to handle multiple levels of requirement conditions + for (Requirement requirement : drug.getRequirements()) { + MetRequirement metReq = new MetRequirement(); + metReq.setRequirement(requirement); + remsRequest.addMetRequirement(metReq); + } remsRepository.save(remsRequest); @@ -109,5 +134,19 @@ public ResponseEntity getRems(@PathVariable String id) { Rems rems = remsRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, id + " not found")); return ResponseEntity.ok().body(rems); } + + public JsonNode getResource(JsonNode bundle, String resourceReference) { + String[] temp = resourceReference.split("/"); + String _resourceType = temp[0]; + String _id = temp[1]; + + for (int i = 0; i < bundle.get("entry").size(); i++) { + if ((bundle.get("entry").get(i).get("resource").get("resourceType").textValue().equals(_resourceType)) + && (bundle.get("entry").get(i).get("resource").get("id").textValue().equals(_id))) { + return bundle.get("entry").get(i).get("resource"); + } + } + return null; + } } \ No newline at end of file diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/Drug.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/Drug.java index b576f2aca..ace9fd834 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/Drug.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/Drug.java @@ -24,7 +24,7 @@ public class Drug { @Column(name = "createdAt", nullable = false) private String createdAt; - @OneToMany(mappedBy="drug") + @OneToMany(mappedBy="drug", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List requirements = new ArrayList<>(); public Drug() { diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/DrugsRepository.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/DrugsRepository.java index 324c8f33b..de10fa8d8 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/DrugsRepository.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/DrugsRepository.java @@ -5,6 +5,8 @@ import org.springframework.data.rest.core.annotation.RepositoryRestResource; import org.springframework.stereotype.Repository; import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.data.repository.query.Param; + import java.util.List; @@ -18,5 +20,7 @@ public interface DrugsRepository extends CrudRepository { "SELECT r FROM Drug r") List findLogs(); + @Query("SELECT r FROM Drug r where r.codeSystem = :system and r.code = :code") + List findDrugByCode(@Param("system") String system, @Param("code") String code); } diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java index 924f53ec4..5cb179410 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java @@ -27,7 +27,11 @@ public class Rems { @Column(name = "status", nullable = false, length = 100) private String status; - @OneToMany(mappedBy="remsRequest") + @Type(type = "json") + @Column(columnDefinition = "json", name = "resource", nullable = false, length = 10000000) + private JsonNode resource; + + @OneToMany(mappedBy="remsRequest", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List metRequirements = new ArrayList<>(); public void Rems() {} @@ -52,11 +56,19 @@ public List getMetRequirements() { return this.metRequirements; } -public void setResource(List metRequirements) { +public void setMetRequirement(List metRequirements) { this.metRequirements = metRequirements; } public void addMetRequirement(MetRequirement metRequirement) { this.metRequirements.add(metRequirement); } + +public JsonNode getResource() { + return this.resource; +} + +public void setResource(JsonNode resource) { + this.resource = resource; +} } diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java index 0bb209919..2ac9f9dc8 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java @@ -25,11 +25,11 @@ public class MetRequirement { private boolean completed ; // FHIR resource which defines the requirement (task, questionnaire, etc) - @JoinColumn(name = "completedRequirement", nullable = false) - @OneToOne + @JoinColumn(name = "completedRequirement", nullable = true) + @OneToOne(fetch = FetchType.LAZY) private RemsFhir completedRequirement; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="REQUIREMENT_ID") @JsonIgnore private Requirement requirement; @@ -39,7 +39,7 @@ public class MetRequirement { @JsonIgnore private Rems remsRequest; - @OneToMany(mappedBy="parentMetRequirement") + @OneToMany(mappedBy="parentMetRequirement", fetch = FetchType.LAZY) private List childMetRequirements = new ArrayList<>(); @ManyToOne diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java index 428e44b38..a97fa22e3 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java @@ -28,15 +28,18 @@ public class Requirement { @OneToOne private RemsFhir requirement; + @OneToMany(mappedBy="requirement") + private List metRequirements = new ArrayList<>(); + @ManyToOne @JoinColumn(name="DRUG_ID") @JsonIgnore private Drug drug; - @OneToMany(mappedBy="parentRequirement") + @OneToMany(mappedBy="parentRequirement", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List childRequirements = new ArrayList<>(); - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="PARENT_REQUIREMENT") @JsonIgnore private Requirement parentRequirement; @@ -97,4 +100,16 @@ public void setParent(Requirement requirement) { this.parentRequirement = requirement; } + public List getMetRequirements() { + return this.metRequirements; + } + + public void setMetRequirements(List metRequirements) { + this.metRequirements = metRequirements; + } + + public void addChild(MetRequirement metRequirement) { + this.metRequirements.add(metRequirement); + } + } From 321f3c2acdbb85dc6c1e4c7f8887a6835ed0c19f Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Tue, 31 May 2022 14:51:25 -0400 Subject: [PATCH 3/8] url change --- .../hl7/davinci/endpoint/rems/controller/RemsController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java index 85e9fc050..779e7a00c 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java @@ -52,7 +52,7 @@ public class RemsController { @Autowired private RemsRepository remsRepository; - @GetMapping(value = "/rems/{id}") + @GetMapping(value = "/drug/{id}") @CrossOrigin public ResponseEntity getRequirements(HttpServletRequest request, @PathVariable String id) throws IOException { Drug drug = drugsRepository.findById(id).get(); @@ -129,7 +129,7 @@ public ResponseEntity postRems(@RequestBody String jsonData) { } @CrossOrigin - @GetMapping("/api/rems/{id}") + @GetMapping("/rems/{id}") public ResponseEntity getRems(@PathVariable String id) { Rems rems = remsRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, id + " not found")); return ResponseEntity.ok().body(rems); From 5a73eb7ae7643c24b229962bd0c8c70661b227b1 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Wed, 1 Jun 2022 11:36:47 -0400 Subject: [PATCH 4/8] field name changes --- .../hl7/davinci/endpoint/rems/DatabaseInit.java | 6 +++--- .../endpoint/rems/database/rems/Rems.java | 17 ++++++++++++++++- .../database/requirement/MetRequirement.java | 12 ++++++------ .../rems/database/requirement/Requirement.java | 12 ++++++------ 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java index 3c034c817..b2051c05a 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java @@ -59,7 +59,7 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re patientEnrollmentResource.setResource(patientQuestionnaireResource); patientEnrollmentResource.setId("turalio-patient-enrollment"); remsFhirRepository.save(patientEnrollmentResource); - patientEnrollmentRequirement.setRequirement(patientEnrollmentResource); + patientEnrollmentRequirement.setResource(patientEnrollmentResource); patientEnrollmentRequirement.setDescription("complete patient enrollment questionnaire"); patientEnrollmentRequirement.setDrug(turalio); turalio.addRequirement(patientEnrollmentRequirement); @@ -73,7 +73,7 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re prescriberKnowledgeResource.setResource(prescriberKnowledgeQuestionnaireResource); prescriberKnowledgeResource.setId("turalio-prescriber-knowledge-check"); remsFhirRepository.save(prescriberKnowledgeResource); - prescriberCertificationRequirement.setRequirement(prescriberKnowledgeResource); + prescriberCertificationRequirement.setResource(prescriberKnowledgeResource); prescriberCertificationRequirement.setDescription("complete prescriber knowledge check"); // prescriber enrollment form requirement @@ -85,7 +85,7 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re prescriberEnrollmentResource.setResource(prescriberQuestionnaireResource); prescriberEnrollmentResource.setId("turalio-prescriber-enrollment"); remsFhirRepository.save(prescriberEnrollmentResource); - prescriberEnrollmentRequirement.setRequirement(prescriberEnrollmentResource); + prescriberEnrollmentRequirement.setResource(prescriberEnrollmentResource); prescriberEnrollmentRequirement.setDescription("complete prescriber enrollment questionnaire"); prescriberEnrollmentRequirement.setDrug(turalio); prescriberEnrollmentRequirement.addChild(prescriberCertificationRequirement); diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java index 5cb179410..bebc0a60b 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; import javax.persistence.*; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import javax.persistence.Column; @@ -27,6 +29,9 @@ public class Rems { @Column(name = "status", nullable = false, length = 100) private String status; + @Column(name = "createdAt", nullable = false) + private String createdAt; + @Type(type = "json") @Column(columnDefinition = "json", name = "resource", nullable = false, length = 10000000) private JsonNode resource; @@ -34,7 +39,9 @@ public class Rems { @OneToMany(mappedBy="remsRequest", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List metRequirements = new ArrayList<>(); - public void Rems() {} + public void Rems() { + this.createdAt = ZonedDateTime.now().format(DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" )); + } public String getCase_number() { return this.case_number; @@ -64,6 +71,14 @@ public void addMetRequirement(MetRequirement metRequirement) { this.metRequirements.add(metRequirement); } +public String getCreatedAt() { + return createdAt; +} + +public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; +} + public JsonNode getResource() { return this.resource; } diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java index 2ac9f9dc8..0b93d3823 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java @@ -25,9 +25,9 @@ public class MetRequirement { private boolean completed ; // FHIR resource which defines the requirement (task, questionnaire, etc) - @JoinColumn(name = "completedRequirement", nullable = true) + @JoinColumn(name = "completedResource", nullable = true) @OneToOne(fetch = FetchType.LAZY) - private RemsFhir completedRequirement; + private RemsFhir completedResource; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="REQUIREMENT_ID") @@ -52,12 +52,12 @@ public MetRequirement() { this.completed = false; } - public RemsFhir getCompletedRequirement() { - return this.completedRequirement; + public RemsFhir getCompletedResource() { + return this.completedResource; } - public void setCompletedRequirement(RemsFhir requirement) { - this.completedRequirement = requirement; + public void setCompletedResource(RemsFhir requirement) { + this.completedResource = requirement; } public String getCreatedAt() { diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java index a97fa22e3..ca6d0b975 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java @@ -24,9 +24,9 @@ public class Requirement { private String description; // FHIR resource which defines the requirement (task, questionnaire, etc) - @JoinColumn(name = "requirement", nullable = false) + @JoinColumn(name = "resource", nullable = false) @OneToOne - private RemsFhir requirement; + private RemsFhir resource; @OneToMany(mappedBy="requirement") private List metRequirements = new ArrayList<>(); @@ -48,12 +48,12 @@ public Requirement() { this.createdAt = ZonedDateTime.now().format(DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" )); } - public RemsFhir getRequirement() { - return this.requirement; + public RemsFhir getResource() { + return this.resource; } - public void setRequirement(RemsFhir requirement) { - this.requirement = requirement; + public void setResource(RemsFhir resource) { + this.resource = resource; } public String getCreatedAt() { From 27cdc1b2e227a4e28b0c7115eb17cf521e4cf957 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Wed, 1 Jun 2022 14:00:48 -0400 Subject: [PATCH 5/8] Revert "field name changes" This reverts commit 5a73eb7ae7643c24b229962bd0c8c70661b227b1. --- .../hl7/davinci/endpoint/rems/DatabaseInit.java | 6 +++--- .../endpoint/rems/database/rems/Rems.java | 17 +---------------- .../database/requirement/MetRequirement.java | 12 ++++++------ .../rems/database/requirement/Requirement.java | 12 ++++++------ 4 files changed, 16 insertions(+), 31 deletions(-) diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java index b2051c05a..3c034c817 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java @@ -59,7 +59,7 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re patientEnrollmentResource.setResource(patientQuestionnaireResource); patientEnrollmentResource.setId("turalio-patient-enrollment"); remsFhirRepository.save(patientEnrollmentResource); - patientEnrollmentRequirement.setResource(patientEnrollmentResource); + patientEnrollmentRequirement.setRequirement(patientEnrollmentResource); patientEnrollmentRequirement.setDescription("complete patient enrollment questionnaire"); patientEnrollmentRequirement.setDrug(turalio); turalio.addRequirement(patientEnrollmentRequirement); @@ -73,7 +73,7 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re prescriberKnowledgeResource.setResource(prescriberKnowledgeQuestionnaireResource); prescriberKnowledgeResource.setId("turalio-prescriber-knowledge-check"); remsFhirRepository.save(prescriberKnowledgeResource); - prescriberCertificationRequirement.setResource(prescriberKnowledgeResource); + prescriberCertificationRequirement.setRequirement(prescriberKnowledgeResource); prescriberCertificationRequirement.setDescription("complete prescriber knowledge check"); // prescriber enrollment form requirement @@ -85,7 +85,7 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re prescriberEnrollmentResource.setResource(prescriberQuestionnaireResource); prescriberEnrollmentResource.setId("turalio-prescriber-enrollment"); remsFhirRepository.save(prescriberEnrollmentResource); - prescriberEnrollmentRequirement.setResource(prescriberEnrollmentResource); + prescriberEnrollmentRequirement.setRequirement(prescriberEnrollmentResource); prescriberEnrollmentRequirement.setDescription("complete prescriber enrollment questionnaire"); prescriberEnrollmentRequirement.setDrug(turalio); prescriberEnrollmentRequirement.addChild(prescriberCertificationRequirement); diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java index bebc0a60b..5cb179410 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java @@ -3,8 +3,6 @@ import java.util.ArrayList; import java.util.List; import javax.persistence.*; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; import javax.persistence.Column; @@ -29,9 +27,6 @@ public class Rems { @Column(name = "status", nullable = false, length = 100) private String status; - @Column(name = "createdAt", nullable = false) - private String createdAt; - @Type(type = "json") @Column(columnDefinition = "json", name = "resource", nullable = false, length = 10000000) private JsonNode resource; @@ -39,9 +34,7 @@ public class Rems { @OneToMany(mappedBy="remsRequest", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List metRequirements = new ArrayList<>(); - public void Rems() { - this.createdAt = ZonedDateTime.now().format(DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" )); - } + public void Rems() {} public String getCase_number() { return this.case_number; @@ -71,14 +64,6 @@ public void addMetRequirement(MetRequirement metRequirement) { this.metRequirements.add(metRequirement); } -public String getCreatedAt() { - return createdAt; -} - -public void setCreatedAt(String createdAt) { - this.createdAt = createdAt; -} - public JsonNode getResource() { return this.resource; } diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java index 0b93d3823..2ac9f9dc8 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java @@ -25,9 +25,9 @@ public class MetRequirement { private boolean completed ; // FHIR resource which defines the requirement (task, questionnaire, etc) - @JoinColumn(name = "completedResource", nullable = true) + @JoinColumn(name = "completedRequirement", nullable = true) @OneToOne(fetch = FetchType.LAZY) - private RemsFhir completedResource; + private RemsFhir completedRequirement; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="REQUIREMENT_ID") @@ -52,12 +52,12 @@ public MetRequirement() { this.completed = false; } - public RemsFhir getCompletedResource() { - return this.completedResource; + public RemsFhir getCompletedRequirement() { + return this.completedRequirement; } - public void setCompletedResource(RemsFhir requirement) { - this.completedResource = requirement; + public void setCompletedRequirement(RemsFhir requirement) { + this.completedRequirement = requirement; } public String getCreatedAt() { diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java index ca6d0b975..a97fa22e3 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java @@ -24,9 +24,9 @@ public class Requirement { private String description; // FHIR resource which defines the requirement (task, questionnaire, etc) - @JoinColumn(name = "resource", nullable = false) + @JoinColumn(name = "requirement", nullable = false) @OneToOne - private RemsFhir resource; + private RemsFhir requirement; @OneToMany(mappedBy="requirement") private List metRequirements = new ArrayList<>(); @@ -48,12 +48,12 @@ public Requirement() { this.createdAt = ZonedDateTime.now().format(DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" )); } - public RemsFhir getResource() { - return this.resource; + public RemsFhir getRequirement() { + return this.requirement; } - public void setResource(RemsFhir resource) { - this.resource = resource; + public void setRequirement(RemsFhir requirement) { + this.requirement = requirement; } public String getCreatedAt() { From e231aca1ab6a809b73ef7a602aecf2fde9aff3f3 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Wed, 1 Jun 2022 14:01:13 -0400 Subject: [PATCH 6/8] db visualizer --- server/src/main/resources/application.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index f4e8084e2..e4671c347 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -2,6 +2,8 @@ spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation: true spring: + h2: + console.enabled: true thymeleaf: cache: false datasource: From f8e6c1434b67cfcfcc0d8ab6fd73404d207657f4 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Mon, 6 Jun 2022 14:43:31 -0400 Subject: [PATCH 7/8] db updates --- .../davinci/endpoint/rems/DatabaseInit.java | 40 ++- .../rems/controller/RemsController.java | 16 +- .../endpoint/rems/database/drugs/Drug.java | 2 +- .../endpoint/rems/database/rems/Rems.java | 2 +- .../database/requirement/MetRequirement.java | 15 +- .../database/requirement/Requirement.java | 16 +- ...uestionnaire-R4-Prescriber-Enrollment.json | 330 +++++++++++++++++ ...re-R4-Prescriber-Knowledge-Assessment.json | 333 ++++++++++++++++++ 8 files changed, 716 insertions(+), 38 deletions(-) create mode 100644 server/src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/Questionnaire-R4-Prescriber-Enrollment.json create mode 100644 server/src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/Questionnaire-R4-Prescriber-Knowledge-Assessment.json diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java index 3c034c817..1cb358a68 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/DatabaseInit.java @@ -49,6 +49,8 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re turalio.setId("turalio"); turalio.setCodeSystem("http://www.nlm.nih.gov/research/umls/rxnorm"); turalio.setCode("2183126"); + repository.save(turalio);; + // patient enrollment form requirement String patientQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); @@ -59,25 +61,13 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re patientEnrollmentResource.setResource(patientQuestionnaireResource); patientEnrollmentResource.setId("turalio-patient-enrollment"); remsFhirRepository.save(patientEnrollmentResource); - patientEnrollmentRequirement.setRequirement(patientEnrollmentResource); + patientEnrollmentRequirement.setResource(patientEnrollmentResource); patientEnrollmentRequirement.setDescription("complete patient enrollment questionnaire"); patientEnrollmentRequirement.setDrug(turalio); - turalio.addRequirement(patientEnrollmentRequirement); - - // prescriber knowledge assessment / certification sub-requirement - String prescriberKnowledgeQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); - Requirement prescriberCertificationRequirement = new Requirement(); - RemsFhir prescriberKnowledgeResource = new RemsFhir(); - prescriberKnowledgeResource.setResourceType(ResourceType.Questionnaire.toString()); - JsonNode prescriberKnowledgeQuestionnaireResource = JacksonUtil.toJsonNode(prescriberKnowledgeQuestionnaire); - prescriberKnowledgeResource.setResource(prescriberKnowledgeQuestionnaireResource); - prescriberKnowledgeResource.setId("turalio-prescriber-knowledge-check"); - remsFhirRepository.save(prescriberKnowledgeResource); - prescriberCertificationRequirement.setRequirement(prescriberKnowledgeResource); - prescriberCertificationRequirement.setDescription("complete prescriber knowledge check"); + requirementRepository.save(patientEnrollmentRequirement); // prescriber enrollment form requirement - String prescriberQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/fhir/Questionnaire-R4-DrugHasREMS.json", Charset.defaultCharset()); + String prescriberQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/Questionnaire-R4-Prescriber-Enrollment.json", Charset.defaultCharset()); Requirement prescriberEnrollmentRequirement = new Requirement(); RemsFhir prescriberEnrollmentResource = new RemsFhir(); prescriberEnrollmentResource.setResourceType(ResourceType.Questionnaire.toString()); @@ -85,13 +75,25 @@ CommandLineRunner initDatabase(DrugsRepository repository, RemsFhirRepository re prescriberEnrollmentResource.setResource(prescriberQuestionnaireResource); prescriberEnrollmentResource.setId("turalio-prescriber-enrollment"); remsFhirRepository.save(prescriberEnrollmentResource); - prescriberEnrollmentRequirement.setRequirement(prescriberEnrollmentResource); + prescriberEnrollmentRequirement.setResource(prescriberEnrollmentResource); prescriberEnrollmentRequirement.setDescription("complete prescriber enrollment questionnaire"); prescriberEnrollmentRequirement.setDrug(turalio); - prescriberEnrollmentRequirement.addChild(prescriberCertificationRequirement); - turalio.addRequirement(prescriberEnrollmentRequirement); + requirementRepository.save(prescriberEnrollmentRequirement); + + // prescriber knowledge assessment / certification sub-requirement + String prescriberKnowledgeQuestionnaire = readFile("src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/Questionnaire-R4-Prescriber-Knowledge-Assessment.json", Charset.defaultCharset()); + Requirement prescriberCertificationRequirement = new Requirement(); + RemsFhir prescriberKnowledgeResource = new RemsFhir(); + prescriberKnowledgeResource.setResourceType(ResourceType.Questionnaire.toString()); + JsonNode prescriberKnowledgeQuestionnaireResource = JacksonUtil.toJsonNode(prescriberKnowledgeQuestionnaire); + prescriberKnowledgeResource.setResource(prescriberKnowledgeQuestionnaireResource); + prescriberKnowledgeResource.setId("turalio-prescriber-knowledge-check"); + remsFhirRepository.save(prescriberKnowledgeResource); + prescriberCertificationRequirement.setResource(prescriberKnowledgeResource); + prescriberCertificationRequirement.setDescription("complete prescriber knowledge check"); + prescriberCertificationRequirement.setParent(prescriberEnrollmentRequirement); + requirementRepository.save(prescriberCertificationRequirement); - repository.save(turalio);; }; } } \ No newline at end of file diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java index 779e7a00c..6a82297db 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.vladmihalcea.hibernate.type.json.internal.JacksonUtil; import org.hl7.davinci.endpoint.rems.database.requirement.MetRequirement; +import org.hl7.davinci.endpoint.rems.database.requirement.MetRequirementRepository; import org.hl7.davinci.endpoint.rems.database.requirement.Requirement; import org.hl7.davinci.endpoint.Application; @@ -52,6 +53,9 @@ public class RemsController { @Autowired private RemsRepository remsRepository; + @Autowired + private MetRequirementRepository metRequirementsRepository; + @GetMapping(value = "/drug/{id}") @CrossOrigin public ResponseEntity getRequirements(HttpServletRequest request, @PathVariable String id) throws IOException { @@ -113,18 +117,20 @@ public ResponseEntity postRems(@RequestBody String jsonData) { remsRequest.setCase_number(id); remsRequest.setStatus("Pending"); remsRequest.setResource(remsObject); + remsRepository.save(remsRequest); - // sub requirements don't seem to be working, this loop will need to change to handle multiple levels of requirement conditions + // this loop needs to change to handle multiple levels of sub-requirement conditions + // this loop needs to also handle parsing out resources for each requirement - may need to be separate endpoints for (Requirement requirement : drug.getRequirements()) { MetRequirement metReq = new MetRequirement(); metReq.setRequirement(requirement); - remsRequest.addMetRequirement(metReq); + metReq.setRemsRequest(remsRequest); + metRequirementsRepository.save(metReq); } - - remsRepository.save(remsRequest); + Rems remsReturn = remsRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, id + " not found")); updateRemsRequestStatusInBackground(id); - return ResponseEntity.ok().body(remsRequest); + return ResponseEntity.ok().body(remsReturn); } diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/Drug.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/Drug.java index ace9fd834..0ec47c097 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/Drug.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/drugs/Drug.java @@ -24,7 +24,7 @@ public class Drug { @Column(name = "createdAt", nullable = false) private String createdAt; - @OneToMany(mappedBy="drug", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @OneToMany(mappedBy="drug", fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List requirements = new ArrayList<>(); public Drug() { diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java index 5cb179410..b59975ac6 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/rems/Rems.java @@ -31,7 +31,7 @@ public class Rems { @Column(columnDefinition = "json", name = "resource", nullable = false, length = 10000000) private JsonNode resource; - @OneToMany(mappedBy="remsRequest", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @OneToMany(mappedBy="remsRequest", fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List metRequirements = new ArrayList<>(); public void Rems() {} diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java index 2ac9f9dc8..56a64a356 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/MetRequirement.java @@ -26,10 +26,10 @@ public class MetRequirement { // FHIR resource which defines the requirement (task, questionnaire, etc) @JoinColumn(name = "completedRequirement", nullable = true) - @OneToOne(fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.EAGER) private RemsFhir completedRequirement; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name="REQUIREMENT_ID") @JsonIgnore private Requirement requirement; @@ -39,7 +39,7 @@ public class MetRequirement { @JsonIgnore private Rems remsRequest; - @OneToMany(mappedBy="parentMetRequirement", fetch = FetchType.LAZY) + @OneToMany(mappedBy="parentMetRequirement", fetch = FetchType.EAGER) private List childMetRequirements = new ArrayList<>(); @ManyToOne @@ -49,7 +49,14 @@ public class MetRequirement { public MetRequirement() { this.createdAt = ZonedDateTime.now().format(DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" )); - this.completed = false; + this.completed = false; } + + public Rems getRemsRequest() { + return this.remsRequest; + } + + public void setRemsRequest(Rems request) { + this.remsRequest = request; } public RemsFhir getCompletedRequirement() { diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java index a97fa22e3..f9efa8bf5 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/database/requirement/Requirement.java @@ -24,9 +24,9 @@ public class Requirement { private String description; // FHIR resource which defines the requirement (task, questionnaire, etc) - @JoinColumn(name = "requirement", nullable = false) + @JoinColumn(name = "resource", nullable = false) @OneToOne - private RemsFhir requirement; + private RemsFhir resource; @OneToMany(mappedBy="requirement") private List metRequirements = new ArrayList<>(); @@ -36,10 +36,10 @@ public class Requirement { @JsonIgnore private Drug drug; - @OneToMany(mappedBy="parentRequirement", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @OneToMany(mappedBy="parentRequirement", fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List childRequirements = new ArrayList<>(); - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name="PARENT_REQUIREMENT") @JsonIgnore private Requirement parentRequirement; @@ -48,12 +48,12 @@ public Requirement() { this.createdAt = ZonedDateTime.now().format(DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" )); } - public RemsFhir getRequirement() { - return this.requirement; + public RemsFhir getResource() { + return this.resource; } - public void setRequirement(RemsFhir requirement) { - this.requirement = requirement; + public void setResource(RemsFhir resource) { + this.resource = resource; } public String getCreatedAt() { diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/Questionnaire-R4-Prescriber-Enrollment.json b/server/src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/Questionnaire-R4-Prescriber-Enrollment.json new file mode 100644 index 000000000..786ea90f6 --- /dev/null +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/Questionnaire-R4-Prescriber-Enrollment.json @@ -0,0 +1,330 @@ +{ + "resourceType": "Questionnaire", + "id": "TuralioPrescriberEnrollmentForm", + "name": "TuralioPrescriberEnrollmentForm", + "title": "Turalio REMS Prescriber Enrollment Form", + "status": "draft", + "subjectType": [ + "Practitioner" + ], + "date": "2022-05-28", + "publisher": "FDA-REMS", + "item": [ + { + "linkId": "1", + "type": "group", + "text": "Prescriber Information", + "item": [ + { + "linkId": "1.1", + "text": "First Name", + "type": "string", + "required": true + }, + { + "linkId": "1.2", + "text": "Last Name", + "type": "string", + "required": true + }, + { + "linkId": "1.3", + "text": "Middle Initial", + "type": "string", + "required": false + }, + { + "linkId": "1.4", + "text": "Credentials", + "type": "open-choice", + "required": true, + "answerOption": [ + { + "valueCoding": { + "code": "MD", + "display": "MD" + } + }, + { + "valueCoding": { + "code": "DO", + "display": "DO" + } + }, + { + "valueCoding": { + "code": "NP", + "display": "NP" + } + }, + { + "valueCoding": { + "code": "PA", + "display": "PA" + } + }, + { + "valueCoding": { + "code": "Other", + "display": "Other" + } + } + ] + }, + { + "linkId": "1.5", + "text": "Specialty", + "type": "open-choice", + "required": true, + "answerOption": [ + { + "valueCoding": { + "code": "Oncolgy", + "display": "Oncology" + } + }, + { + "valueCoding": { + "code": "Orthopedics", + "display": "Orthopedics" + } + }, + { + "valueCoding": { + "code": "Other", + "display": "Other" + } + } + ] + }, + { + "linkId": "1.6", + "text": "National Provider Identifier (NPI) #", + "type": "string", + "required": true + }, + { + "linkId": "1.7", + "text": "State License #", + "type": "string", + "required": false + }, + { + "linkId": "1.8", + "text": "Practice/Facility Name", + "type": "string", + "required": false + }, + { + "linkId": "1.9", + "text": "Street Address", + "type": "string", + "required": true + }, + { + "linkId": "1.10", + "text": "City", + "type": "string", + "required": true + }, + { + "linkId": "1.11", + "text": "State", + "type": "string", + "required": true + }, + { + "linkId": "1.12", + "text": "ZIP Code", + "type": "string", + "required": true + }, + { + "linkId": "1.13", + "text": "Office Phone Number", + "type": "string", + "required": true + }, + { + "linkId": "1.14", + "text": "Office Fax Number", + "type": "string", + "required": true + }, + { + "linkId": "1.15", + "text": "E-Mail", + "type": "string", + "required": true + }, + { + "linkId": "1.16", + "text": "Perfered Method of Communication", + "type": "open-choice", + "required": false, + "answerOption": [ + { + "valueCoding": { + "code": "Fax", + "display": "Fax" + } + }, + { + "valueCoding": { + "code": "Email", + "display": "Email" + } + }, + { + "valueCoding": { + "code": "Phone", + "display": "Phone" + } + } + ] + }, + { + "linkId": "1.17", + "text": "Perferred Time of Contact", + "type": "open-choice", + "required": false, + "answerOption": [ + { + "valueCoding": { + "code": "AM", + "display": "AM" + } + }, + { + "valueCoding": { + "code": "PM", + "display": "PM" + } + } + ] + } + + ] + }, + { + "linkId": "2", + "type": "group", + "text": "Office Contact Information", + "item": [ + { + "linkId": "2.1", + "text": "Prescribers may grant administrative rights to two (2) Office Contacts which allow them to view, edit, and initiate paperwork related to the TURALIO REMS via the REMS Portal.", + "type": "display" + }, + { + "linkId": "2.2", + "text": "I, the prescriber, grant administrative rights to the office contact(s) listed below and understand that I must review all paperwork and sign prior to submitting to the REMS.", + "type": "display" + }, + { + "linkId": "2.3", + "type": "group", + "text": "Office Contact #1 (Optional)", + "item": [ + { + "linkId": "2.3.1", + "text": "First Name", + "type": "string", + "required": false + }, + { + "linkId": "2.3.2", + "text": "Last Name", + "type": "string", + "required": false + }, + { + "linkId": "2.3.3", + "text": "Office Phone Number", + "type": "string", + "required": false + }, + { + "linkId": "2.3.4", + "text": "Office Fax Number", + "type": "string", + "required": false + }, + { + "linkId": "2.3.5", + "text": "Email", + "type": "string", + "required": false + } + ] + }, + { + "linkId": "2.4", + "type": "group", + "text": "Office Contact #2 (Optional)", + "item": [ + { + "linkId": "2.4.1", + "text": "First Name", + "type": "string", + "required": false + }, + { + "linkId": "2.4.2", + "text": "Last Name", + "type": "string", + "required": false + }, + { + "linkId": "2.4.3", + "text": "Office Phone Number", + "type": "string", + "required": false + }, + { + "linkId": "2.4.4", + "text": "Office Fax Number", + "type": "string", + "required": false + }, + { + "linkId": "2.4.5", + "text": "Email", + "type": "string", + "required": false + } + ] + }, + { + "linkId": "2.5", + "text": "Office Contacts can be updated by visiting www.turaliorems.com or contacting the TURALIO REMS Coordinating Center at 1-833-TURALIO (833-887-2546).", + "type": "display" + } + ] + }, + { + "linkId": "3", + "type": "group", + "text": "Prescriber Attestations", + "item": [ + { + "linkId": "3.1", + "text": "By signing this form, I agree TURALIO is only available through the TURALIO REMS and I agree to comply with the following TURALIO REMS requirements: \n\n I have: \n - Reviewed the Prescribing Information, Program Overview and Prescriber Training. \n - Successfully completed the Prescriber Knowledge Assessment and submitted it to the TURALIO REMS. \n\n Before treatment initiation and with the first dose of TURALIO: \n - I understand that I should counsel the patient on the risk of serious and potentially fatal liver injury, and liver test monitoring at baseline and periodically during treatment. \n - I must assess the patient by obtaining baseline liver tests. I must submit the results of the assessment on the Patient Enrollment Form. \n - I must enroll patients in the TURALIO REMS by completing and submitting the Patient Enrollment Form. \n\n During treatment with TURALIO: \n - I must assess the patient by obtaining liver tests weekly for the first 8 weeks, then every 2 weeks for 1 month, then every 3 months and modify the dose of TURALIO as needed in accordance with the Prescribing Information. \n - I must prescribe no more than a 30 days supply for each of the first 3 months of treatment. \n - I must complete the Patient Status Form every month for the first 3 months of treatment, at months 6, 9, and 12 and then every 6 months thereafter while the patient receives TURALIO. \n\n At all times: \n - I must report adverse events of serious and potentially fatal liver injury by submitting the Liver Adverse Event Reporting Form. \n - I understand that Daiichi Sankyo, Inc. and/or its agents may contact me by phone, mail or email to provide or obtain additional information related to the REMS program, including details regarding any reported liver adverse events. \n", + "type": "display", + "readOnly": true + }, + { + "linkId": "3.2", + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/sub-questionnaire", + "valueCanonical": "questionnaire/provider-signature" + } + ], + "type": "display" + } + + ] + } + ] +} \ No newline at end of file diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/Questionnaire-R4-Prescriber-Knowledge-Assessment.json b/server/src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/Questionnaire-R4-Prescriber-Knowledge-Assessment.json new file mode 100644 index 000000000..b1071a2b2 --- /dev/null +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/resources/Turalio/Questionnaire-R4-Prescriber-Knowledge-Assessment.json @@ -0,0 +1,333 @@ +{ + "resourceType": "Questionnaire", + "id": "TuralioPrescriberKnowledgeAssessment", + "name": "TuralioPrescriberKnowledgeAssessment", + "title": "Turalio REMS Prescriber Knowledge Assessment", + "status": "draft", + "subjectType": [ + "Prescriber" + ], + "date": "2022-05-28", + "publisher": "FDA-REMS", + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/cqf-library", + "valueCanonical": "http://hl7.org/fhir/us/davinci-dtr/Library/BasicPractitionerInfo-prepopulation" + } + ], + "item": [ + { + "linkId": "1", + "type": "group", + "text": "Prescriber Information", + "item": [ + { + "linkId": "1.1", + "text": "First Name", + "type": "string", + "required": true, + "extension": [ + { + "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression", + "valueExpression": { + "language": "text/cql", + "expression": "\"BasicClinicalInfoPrepopulation\".EncounterProviderFirstName" + } + }, + { + "url" : "http://hl7.org/fhir/StructureDefinition/minLength", + "valueInteger": 2 + } + ] + }, + { + "linkId": "1.2", + "text": "Last Name", + "type": "string", + "required": true, + "extension": [ + { + "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression", + "valueExpression": { + "language": "text/cql", + "expression": "\"BasicClinicalInfoPrepopulation\".EncounterProviderLastName" + } + }, + { + "url" : "http://hl7.org/fhir/StructureDefinition/minLength", + "valueInteger": 2 + } + ] + }, + { + "linkId": "1.3", + "text": "Middle Initial", + "type": "string", + "required": false, + "extension": [ + { + "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression", + "valueExpression": { + "language": "text/cql", + "expression": "\"BasicClinicalInfoPrepopulation\".EncounterProviderMiddleInitial" + } + } + ] + }, + { + "linkId": "1.4", + "text": "National Provider Identifier (NPI) #", + "type": "string", + "required": true, + "extension": [ + { + "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression", + "valueExpression": { + "language": "text/cql", + "expression": "\"BasicClinicalInfoPrepopulation\".EncounterProviderNPI" + } + } + ] + }, + { + "linkId": "1.5", + "text": "Phone Number", + "type": "string", + "required": true + }, + { + "linkId": "1.6", + "text": "Fax Number", + "type": "string", + "required": true + }, + { + "linkId": "1.7", + "text": "Email", + "type": "string", + "required": true + } + ] + }, + { + "linkId": "2", + "type": "group", + "text": "Knowledge Assessment: Questions 1-9", + "item": [ + { + "linkId": "2.1", + "text": "1. TURALIO is indicated for the treatment of adult patients with symptomatic tenosynovial giant cell tumor (TGCT) associated with severe morbidity or functional limitations and not amenable to improvement with surgery.", + "type": "open-choice", + "answerOption": [ + { + "valueCoding": { + "code": "true", + "display": "True" + } + }, + { + "valueCoding": { + "code": "false", + "display": "False" + } + } + ] + }, + { + "linkId": "2.2", + "text": "2. TURALIO is contraindicated in patients with hepatic impairment.", + "type": "open-choice", + "answerOption": [ + { + "valueCoding": { + "code": "true", + "display": "True" + } + }, + { + "valueCoding": { + "code": "false", + "display": "False" + } + } + ] + }, + { + "linkId": "2.3", + "text": "3. To prescribe TURALIO, I must enroll each patient in the TURALIO REMS by completing a Patient Enrollment Form with the patient and submitting it to the TURALIO REMS.", + "type": "open-choice", + "answerOption": [ + { + "valueCoding": { + "code": "true", + "display": "True" + } + }, + { + "valueCoding": { + "code": "false", + "display": "False" + } + } + ] + }, + { + "linkId": "2.4", + "text": "4. Before treating each patient with TURALIO, I must", + "type": "open-choice", + "answerOption": [ + { + "valueCoding": { + "code": "Become certified in the TURALIO REMS", + "display": "Become certified in the TURALIO REMS" + } + }, + { + "valueCoding": { + "code": "Counsel the patient regarding the risk of serious and potentially fatal liver injury associated with TURALIO", + "display": "Counsel the patient regarding the risk of serious and potentially fatal liver injury associated with TURALIO" + } + }, + { + "valueCoding": { + "code": "Obtain and review baseline liver tests", + "display": "Obtain and review baseline liver tests" + } + }, + { + "valueCoding": { + "code": "All of the above", + "display": "All of the above" + } + } + ] + }, + { + "linkId": "2.5", + "text": "5. One of the primary counseling messages I must tell my patients before prescribing TURALIO is", + "type": "open-choice", + "answerOption": [ + { + "valueCoding": { + "code": "Do not take TURALIO if you have vision issues", + "display": "Do not take TURALIO if you have vision issues" + } + }, + { + "valueCoding": { + "code": "Patients with renal impairment should not start TURALIO at a reduced dose", + "display": "Patients with renal impairment should not start TURALIO at a reduced dose" + } + }, + { + "valueCoding": { + "code": "There is a risk of liver injury associated with TURALIO and liver monitoring is required prior to treatment initiation and periodically while taking TURALIO", + "display": "There is a risk of liver injury associated with TURALIO and liver monitoring is required prior to treatment initiation and periodically while taking TURALIO" + } + }, + { + "valueCoding": { + "code": "None of the above", + "display": "None of the above" + } + } + ] + }, + { + "linkId": "2.6", + "text": "6. I am required to educate my patients on the signs and symptoms of liver injury and the need to notify me should they experience them.", + "type": "open-choice", + "answerOption": [ + { + "valueCoding": { + "code": "true", + "display": "True" + } + }, + { + "valueCoding": { + "code": "false", + "display": "False" + } + } + ] + }, + { + "linkId": "2.7", + "text": "7. If any dose modifications are required, they must be done in increments of 200 mg.", + "type": "open-choice", + "answerOption": [ + { + "valueCoding": { + "code": "true", + "display": "True" + } + }, + { + "valueCoding": { + "code": "false", + "display": "False" + } + } + ] + }, + { + "linkId": "2.8", + "text": "8. After treatment initiation, I need to monitor liver tests weekly for the first 8 weeks of treatment, every 2 weeks for the next month, and every 3 months thereafter.", + "type": "open-choice", + "answerOption": [ + { + "valueCoding": { + "code": "true", + "display": "True" + } + }, + { + "valueCoding": { + "code": "false", + "display": "False" + } + } + ] + }, + { + "linkId": "2.9", + "text": "9. I must complete a Patient Status Form for each patient taking TURALIO and submit it to the TURALIO REMS:", + "type": "open-choice", + "answerOption": [ + { + "valueCoding": { + "code": "Every month during treatment", + "display": "Every month during treatment" + } + }, + { + "valueCoding": { + "code": "Weekly for 8 weeks of treatment, every 2 weeks for the next month, and every 3 months thereafter", + "display": "Weekly for 8 weeks of treatment, every 2 weeks for the next month, and every 3 months thereafter" + } + }, + { + "valueCoding": { + "code": "Every month for the first 3 months of treatment, month 6, month 9, and month 12 of treatment, and every 6 months thereafter", + "display": "Every month for the first 3 months of treatment, month 6, month 9, and month 12 of treatment, and every 6 months thereafter" + } + }, + { + "valueCoding": { + "code": "Every month for the first 6 months of treatment and every 6 months thereafter", + "display": "Every month for the first 6 months of treatment and every 6 months thereafter" + } + }, + { + "valueCoding": { + "code": "None of the above", + "display": "None of the above" + } + } + ] + } + ] + } + ] +} \ No newline at end of file From 0b466456e5c0ceedec0a93e44b756d8985d08d81 Mon Sep 17 00:00:00 2001 From: kghoreshi Date: Mon, 6 Jun 2022 15:37:00 -0400 Subject: [PATCH 8/8] save metreq to rems and rems to database --- .../davinci/endpoint/rems/controller/RemsController.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java b/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java index 6a82297db..2564fba7f 100644 --- a/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java +++ b/server/src/main/java/org/hl7/davinci/endpoint/rems/controller/RemsController.java @@ -125,12 +125,12 @@ public ResponseEntity postRems(@RequestBody String jsonData) { MetRequirement metReq = new MetRequirement(); metReq.setRequirement(requirement); metReq.setRemsRequest(remsRequest); + remsRequest.addMetRequirement(metReq); metRequirementsRepository.save(metReq); } - - Rems remsReturn = remsRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, id + " not found")); + remsRepository.save(remsRequest); updateRemsRequestStatusInBackground(id); - return ResponseEntity.ok().body(remsReturn); + return ResponseEntity.ok().body(remsRequest); }