diff options
Diffstat (limited to 'src/main/scala/xyz/driver/pdsuidomain')
31 files changed, 653 insertions, 63 deletions
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Criterion.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Criterion.scala index 2432251..26ced22 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/entities/Criterion.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Criterion.scala @@ -30,7 +30,7 @@ object Criterion { } } -final case class CriterionArm(criterionId: LongId[Criterion], armId: LongId[Arm]) +final case class CriterionArm(criterionId: LongId[Criterion], armId: LongId[EligibilityArm]) object CriterionArm { diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/EligibilityArm.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/EligibilityArm.scala new file mode 100644 index 0000000..50b49ad --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/EligibilityArm.scala @@ -0,0 +1,42 @@ +package xyz.driver.pdsuidomain.entities + +import java.time.LocalDateTime + +import xyz.driver.entities.patient.CancerType +import xyz.driver.pdsuicommon.domain.{LongId, StringId} +import xyz.driver.pdsuicommon.logging._ + +final case class EligibilityArm(id: LongId[EligibilityArm], + name: String, + originalName: String, + trialId: StringId[Trial], + deleted: Option[LocalDateTime] = None) + +object EligibilityArm { + + implicit def toPhiString(x: EligibilityArm): PhiString = { + import x._ + phi"Arm(id=$id, name=${Unsafe(x.name)}, trialId=${Unsafe(x.trialId)})" + } +} + +final case class EligibilityArmDisease(eligibilityArmId: LongId[EligibilityArm], disease: CancerType) + +object EligibilityArmDisease { + + implicit def toPhiString(x: EligibilityArmDisease): PhiString = { + phi"EligibilityArmDisease(eligibilityArmId=${Unsafe(x.eligibilityArmId)}, disease=${Unsafe(x.disease)})" + } + +} + +final case class EligibilityArmWithDiseases(eligibilityArm: EligibilityArm, + eligibilityArmDiseases: Seq[EligibilityArmDisease]) + +object EligibilityArmWithDiseases { + + implicit def toPhiString(x: EligibilityArmWithDiseases): PhiString = { + import x._ + phi"EligibilityArmWithDiseases(eligibilityArm=$eligibilityArm, eligibilityArmDiseases=$eligibilityArmDiseases)" + } +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala index cc831cd..f02bedc 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala @@ -188,7 +188,7 @@ object InterventionType { } } -final case class InterventionArm(armId: LongId[Arm], interventionId: LongId[Intervention]) +final case class InterventionArm(armId: LongId[SlotArm], interventionId: LongId[Intervention]) object InterventionArm { implicit def toPhiString(x: InterventionArm): PhiString = { diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/SlotArmEligibilityArm.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/SlotArmEligibilityArm.scala new file mode 100644 index 0000000..70114de --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/SlotArmEligibilityArm.scala @@ -0,0 +1,13 @@ +package xyz.driver.pdsuidomain.entities + +import xyz.driver.pdsuicommon.domain.LongId +import xyz.driver.pdsuicommon.logging._ + +final case class SlotArmEligibilityArm(slotArmId: LongId[SlotArm], eligibilityArmId: LongId[EligibilityArm]) + +object SlotArmEligibilityArm { + implicit def toPhiString(x: SlotArmEligibilityArm): PhiString = { + import x._ + phi"SlotArmEligibilityArm(slotArmId=$slotArmId, eligibilityArmId=$eligibilityArmId)" + } +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/SlotArms.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/SlotArms.scala new file mode 100644 index 0000000..932de38 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/SlotArms.scala @@ -0,0 +1,20 @@ +package xyz.driver.pdsuidomain.entities + +import java.time.LocalDateTime + +import xyz.driver.pdsuicommon.domain.{LongId, StringId} +import xyz.driver.pdsuicommon.logging._ + +final case class SlotArm(id: LongId[SlotArm], + name: String, + originalName: String, + trialId: StringId[Trial], + deleted: Option[LocalDateTime] = None) + +object SlotArm { + + implicit def toPhiString(x: SlotArm): PhiString = { + import x._ + phi"Arm(id=$id, name=${Unsafe(x.name)}, trialId=${Unsafe(x.trialId)})" + } +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala index 7584e9c..ac5feef 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala @@ -2,7 +2,6 @@ package xyz.driver.pdsuidomain.entities import java.time.LocalDateTime -import xyz.driver.entities.patient.CancerType import xyz.driver.pdsuicommon.domain.{LongId, StringId, User, UuidId} import xyz.driver.pdsuicommon.logging._ import xyz.driver.pdsuicommon.utils.Utils @@ -69,7 +68,6 @@ final case class Trial(id: StringId[Trial], previousAssignee: Option[StringId[User]], lastActiveUserId: Option[StringId[User]], lastUpdate: LocalDateTime, - disease: CancerType, phase: String, hypothesisId: Option[UuidId[Hypothesis]], studyDesignId: Option[LongId[StudyDesign]], diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialArm.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialArm.scala index 5a9a406..fbac0df 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialArm.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialArm.scala @@ -2,14 +2,14 @@ package xyz.driver.pdsuidomain.entities.export.trial import xyz.driver.pdsuicommon.domain._ import xyz.driver.pdsuicommon.logging._ -import xyz.driver.pdsuidomain.entities.Arm +import xyz.driver.pdsuidomain.entities.EligibilityArm -final case class ExportTrialArm(armId: LongId[Arm], armName: String) +final case class ExportTrialArm(armId: LongId[EligibilityArm], armName: String, diseaseList: Seq[String]) object ExportTrialArm { implicit def toPhiString(x: ExportTrialArm): PhiString = { import x._ - phi"ExportTrialArm(armId=$armId, armName=${Unsafe(armName)})" + phi"ExportTrialArm(armId=$armId, armName=${Unsafe(armName)}, diseaseList=${Unsafe(diseaseList)})" } } diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialLabelCriterion.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialLabelCriterion.scala index 385bbbe..8376e34 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialLabelCriterion.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialLabelCriterion.scala @@ -3,12 +3,12 @@ package xyz.driver.pdsuidomain.entities.export.trial import xyz.driver.entities.labels.Label import xyz.driver.pdsuicommon.domain._ import xyz.driver.pdsuicommon.logging._ -import xyz.driver.pdsuidomain.entities.{Arm, Criterion} +import xyz.driver.pdsuidomain.entities.{Criterion, EligibilityArm} final case class ExportTrialLabelCriterion(criterionId: LongId[Criterion], value: Option[Boolean], labelId: LongId[Label], - armIds: Set[LongId[Arm]], + armIds: Set[LongId[EligibilityArm]], criteria: String, isCompound: Boolean, isDefining: Boolean) diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialWithLabels.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialWithLabels.scala index 3a9434b..3681945 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialWithLabels.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialWithLabels.scala @@ -8,7 +8,6 @@ import xyz.driver.pdsuidomain.entities.Trial final case class ExportTrialWithLabels(nctId: StringId[Trial], trialId: UuidId[Trial], - disease: String, lastReviewed: LocalDateTime, labelVersion: Long, arms: List[ExportTrialArm], @@ -18,7 +17,7 @@ object ExportTrialWithLabels { implicit def toPhiString(x: ExportTrialWithLabels): PhiString = { import x._ - phi"TrialWithLabels(nctId=$nctId, trialId=$trialId, disease=${Unsafe(disease)}, " + + phi"TrialWithLabels(nctId=$nctId, trialId=$trialId}, " + phi"lastReviewed=$lastReviewed, labelVersion=${Unsafe(labelVersion)}, arms=$arms, criteria=$criteria)" } } diff --git a/src/main/scala/xyz/driver/pdsuidomain/fakes/entities/export.scala b/src/main/scala/xyz/driver/pdsuidomain/fakes/entities/export.scala index a3ba562..1fe7533 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/fakes/entities/export.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/fakes/entities/export.scala @@ -1,22 +1,24 @@ package xyz.driver.pdsuidomain.fakes.entities import xyz.driver.entities.labels.Label -import xyz.driver.pdsuidomain.entities.{Arm, Criterion, Trial} import xyz.driver.pdsuidomain.entities.export.trial._ +import xyz.driver.pdsuidomain.entities.{Criterion, EligibilityArm, Trial} object export { - import xyz.driver.core.generators._ import common._ + import xyz.driver.core.generators._ def nextExportTrialArm(): ExportTrialArm = - ExportTrialArm(armId = nextLongId[Arm], armName = nextString(100)) + ExportTrialArm(armId = nextLongId[EligibilityArm], + armName = nextString(100), + diseaseList = listOf(nextString(100))) def nextExportTrialLabelCriterion(): ExportTrialLabelCriterion = ExportTrialLabelCriterion( criterionId = nextLongId[Criterion], value = nextOption[Boolean](nextBoolean()), labelId = nextLongId[Label], - armIds = setOf(nextLongId[Arm]), + armIds = setOf(nextLongId[EligibilityArm]), criteria = nextString(100), isCompound = nextBoolean(), isDefining = nextBoolean() @@ -26,7 +28,6 @@ object export { ExportTrialWithLabels( nctId = nextStringId[Trial], trialId = nextUuidId[Trial], - disease = nextString(100), lastReviewed = nextLocalDateTime, labelVersion = nextInt(100).toLong, arms = listOf(nextExportTrialArm()), 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 069d1f1..ade0115 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/fakes/entities/trialcuration.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/fakes/entities/trialcuration.scala @@ -1,14 +1,13 @@ package xyz.driver.pdsuidomain.fakes.entities import xyz.driver.entities.labels.{Label, LabelCategory} -import xyz.driver.entities.patient.CancerType import xyz.driver.pdsuicommon.domain.{LongId, User} import xyz.driver.pdsuidomain.entities._ import xyz.driver.pdsuidomain.services.CriterionService.RichCriterion object trialcuration { - import xyz.driver.core.generators import common._ + import xyz.driver.core.generators import xyz.driver.pdsuidomain.entities.InterventionType._ def nextTrial(): Trial = Trial( @@ -20,7 +19,6 @@ object trialcuration { previousAssignee = Option(nextStringId[User]), lastActiveUserId = Option(nextStringId[User]), lastUpdate = nextLocalDateTime, - disease = generators.oneOf[CancerType](CancerType.Breast, CancerType.Lung, CancerType.Prostate), phase = generators.nextString(), hypothesisId = Option(nextUuidId[Hypothesis]), studyDesignId = Option(nextLongId[StudyDesign]), @@ -63,7 +61,7 @@ object trialcuration { val criterion = nextCriterion() RichCriterion( criterion = criterion, - armIds = Seq(nextLongId[Arm], nextLongId[Arm]), + armIds = Seq(nextLongId[EligibilityArm], nextLongId[EligibilityArm]), labels = Seq( nextCriterionLabel(criterion.id), nextCriterionLabel(criterion.id) @@ -86,7 +84,7 @@ object trialcuration { def nextInterventionArm(interventionId: LongId[Intervention]): InterventionArm = InterventionArm( interventionId = interventionId, - armId = nextLongId[Arm] + armId = nextLongId[SlotArm] ) def nextInterventionWithArms(): InterventionWithArms = { diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiCriterion.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiCriterion.scala index 43b5494..239adb1 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiCriterion.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiCriterion.scala @@ -4,7 +4,7 @@ import xyz.driver.pdsuicommon.json.Serialization.seqJsonFormat import play.api.libs.functional.syntax._ import play.api.libs.json._ import xyz.driver.pdsuicommon.domain.{LongId, StringId} -import xyz.driver.pdsuidomain.entities.{Arm, Criterion, Trial} +import xyz.driver.pdsuidomain.entities.{EligibilityArm, Criterion, Trial} import xyz.driver.pdsuidomain.formats.json.label.ApiCriterionLabel import xyz.driver.pdsuidomain.services.CriterionService.RichCriterion @@ -26,7 +26,7 @@ final case class ApiCriterion(id: Long, meta.getOrElse(""), inclusion ), - armIds = arms.map(LongId[Arm]), + armIds = arms.map(LongId[EligibilityArm]), labels = labels.map(_.toDomain(LongId[Criterion](id))) ) } diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiNewCriterion.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiNewCriterion.scala index d72a9b4..4b85f83 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiNewCriterion.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiNewCriterion.scala @@ -25,7 +25,7 @@ final case class ApiNewCriterion(meta: Option[String], text = text, inclusion = inclusion ), - armIds = arms.getOrElse(Seq.empty).map(LongId[Arm]), + armIds = arms.getOrElse(Seq.empty).map(LongId[EligibilityArm]), labels = labels.map(_.toDomain(LongId(Long.MaxValue))) // A developer should specify right criterionId himself ) } diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiUpdateCriterion.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiUpdateCriterion.scala index 77989f0..a700309 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiUpdateCriterion.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/criterion/ApiUpdateCriterion.scala @@ -2,7 +2,7 @@ package xyz.driver.pdsuidomain.formats.json.criterion import xyz.driver.pdsuicommon.domain.LongId import xyz.driver.pdsuicommon.json.Serialization.seqJsonFormat -import xyz.driver.pdsuidomain.entities.{Arm, Criterion} +import xyz.driver.pdsuidomain.entities.{EligibilityArm, Criterion} import org.davidbild.tristate._ import org.davidbild.tristate.contrib.play.ToJsPathOpsFromJsPath import play.api.libs.functional.syntax._ @@ -19,7 +19,7 @@ final case class ApiUpdateCriterion(meta: Tristate[String], def applyTo(orig: RichCriterion): RichCriterion = RichCriterion( criterion = applyTo(orig.criterion), - armIds = arms.cata(_.map(LongId[Arm]), Seq.empty, orig.armIds), + armIds = arms.cata(_.map(LongId[EligibilityArm]), Seq.empty, orig.armIds), labels = labels.cata(_.map(_.toDomain(orig.criterion.id)), Seq.empty, orig.labels) ) diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibilityarm/ApiEligibilityArm.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibilityarm/ApiEligibilityArm.scala new file mode 100644 index 0000000..71423e8 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibilityarm/ApiEligibilityArm.scala @@ -0,0 +1,57 @@ +package xyz.driver.pdsuidomain.formats.json.eligibilityarm + +import play.api.libs.functional.syntax._ +import play.api.libs.json._ +import xyz.driver.entities.patient.CancerType +import xyz.driver.pdsuicommon.domain.{LongId, StringId} +import xyz.driver.pdsuidomain.entities.{EligibilityArm, EligibilityArmDisease, EligibilityArmWithDiseases} + +final case class ApiEligibilityArm(id: Long, + name: String, + originalName: String, + trialId: String, + diseases: Seq[String]) { + + def toDomain: EligibilityArmWithDiseases = { + val eligibilityArm = EligibilityArm( + id = LongId(this.id), + name = this.name, + originalName = this.originalName, + trialId = StringId(this.trialId), + deleted = None // if we have an ApiEligibilityArm object, the EligibilityArm itself has not been deleted + ) + + EligibilityArmWithDiseases( + eligibilityArm, + this.diseases.map { disease => + val condition = CancerType + .fromString(disease) + .getOrElse(throw new NoSuchElementException(s"unknown condition $disease")) + EligibilityArmDisease(eligibilityArm.id, condition) + } + ) + } +} + +object ApiEligibilityArm { + + implicit val format: Format[ApiEligibilityArm] = ( + (JsPath \ "id").format[Long] and + (JsPath \ "name").format[String] and + (JsPath \ "originalName").format[String] and + (JsPath \ "trialId").format[String] and + (JsPath \ "diseases").format[Seq[String]] + )(ApiEligibilityArm.apply, unlift(ApiEligibilityArm.unapply)) + + def fromDomain(eligibilityArmWithDiseases: EligibilityArmWithDiseases): ApiEligibilityArm = { + import eligibilityArmWithDiseases.{eligibilityArm, eligibilityArmDiseases} + + ApiEligibilityArm( + id = eligibilityArm.id.id, + name = eligibilityArm.name, + originalName = eligibilityArm.originalName, + trialId = eligibilityArm.trialId.id, + diseases = eligibilityArmDiseases.map(_.disease.toString) + ) + } +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibilityarm/ApiEligibilityCreateArm.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibilityarm/ApiEligibilityCreateArm.scala new file mode 100644 index 0000000..087fed5 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibilityarm/ApiEligibilityCreateArm.scala @@ -0,0 +1,33 @@ +package xyz.driver.pdsuidomain.formats.json.eligibilityarm + +import play.api.libs.json.{Format, Json} +import xyz.driver.entities.patient.CancerType +import xyz.driver.pdsuicommon.domain.{LongId, StringId} +import xyz.driver.pdsuidomain.entities.{EligibilityArm, EligibilityArmDisease, EligibilityArmWithDiseases} + +final case class ApiCreateEligibilityArm(name: String, trialId: String, diseases: Seq[String]) { + + def toDomain: EligibilityArmWithDiseases = { + val eligibilityArm = EligibilityArm( + id = LongId(0), + name = name, + trialId = StringId(trialId), + originalName = name + ) + + EligibilityArmWithDiseases( + eligibilityArm, + diseases.map { disease => + val condition = CancerType + .fromString(disease) + .getOrElse(throw new NoSuchElementException(s"unknown condition $disease")) + EligibilityArmDisease(eligibilityArm.id, condition) + } + ) + } +} + +object ApiCreateEligibilityArm { + + implicit val format: Format[ApiCreateEligibilityArm] = Json.format[ApiCreateEligibilityArm] +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibilityarm/ApiPartialEligibilityArm.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibilityarm/ApiPartialEligibilityArm.scala new file mode 100644 index 0000000..aca22ef --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibilityarm/ApiPartialEligibilityArm.scala @@ -0,0 +1,23 @@ +package xyz.driver.pdsuidomain.formats.json.eligibilityarm + +import play.api.libs.json.{Format, Json} +import xyz.driver.entities.patient.CancerType +import xyz.driver.pdsuidomain.entities.{EligibilityArmDisease, EligibilityArmWithDiseases} + +final case class ApiPartialEligibilityArm(name: String, diseases: Seq[String]) { + + def applyTo(armWithDisease: EligibilityArmWithDiseases): EligibilityArmWithDiseases = { + val arm = armWithDisease.eligibilityArm.copy(name = name) + val armDiseases = diseases.map { disease => + EligibilityArmDisease( + armWithDisease.eligibilityArm.id, + CancerType.fromString(disease).getOrElse(throw new NoSuchElementException(s"unknown condition $disease"))) + } + EligibilityArmWithDiseases(arm, armDiseases) + } +} + +object ApiPartialEligibilityArm { + + implicit val format: Format[ApiPartialEligibilityArm] = Json.format +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/slotarm/ApiPartialSlotArm.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/slotarm/ApiPartialSlotArm.scala new file mode 100644 index 0000000..2f8e93f --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/slotarm/ApiPartialSlotArm.scala @@ -0,0 +1,14 @@ +package xyz.driver.pdsuidomain.formats.json.slotarm + +import xyz.driver.pdsuidomain.entities.SlotArm +import play.api.libs.json.{Format, Json} + +final case class ApiPartialSlotArm(name: String) { + + def applyTo(arm: SlotArm): SlotArm = arm.copy(name = name) +} + +object ApiPartialSlotArm { + + implicit val format: Format[ApiPartialSlotArm] = Json.format +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/slotarm/ApiSlotArm.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/slotarm/ApiSlotArm.scala new file mode 100644 index 0000000..375c1a2 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/slotarm/ApiSlotArm.scala @@ -0,0 +1,35 @@ +package xyz.driver.pdsuidomain.formats.json.slotarm + +import xyz.driver.pdsuicommon.domain.{LongId, StringId} +import xyz.driver.pdsuidomain.entities.SlotArm +import play.api.libs.functional.syntax._ +import play.api.libs.json._ + +final case class ApiSlotArm(id: Long, name: String, originalName: String, trialId: String) { + + def toDomain: SlotArm = SlotArm( + id = LongId(this.id), + name = this.name, + originalName = this.originalName, + trialId = StringId(this.trialId), + deleted = None // if we have an ApiSlotArm object, the SlotArm itself has not been deleted + ) + +} + +object ApiSlotArm { + + implicit val format: Format[ApiSlotArm] = ( + (JsPath \ "id").format[Long] and + (JsPath \ "name").format[String] and + (JsPath \ "originalName").format[String] and + (JsPath \ "trialId").format[String] + )(ApiSlotArm.apply, unlift(ApiSlotArm.unapply)) + + def fromDomain(arm: SlotArm): ApiSlotArm = ApiSlotArm( + id = arm.id.id, + name = arm.name, + originalName = arm.originalName, + trialId = arm.trialId.id + ) +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/slotarm/ApiSlotCreateArm.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/slotarm/ApiSlotCreateArm.scala new file mode 100644 index 0000000..3e52c13 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/slotarm/ApiSlotCreateArm.scala @@ -0,0 +1,20 @@ +package xyz.driver.pdsuidomain.formats.json.slotarm + +import xyz.driver.pdsuicommon.domain.{LongId, StringId} +import xyz.driver.pdsuidomain.entities.SlotArm +import play.api.libs.json.{Format, Json} + +final case class ApiCreateSlotArm(name: String, trialId: String) { + + def toDomain = SlotArm( + id = LongId(0), + name = name, + trialId = StringId(trialId), + originalName = name + ) +} + +object ApiCreateSlotArm { + + implicit val format: Format[ApiCreateSlotArm] = Json.format[ApiCreateSlotArm] +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/criterion.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/criterion.scala index 89c843f..a43e92a 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/criterion.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/criterion.scala @@ -80,7 +80,7 @@ object criterion { val arms = fields .get("arms") - .map(_.convertTo[Option[List[LongId[Arm]]]].getOrElse(List.empty[LongId[Arm]])) + .map(_.convertTo[Option[List[LongId[EligibilityArm]]]].getOrElse(List.empty[LongId[EligibilityArm]])) .getOrElse(orig.armIds) val labels = fields @@ -143,8 +143,8 @@ object criterion { val arms = fields .get("arms") - .map(_.convertTo[List[LongId[Arm]]]) - .getOrElse(List.empty[LongId[Arm]]) + .map(_.convertTo[List[LongId[EligibilityArm]]]) + .getOrElse(List.empty[LongId[EligibilityArm]]) val labels = fields .get("labels") diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/eligibilityarm.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/eligibilityarm.scala new file mode 100644 index 0000000..acb790a --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/eligibilityarm.scala @@ -0,0 +1,44 @@ +package xyz.driver.pdsuidomain.formats.json.sprayformats + +import spray.json._ +import xyz.driver.pdsuicommon.domain.{LongId, StringId} +import xyz.driver.pdsuidomain.entities.{EligibilityArm, Trial} + +object eligibilityarm { + import DefaultJsonProtocol._ + import common._ + + def applyUpdateToArm(json: JsValue, orig: EligibilityArm): EligibilityArm = json match { + case JsObject(fields) => + val name = fields + .get("name") + .map(_.convertTo[String]) + .getOrElse(deserializationError(s"Arm json object does not contain `name` field: $json")) + orig.copy(name = name) + + case _ => deserializationError(s"Expected Json Object as partial Arm, but got $json") + } + + def eligibilityArmFormat: RootJsonFormat[EligibilityArm] = new RootJsonFormat[EligibilityArm] { + override def write(obj: EligibilityArm): JsValue = + JsObject( + "id" -> obj.id.toJson, + "name" -> obj.name.toJson, + "originalName" -> obj.originalName.toJson, + "trialId" -> obj.trialId.toJson + ) + + override def read(json: JsValue): EligibilityArm = json.asJsObject.getFields("trialId", "name") match { + case Seq(trialId, name) => + EligibilityArm( + id = LongId(0), + name = name.convertTo[String], + trialId = trialId.convertTo[StringId[Trial]], + originalName = name.convertTo[String] + ) + + case _ => deserializationError(s"Expected Json Object as Arm, but got $json") + } + } + +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/export.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/export.scala index 85d614d..4391453 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/export.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/export.scala @@ -2,16 +2,16 @@ package xyz.driver.pdsuidomain.formats.json.sprayformats import spray.json._ import xyz.driver.entities.labels.Label -import xyz.driver.pdsuidomain.entities.{Arm, Criterion} +import xyz.driver.formats.json.labels._ import xyz.driver.pdsuidomain.entities.export.patient._ import xyz.driver.pdsuidomain.entities.export.trial.{ExportTrialArm, ExportTrialLabelCriterion, ExportTrialWithLabels} -import xyz.driver.formats.json.labels._ +import xyz.driver.pdsuidomain.entities.{Criterion, EligibilityArm} object export { import DefaultJsonProtocol._ import common._ - import record._ import document._ + import record._ implicit val patientLabelEvidenceDocumentFormat: RootJsonFormat[ExportPatientLabelEvidenceDocument] = jsonFormat5(ExportPatientLabelEvidenceDocument.apply) @@ -25,7 +25,7 @@ object export { implicit val patientWithLabelsFormat: RootJsonFormat[ExportPatientWithLabels] = jsonFormat(ExportPatientWithLabels.apply, "patientId", "labelVersion", "labels") - implicit val trialArmFormat: RootJsonFormat[ExportTrialArm] = jsonFormat2(ExportTrialArm.apply) + implicit val trialArmFormat: RootJsonFormat[ExportTrialArm] = jsonFormat3(ExportTrialArm.apply) implicit val trialLabelCriterionFormat: RootJsonFormat[ExportTrialLabelCriterion] = new RootJsonFormat[ExportTrialLabelCriterion] { @@ -68,7 +68,7 @@ object export { longIdFormat[Criterion].read(criterionId), value, longIdFormat[Label].read(labelId), - armIdsVector.map(longIdFormat[Arm].read).toSet, + armIdsVector.map(longIdFormat[EligibilityArm].read).toSet, criterionText, isCompound, isDefining @@ -82,12 +82,5 @@ object export { } implicit val trialWithLabelsFormat: RootJsonFormat[ExportTrialWithLabels] = - jsonFormat(ExportTrialWithLabels.apply, - "nctId", - "trialId", - "disease", - "lastReviewed", - "labelVersion", - "arms", - "criteria") + jsonFormat(ExportTrialWithLabels.apply, "nctId", "trialId", "lastReviewed", "labelVersion", "arms", "criteria") } diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/intervention.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/intervention.scala index 62cb9fa..2ced434 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/intervention.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/intervention.scala @@ -56,7 +56,7 @@ object intervention { val arms = fields .get("arms") - .map(_.convertTo[List[LongId[Arm]]].map(x => InterventionArm(armId = x, interventionId = LongId(0)))) + .map(_.convertTo[List[LongId[SlotArm]]].map(x => InterventionArm(armId = x, interventionId = LongId(0)))) .getOrElse(List.empty[InterventionArm]) InterventionWithArms( @@ -104,7 +104,7 @@ object intervention { val origIntervention = orig.intervention val arms = fields .get("arms") - .map(_.convertTo[List[LongId[Arm]]].map(x => InterventionArm(x, orig.intervention.id))) + .map(_.convertTo[List[LongId[SlotArm]]].map(x => InterventionArm(x, orig.intervention.id))) orig.copy( intervention = origIntervention.copy( diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/slotarm.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/slotarm.scala new file mode 100644 index 0000000..192bd6a --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/slotarm.scala @@ -0,0 +1,44 @@ +package xyz.driver.pdsuidomain.formats.json.sprayformats + +import spray.json._ +import xyz.driver.pdsuicommon.domain.{LongId, StringId} +import xyz.driver.pdsuidomain.entities.{SlotArm, Trial} + +object slotarm { + import DefaultJsonProtocol._ + import common._ + + def applyUpdateToArm(json: JsValue, orig: SlotArm): SlotArm = json match { + case JsObject(fields) => + val name = fields + .get("name") + .map(_.convertTo[String]) + .getOrElse(deserializationError(s"Arm json object does not contain `name` field: $json")) + orig.copy(name = name) + + case _ => deserializationError(s"Expected Json Object as partial Arm, but got $json") + } + + def slotArmFormat: RootJsonFormat[SlotArm] = new RootJsonFormat[SlotArm] { + override def write(obj: SlotArm): JsValue = + JsObject( + "id" -> obj.id.toJson, + "name" -> obj.name.toJson, + "originalName" -> obj.originalName.toJson, + "trialId" -> obj.trialId.toJson + ) + + override def read(json: JsValue): SlotArm = json.asJsObject.getFields("trialId", "name") match { + case Seq(trialId, name) => + SlotArm( + id = LongId(0), + name = name.convertTo[String], + trialId = trialId.convertTo[StringId[Trial]], + originalName = name.convertTo[String] + ) + + case _ => deserializationError(s"Expected Json Object as Arm, but got $json") + } + } + +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trial.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trial.scala index d851c2c..b25ed1d 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trial.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trial.scala @@ -6,12 +6,11 @@ import spray.json._ import xyz.driver.core.json.EnumJsonFormat import xyz.driver.pdsuicommon.domain.{LongId, UuidId} import xyz.driver.pdsuidomain.entities._ -import xyz.driver.formats.json.patient._ object trial { import DefaultJsonProtocol._ - import common._ import Trial._ + import common._ implicit val trialStatusFormat = new EnumJsonFormat[Status]( "New" -> Status.New, @@ -36,7 +35,6 @@ object trial { "previousStatus" -> obj.previousStatus.toJson, "previousAssignee" -> obj.previousAssignee.toJson, "lastActiveUser" -> obj.lastActiveUserId.toJson, - "disease" -> obj.disease.toJson, "phase" -> obj.phase.toJson, "hypothesisId" -> obj.hypothesisId.toJson, "studyDesignId" -> obj.studyDesignId.toJson, diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial/ApiTrial.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial/ApiTrial.scala index a2a1ca9..133a2c8 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial/ApiTrial.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial/ApiTrial.scala @@ -3,11 +3,10 @@ package xyz.driver.pdsuidomain.formats.json.trial import java.time.{ZoneId, ZonedDateTime} import java.util.UUID -import xyz.driver.pdsuicommon.domain.{LongId, StringId, UuidId} -import xyz.driver.pdsuidomain.entities.Trial import play.api.libs.functional.syntax._ import play.api.libs.json._ -import xyz.driver.entities.patient.CancerType +import xyz.driver.pdsuicommon.domain.{LongId, StringId, UuidId} +import xyz.driver.pdsuidomain.entities.Trial final case class ApiTrial(id: String, externalId: UUID, @@ -17,7 +16,6 @@ final case class ApiTrial(id: String, previousStatus: Option[String], previousAssignee: Option[String], lastActiveUser: Option[String], - disease: String, phase: String, hypothesisId: Option[UUID], studyDesignId: Option[Long], @@ -38,9 +36,6 @@ final case class ApiTrial(id: String, previousAssignee = this.previousAssignee.map(id => StringId(id)), lastActiveUserId = this.lastActiveUser.map(id => StringId(id)), lastUpdate = this.lastUpdate.toLocalDateTime, - disease = CancerType - .fromString(this.disease) - .getOrElse(throw new NoSuchElementException(s"Unknown disease ${this.disease}")), phase = this.phase, hypothesisId = this.hypothesisId.map(id => UuidId(id)), studyDesignId = this.studyDesignId.map(id => LongId(id)), @@ -66,7 +61,6 @@ object ApiTrial { (JsPath \ "previousStatus").formatNullable[String] and (JsPath \ "previousAssignee").formatNullable[String] and (JsPath \ "lastActiveUser").formatNullable[String] and - (JsPath \ "disease").format[String] and (JsPath \ "phase").format[String] and (JsPath \ "hypothesisId").formatNullable[UUID] and (JsPath \ "studyDesignId").formatNullable[Long] and @@ -88,7 +82,6 @@ object ApiTrial { previousAssignee = trial.previousAssignee.map(_.id), lastActiveUser = trial.lastActiveUserId.map(_.id), lastUpdate = ZonedDateTime.of(trial.lastUpdate, ZoneId.of("Z")), - disease = trial.disease.toString, phase = trial.phase, hypothesisId = trial.hypothesisId.map(_.id), studyDesignId = trial.studyDesignId.map(_.id), diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/CriterionService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/CriterionService.scala index fd9268b..7dbf0d9 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/services/CriterionService.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/services/CriterionService.scala @@ -21,7 +21,9 @@ object CriterionService { def userMessage: String = "Access denied" } - final case class RichCriterion(criterion: Criterion, armIds: Seq[LongId[Arm]], labels: Seq[CriterionLabel]) + final case class RichCriterion(criterion: Criterion, + armIds: Seq[LongId[EligibilityArm]], + labels: Seq[CriterionLabel]) object RichCriterion { implicit def toPhiString(x: RichCriterion): PhiString = { import x._ diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/EligibilityArmService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/EligibilityArmService.scala new file mode 100644 index 0000000..1e0f65e --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/services/EligibilityArmService.scala @@ -0,0 +1,139 @@ +package xyz.driver.pdsuidomain.services + +import xyz.driver.pdsuicommon.auth.AuthenticatedRequestContext +import xyz.driver.pdsuicommon.db._ +import xyz.driver.pdsuicommon.domain.LongId +import xyz.driver.pdsuicommon.error.DomainError +import xyz.driver.pdsuicommon.logging._ +import xyz.driver.pdsuidomain.entities.{EligibilityArm, EligibilityArmWithDiseases, SlotArm} + +import scala.concurrent.Future + +object EligibilityArmService { + + trait DefaultAccessDeniedError { + def userMessage: String = "Access denied" + } + + trait DefaultNotFoundError { + def userMessage: String = "EligibilityArm not found" + } + + trait SlotArmNotFoundError { + def userMessage: String = "SlotArm not found" + } + + sealed trait GetByIdReply + object GetByIdReply { + + final case class Entity(x: EligibilityArmWithDiseases) extends GetByIdReply + + type Error = GetByIdReply with DomainError + + case object NotFoundError extends GetByIdReply with DefaultNotFoundError with DomainError.NotFoundError + + case object AuthorizationError + extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError + + final case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext) + extends GetByIdReply with DomainError + } + + sealed trait GetListReply + object GetListReply { + type Error = GetListReply with DomainError + + final case class EntityList(xs: Seq[EligibilityArmWithDiseases], totalFound: Int) extends GetListReply + + case object AuthorizationError + extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError + } + + sealed trait UpdateReply + object UpdateReply { + + final case class Updated(updated: EligibilityArmWithDiseases) extends UpdateReply + + type Error = UpdateReply with DomainError + + case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError + + case object AuthorizationError + extends UpdateReply with DefaultAccessDeniedError with DomainError.AuthorizationError + + final case class CommonError(userMessage: String) extends UpdateReply with DomainError + + final case class AlreadyExistsError(x: EligibilityArmWithDiseases) extends UpdateReply with DomainError { + val userMessage = s"The arm with such name of trial already exists." + } + + implicit def toPhiString(reply: UpdateReply): PhiString = reply match { + case Updated(x) => phi"Updated($x)" + case x: Error => DomainError.toPhiString(x) + } + } + + sealed trait CreateReply + object CreateReply { + final case class Created(x: EligibilityArmWithDiseases) extends CreateReply + + type Error = CreateReply with DomainError + + case object AuthorizationError + extends CreateReply with DefaultAccessDeniedError with DomainError.AuthorizationError + + case object NotFoundError extends CreateReply with SlotArmNotFoundError with DomainError.NotFoundError + + final case class CommonError(userMessage: String) extends CreateReply with DomainError + + final case class AlreadyExistsError(x: EligibilityArmWithDiseases) extends CreateReply with DomainError { + val userMessage = s"The arm with this name of trial already exists." + } + + implicit def toPhiString(reply: CreateReply): PhiString = reply match { + case Created(x) => phi"Created($x)" + case x: Error => DomainError.toPhiString(x) + } + } + + sealed trait DeleteReply + object DeleteReply { + case object Deleted extends DeleteReply + + type Error = DeleteReply with DomainError + + case object NotFoundError extends DeleteReply with DefaultNotFoundError with DomainError.NotFoundError + + case object AuthorizationError + extends DeleteReply with DefaultAccessDeniedError with DomainError.AuthorizationError + + final case class CommonError(userMessage: String) extends DeleteReply with DomainError + } +} + +trait EligibilityArmService { + + import EligibilityArmService._ + + def getAll(filter: SearchFilterExpr = SearchFilterExpr.Empty, + sorting: Option[Sorting] = None, + pagination: Option[Pagination] = None)( + implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] + + def getByEligibilityId(armId: LongId[EligibilityArm])( + implicit requestContext: AuthenticatedRequestContext): Future[GetByIdReply] + + def getBySlotId(armId: LongId[SlotArm], + filter: SearchFilterExpr = SearchFilterExpr.Empty, + sorting: Option[Sorting] = None, + pagination: Option[Pagination] = None)( + implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] + + def create(slotArmId: LongId[SlotArm], draftEligibilityArm: EligibilityArmWithDiseases)( + implicit requestContext: AuthenticatedRequestContext): Future[CreateReply] + + def update(origEligibilityArm: EligibilityArmWithDiseases, draftEligibilityArm: EligibilityArmWithDiseases)( + implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] + + def delete(id: LongId[EligibilityArm])(implicit requestContext: AuthenticatedRequestContext): Future[DeleteReply] +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/SlotArmService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/SlotArmService.scala new file mode 100644 index 0000000..af7084b --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/services/SlotArmService.scala @@ -0,0 +1,125 @@ +package xyz.driver.pdsuidomain.services + +import xyz.driver.pdsuicommon.auth.AuthenticatedRequestContext +import xyz.driver.pdsuicommon.db._ +import xyz.driver.pdsuicommon.domain.LongId +import xyz.driver.pdsuicommon.error.DomainError +import xyz.driver.pdsuicommon.logging._ +import xyz.driver.pdsuidomain.entities.SlotArm + +import scala.concurrent.Future + +object SlotArmService { + + trait DefaultAccessDeniedError { + def userMessage: String = "Access denied" + } + + trait DefaultNotFoundError { + def userMessage: String = "SlotArm not found" + } + + sealed trait GetByIdReply + object GetByIdReply { + + final case class Entity(x: SlotArm) extends GetByIdReply + + type Error = GetByIdReply with DomainError + + case object NotFoundError extends GetByIdReply with DefaultNotFoundError with DomainError.NotFoundError + + case object AuthorizationError + extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError + + final case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext) + extends GetByIdReply with DomainError + } + + sealed trait GetListReply + object GetListReply { + type Error = GetListReply with DomainError + + final case class EntityList(xs: Seq[SlotArm], totalFound: Int) extends GetListReply + + case object AuthorizationError + extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError + } + + sealed trait UpdateReply + object UpdateReply { + + final case class Updated(updated: SlotArm) extends UpdateReply + + type Error = UpdateReply with DomainError + + case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError + + case object AuthorizationError + extends UpdateReply with DefaultAccessDeniedError with DomainError.AuthorizationError + + final case class CommonError(userMessage: String) extends UpdateReply with DomainError + + final case class AlreadyExistsError(x: SlotArm) extends UpdateReply with DomainError { + val userMessage = s"The arm with such name of trial already exists." + } + + implicit def toPhiString(reply: UpdateReply): PhiString = reply match { + case Updated(x) => phi"Updated($x)" + case x: Error => DomainError.toPhiString(x) + } + } + + sealed trait CreateReply + object CreateReply { + final case class Created(x: SlotArm) extends CreateReply + + type Error = CreateReply with DomainError + + case object AuthorizationError + extends CreateReply with DefaultAccessDeniedError with DomainError.AuthorizationError + + final case class CommonError(userMessage: String) extends CreateReply with DomainError + + final case class AlreadyExistsError(x: SlotArm) extends CreateReply with DomainError { + val userMessage = s"The arm with this name of trial already exists." + } + + implicit def toPhiString(reply: CreateReply): PhiString = reply match { + case Created(x) => phi"Created($x)" + case x: Error => DomainError.toPhiString(x) + } + } + + sealed trait DeleteReply + object DeleteReply { + case object Deleted extends DeleteReply + + type Error = DeleteReply with DomainError + + case object NotFoundError extends DeleteReply with DefaultNotFoundError with DomainError.NotFoundError + + case object AuthorizationError + extends DeleteReply with DefaultAccessDeniedError with DomainError.AuthorizationError + + final case class CommonError(userMessage: String) extends DeleteReply with DomainError + } +} + +trait SlotArmService { + + import SlotArmService._ + + def getAll(filter: SearchFilterExpr = SearchFilterExpr.Empty, + sorting: Option[Sorting] = None, + pagination: Option[Pagination] = None)( + implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] + + def getById(armId: LongId[SlotArm])(implicit requestContext: AuthenticatedRequestContext): Future[GetByIdReply] + + def create(draftSlotArm: SlotArm)(implicit requestContext: AuthenticatedRequestContext): Future[CreateReply] + + def update(origSlotArm: SlotArm, draftSlotArm: SlotArm)( + implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] + + def delete(id: LongId[SlotArm])(implicit requestContext: AuthenticatedRequestContext): Future[DeleteReply] +} 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 a1efdac..e0efcd1 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/services/fake/FakeTrialService.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/services/fake/FakeTrialService.scala @@ -11,8 +11,8 @@ import xyz.driver.entities.patient.CancerType import xyz.driver.pdsuicommon.auth.AuthenticatedRequestContext import xyz.driver.pdsuicommon.db._ import xyz.driver.pdsuicommon.domain.{LongId, StringId, UuidId} -import xyz.driver.pdsuidomain.entities.{Arm, Criterion, Trial} import xyz.driver.pdsuidomain.entities.export.trial.{ExportTrialArm, ExportTrialLabelCriterion, ExportTrialWithLabels} +import xyz.driver.pdsuidomain.entities.{Criterion, EligibilityArm, Trial} import xyz.driver.pdsuidomain.services.TrialService import scala.concurrent.Future @@ -30,7 +30,6 @@ class FakeTrialService extends TrialService { previousAssignee = None, lastActiveUserId = None, lastUpdate = LocalDateTime.now(), - disease = CancerType.Breast, phase = "", hypothesisId = None, studyDesignId = None, @@ -70,20 +69,20 @@ class FakeTrialService extends TrialService { ExportTrialWithLabels( StringId[Trial]("NCT" + generators.nextInt(999999).toString), UuidId[Trial](generators.nextUuid()), - generators.oneOf("adenocarcinoma", "breast", "prostate"), LocalDateTime.now(), labelVersion = 1L, generators.listOf( new ExportTrialArm( - LongId[Arm](generators.nextInt(999999).toLong), - generators.nextName().value + LongId[EligibilityArm](generators.nextInt(999999).toLong), + generators.nextName().value, + generators.listOf(generators.oneOf("adenocarcinoma", "breast", "prostate")) )), generators.listOf( new ExportTrialLabelCriterion( LongId[Criterion](generators.nextInt(999999).toLong), generators.nextOption(generators.nextBoolean()), LongId[Label](generators.nextInt(999999).toLong), - generators.setOf(LongId[Arm](generators.nextInt(999999).toLong)), + generators.setOf(LongId[EligibilityArm](generators.nextInt(999999).toLong)), generators.nextName().value, generators.nextBoolean(), generators.nextBoolean() |