From 6747b5dabfececf64ec596ec830f979404445f47 Mon Sep 17 00:00:00 2001 From: vlad Date: Wed, 17 Jan 2018 15:57:08 -0800 Subject: TRIAL-192, TRIAL-159 Trial model simplification to support Trial Synchronizer removal and the InterventionType's update for TRIAL-159 --- .../driver/pdsuidomain/entities/Intervention.scala | 16 +---- .../driver/pdsuidomain/entities/ScrapedTrial.scala | 81 ---------------------- .../xyz/driver/pdsuidomain/entities/Trial.scala | 16 ++++- .../pdsuidomain/fakes/entities/trialcuration.scala | 2 - .../driver/pdsuidomain/formats/json/trial.scala | 4 ++ .../services/ScrapedTrialsService.scala | 53 -------------- .../driver/pdsuidomain/services/TrialService.scala | 7 +- .../services/fake/FakeTrialService.scala | 12 +++- .../services/rest/RestTrialService.scala | 24 +++++++ 9 files changed, 59 insertions(+), 156 deletions(-) delete mode 100644 src/main/scala/xyz/driver/pdsuidomain/entities/ScrapedTrial.scala delete mode 100644 src/main/scala/xyz/driver/pdsuidomain/services/ScrapedTrialsService.scala diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala index 5e743b7..be51e4f 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala @@ -16,12 +16,6 @@ sealed trait InterventionType { object InterventionType { - final case object RadiationTherapy extends InterventionType { - val id: LongId[InterventionType] = LongId[InterventionType](1) - val name: String = "Radiation therapy" - val deliveryMethods: Set[DeliveryMethod] = commonMethods - } - final case object Chemotherapy extends InterventionType { val id: LongId[InterventionType] = LongId[InterventionType](2) val name: String = "Chemotherapy" @@ -40,12 +34,6 @@ object InterventionType { val deliveryMethods: Set[DeliveryMethod] = commonMethods } - final case object Surgery extends InterventionType { - val id: LongId[InterventionType] = LongId[InterventionType](5) - val name: String = "Surgery" - val deliveryMethods: Set[DeliveryMethod] = commonMethods - } - final case object HormoneTherapy extends InterventionType { val id: LongId[InterventionType] = LongId[InterventionType](6) val name: String = "Hormone therapy" @@ -152,7 +140,7 @@ object InterventionType { } } - val commonMethods = Set[DeliveryMethod]( + val commonMethods: Set[DeliveryMethod] = Set[DeliveryMethod]( IntravenousInfusionIV, IntramuscularInjection, SubcutaneousInjection, @@ -166,11 +154,9 @@ object InterventionType { ) val All: Map[LongId[InterventionType], InterventionType] = Map[LongId[InterventionType], InterventionType]( - LongId[InterventionType](1) -> RadiationTherapy, LongId[InterventionType](2) -> Chemotherapy, LongId[InterventionType](3) -> TargetedTherapy, LongId[InterventionType](4) -> Immunotherapy, - LongId[InterventionType](5) -> Surgery, LongId[InterventionType](6) -> HormoneTherapy, LongId[InterventionType](7) -> Other, LongId[InterventionType](8) -> Radiation, diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/ScrapedTrial.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/ScrapedTrial.scala deleted file mode 100644 index e7ee1cb..0000000 --- a/src/main/scala/xyz/driver/pdsuidomain/entities/ScrapedTrial.scala +++ /dev/null @@ -1,81 +0,0 @@ -package xyz.driver.pdsuidomain.entities - -import java.time.LocalDateTime -import java.util.UUID - -import xyz.driver.pdsuicommon.logging._ -import xyz.driver.pdsuicommon.domain.UuidId - -final case class ScrapedStudyDesign(value: String) - -final case class ScrapedOverall(affiliation: String, - status: String, - facilityName: Option[String], - firstName: Option[String], - lastName: Option[String], - phone: Option[String], - phoneExt: Option[String], - email: Option[String], - isBackup: Boolean) - -final case class ScrapedInterventionType(value: String) - -final case class ScrapedIntervention(name: String, - kind: ScrapedInterventionType, - description: Option[String], - isSynonym: Boolean) - -object ScrapedIntervention { - - implicit def toPhiString(x: ScrapedIntervention): PhiString = - phi"ScrapedIntervention(${Unsafe(x.name)})" -} - -final case class ScrapedArm(name: String, kind: Option[String], interventions: Set[ScrapedIntervention]) - -object ScrapedArm { - - implicit def toPhiString(x: ScrapedArm): PhiString = { - import x._ - phi"ScrapedArm(name=${Unsafe(name)}, inverventions=$interventions)" - } -} - -final case class ScrapedTrialChecksum(eligibilityCriteria: String, - briefSummary: String, - detailedDescription: String, - armDescription: String) - -object ScrapedTrialChecksum { - - implicit def toPhiString(x: ScrapedTrialChecksum): PhiString = { - import x._ - phi"ScrapedTrialChecksum(eligibilityCriteria=${Unsafe(eligibilityCriteria)}, briefSummary=${Unsafe(briefSummary)}, " + - phi"detailedDescription=${Unsafe(detailedDescription)}, armDescription=${Unsafe(armDescription)}" - } -} - -object ScrapedTrial { - - implicit def toPhiString(x: ScrapedTrial): PhiString = { - import x._ - phi"ScrapedTrial(rawId=$rawId, nctId=${Unsafe(nctId)}, arms=$arms, checksum=$checksum)" - } -} - -final case class ScrapedTrial(rawId: UuidId[ScrapedTrial], - createdAt: LocalDateTime, - disease: String, - nctId: String, - nctUuid: UUID, - title: Option[String], - startDate: Option[LocalDateTime], - phase: String, - studyDesign: Option[ScrapedStudyDesign], - overall: Set[ScrapedOverall], - // // see ClinicalTrialRaw - // trialHtml: String, - // eligibilityText: String, - lastReviewed: LocalDateTime, - arms: Set[ScrapedArm], - checksum: ScrapedTrialChecksum) diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala index cb75803..2713b4e 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala @@ -49,6 +49,18 @@ object StudyDesign { } } +object TrialCreationRequest { + + implicit def toPhiString(x: TrialCreationRequest): PhiString = phi"${Unsafe(x.toString)}" +} + +final case class TrialCreationRequest(id: UuidId[Trial], + nctId: String, + title: Option[String], + phase: String, + studyDesign: Option[StudyDesign], + lastReviewed: LocalDateTime) + object Trial { sealed trait Status { @@ -67,7 +79,7 @@ object Trial { case object Flagged extends Status case object Archived extends Status - val All = Set[Status]( + val All: Set[Status] = Set[Status]( New, ReviewSummary, Summarized, @@ -79,7 +91,7 @@ object Trial { Archived ) - val AllPrevious = Set[Status](New, ReviewSummary, Summarized, ReviewCriteria) + val AllPrevious: Set[Status] = Set[Status](New, ReviewSummary, Summarized, ReviewCriteria) implicit def toPhiString(x: Status): PhiString = Unsafe(Utils.getClassSimpleName(x.getClass)) } diff --git a/src/main/scala/xyz/driver/pdsuidomain/fakes/entities/trialcuration.scala b/src/main/scala/xyz/driver/pdsuidomain/fakes/entities/trialcuration.scala index 1e4ad51..925a019 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/fakes/entities/trialcuration.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/fakes/entities/trialcuration.scala @@ -137,11 +137,9 @@ object trialcuration { def nextStudyDesign(): StudyDesign = generators.oneOf[StudyDesign](StudyDesign.All: _*) def nextInterventionType(): InterventionType = generators.oneOf[InterventionType]( - RadiationTherapy, Chemotherapy, TargetedTherapy, Immunotherapy, - Surgery, HormoneTherapy, Other, Radiation, diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial.scala index 0b5de6b..7bbdda2 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial.scala @@ -12,6 +12,7 @@ object trial { import DefaultJsonProtocol._ import Trial._ import common._ + import studydesign._ implicit val trialStatusFormat: RootJsonFormat[Status] = new EnumJsonFormat[Status]( "New" -> Status.New, @@ -181,4 +182,7 @@ object trial { case _ => deserializationError(s"Expected Json Object as Trial, but got $json") } + implicit val trialCreationRequestFormat: RootJsonFormat[TrialCreationRequest] = + jsonFormat6(TrialCreationRequest.apply) + } diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/ScrapedTrialsService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/ScrapedTrialsService.scala deleted file mode 100644 index 233495e..0000000 --- a/src/main/scala/xyz/driver/pdsuidomain/services/ScrapedTrialsService.scala +++ /dev/null @@ -1,53 +0,0 @@ -package xyz.driver.pdsuidomain.services - -import xyz.driver.pdsuicommon.error.DomainError -import xyz.driver.pdsuidomain.entities.ScrapedTrial - -import scala.concurrent.Future - -object ScrapedTrialsService { - - sealed trait GetRawTrialReply - object GetRawTrialReply { - type Error = GetRawTrialReply with DomainError - - final case class TrialRawEntity(rawTrial: ScrapedTrial) extends GetRawTrialReply - - case object NotFoundError extends GetRawTrialReply with DomainError.NotFoundError { - override def userMessage: String = "Raw clinical trial not found" - } - } - - sealed trait GetRawTrialOptReply - object GetRawTrialOptReply { - final case class TrialRawEntity(rawTrial: Option[ScrapedTrial]) extends GetRawTrialOptReply - } - - sealed trait GetAllRawTrialsExceptReply - object GetAllRawTrialsExceptReply { - final case class MultipleRawTrials(rawTrials: Seq[ScrapedTrial]) extends GetAllRawTrialsExceptReply - } - - sealed trait GetHtmlForReply - object GetHtmlForReply { - type TrialHtmlMap = Map[String, String] - - /** - * @param trialHtmlMap nctId -> html - */ - final case class HtmlMap(trialHtmlMap: TrialHtmlMap) extends GetHtmlForReply - } -} - -trait ScrapedTrialsService { - - import ScrapedTrialsService._ - - def getRawTrial(nctId: String): Future[GetRawTrialReply] - - def getRawTrialOpt(nctId: String): Future[GetRawTrialOptReply] - - def getAllRawTrialsExcept(nctIds: Seq[String], limit: Int): Future[GetAllRawTrialsExceptReply] - - def getHtmlFor(nctIds: Set[String]): Future[GetHtmlForReply] -} diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/TrialService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/TrialService.scala index 4d61342..9ae1c10 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/services/TrialService.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/services/TrialService.scala @@ -12,7 +12,7 @@ import xyz.driver.pdsuicommon.db._ import xyz.driver.pdsuicommon.domain.StringId import xyz.driver.pdsuicommon.error.DomainError import xyz.driver.pdsuicommon.logging._ -import xyz.driver.pdsuidomain.entities.Trial +import xyz.driver.pdsuidomain.entities.{Trial, TrialCreationRequest} import xyz.driver.pdsuidomain.entities.export.trial.ExportTrialWithLabels import scala.concurrent.Future @@ -121,6 +121,9 @@ trait TrialService { def getPdfSource(trialId: StringId[Trial])( implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo]): Future[Source[ByteString, NotUsed]] + def getHtmlSource(trialId: StringId[Trial])( + implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo]): Future[Source[ByteString, NotUsed]] + def getAll(filter: SearchFilterExpr = SearchFilterExpr.Empty, sorting: Option[Sorting] = None, pagination: Option[Pagination] = None)( @@ -150,4 +153,6 @@ trait TrialService { def unassign(origTrial: Trial)( implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo]): Future[UpdateReply] + def addTrial(trial: TrialCreationRequest)( + implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo]): Future[Trial] } diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/fake/FakeTrialService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/fake/FakeTrialService.scala index 7d44309..221e56c 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/services/fake/FakeTrialService.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/services/fake/FakeTrialService.scala @@ -13,7 +13,7 @@ import xyz.driver.entities.users.AuthUserInfo import xyz.driver.pdsuicommon.db._ import xyz.driver.pdsuicommon.domain.{LongId, StringId, UuidId} import xyz.driver.pdsuidomain.entities.export.trial.{ExportTrialArm, ExportTrialLabelCriterion, ExportTrialWithLabels} -import xyz.driver.pdsuidomain.entities.{Criterion, EligibilityArm, Trial} +import xyz.driver.pdsuidomain.entities._ import xyz.driver.pdsuidomain.services.TrialService import scala.concurrent.Future @@ -52,7 +52,12 @@ class FakeTrialService extends TrialService { def getPdfSource(trialId: StringId[Trial])( implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo] ): Future[Source[ByteString, NotUsed]] = - Future.failed(new NotImplementedError("fake pdf download is not implemented")) + Future.failed(new NotImplementedError("fake PDF download is not implemented")) + + def getHtmlSource(trialId: StringId[Trial])( + implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo] + ): Future[Source[ByteString, NotUsed]] = + Future.failed(new NotImplementedError("fake HTML download is not implemented")) def getAll(filter: SearchFilterExpr = SearchFilterExpr.Empty, sorting: Option[Sorting] = None, @@ -125,4 +130,7 @@ class FakeTrialService extends TrialService { implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo]): Future[UpdateReply] = update(origTrial, origTrial) + def addTrial(newTrial: TrialCreationRequest)( + implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo]): Future[Trial] = + Future.successful(trial) } diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestTrialService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestTrialService.scala index 6650d51..94e1c63 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestTrialService.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestTrialService.scala @@ -73,6 +73,18 @@ class RestTrialService(transport: ServiceTransport, baseUri: Uri)(implicit prote } } + def getHtmlSource(trialId: StringId[Trial])( + implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo] + ): Future[Source[ByteString, NotUsed]] = { + val request = HttpRequest(HttpMethods.GET, endpointUri(baseUri, s"/v1/trial/$trialId/source.html")) + for { + response <- transport.sendRequestGetResponse(requestContext)(request) + reply <- apiResponse[HttpEntity](response) + } yield { + reply.dataBytes.mapMaterializedValue(_ => NotUsed) + } + } + def getAll(filter: SearchFilterExpr = SearchFilterExpr.Empty, sorting: Option[Sorting] = None, pagination: Option[Pagination] = None)( @@ -146,4 +158,16 @@ class RestTrialService(transport: ServiceTransport, baseUri: Uri)(implicit prote def unassign(origTrial: Trial)( implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo]): Future[UpdateReply] = singleAction(origTrial, "unassign") + + override def addTrial(trial: TrialCreationRequest)( + implicit requestContext: AuthorizedServiceRequestContext[AuthUserInfo]): Future[Trial] = { + for { + entity <- Marshal(trial).to[RequestEntity] + request = HttpRequest(HttpMethods.POST, endpointUri(baseUri, s"/v1/trial/${trial.nctId}")).withEntity(entity) + response <- transport.sendRequestGetResponse(requestContext)(request) + reply <- apiResponse[Trial](response) + } yield { + reply + } + } } -- cgit v1.2.3