aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jakob@odersky.com>2017-08-14 22:29:45 -0700
committerGitHub <noreply@github.com>2017-08-14 22:29:45 -0700
commit322ea28ecf5ad5f65d3376f3e97e004d229d4736 (patch)
treec405d10d70f4ec1f18ffa81bc01cd8da64bddcba
parentbe74ae7c5531af998d38b9de8052791f17b25341 (diff)
parent442579b27ccbac82cb001a5b02402a593d005977 (diff)
downloadrest-query-322ea28ecf5ad5f65d3376f3e97e004d229d4736.tar.gz
rest-query-322ea28ecf5ad5f65d3376f3e97e004d229d4736.tar.bz2
rest-query-322ea28ecf5ad5f65d3376f3e97e004d229d4736.zip
Merge pull request #18 from drivergroup/PDSUI-2188
PDSUI-2188 Create spray json formats for domain entities
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/arm.scala44
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/bridgeuploadqueue.scala68
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/common.scala74
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/criterion.scala158
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/document.scala164
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/documenthistory.scala29
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/documentissue.scala77
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/export.scala78
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/extracteddata.scala148
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/hypothesis.scala12
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/intervention.scala60
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patient.scala46
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientcriterion.scala68
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientdefiningcriteria.scala18
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienteligibletrial.scala39
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienthistory.scala30
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienthypothesis.scala37
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientissue.scala54
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientlabel.scala64
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/record.scala237
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/recordhistory.scala30
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/recordissue.scala79
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/studydesign.scala12
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trial.scala90
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trialhistory.scala30
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trialissue.scala60
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/ApiDocumentSuite.scala78
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/ApiPartialDocumentSuite.scala263
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ArmFormatSuite.scala36
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/BridgeUploadQueueFormat.scala32
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/CriterionFormatSuite.scala68
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentFormatSuite.scala74
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentHistoryFormatSuite.scala32
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentIssueFormatSuite.scala47
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ExportFormatSuite.scala124
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ExtractedDataFormatSuite.scala95
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/HypothesisFormatSuite.scala28
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/InterventionFormatSuite.scala63
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordFormatSuite.scala77
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordHistoryFormatSuite.scala32
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordIssueFormatSuite.scala47
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientCriterionFormatSuite.scala55
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientEligibleTrialFormatSuite.scala62
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientFormatSuite.scala36
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientHistoryFormatSuite.scala32
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientHypothesisFormatSuite.scala31
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientIssueFormatSuite.scala44
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientLabelFormatSuite.scala76
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/StudyDesignFormatSuite.scala24
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialFormatSuite.scala50
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialHistoryFormatSuite.scala32
-rw-r--r--src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialIssueFormatSuite.scala49
52 files changed, 3052 insertions, 341 deletions
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/arm.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/arm.scala
new file mode 100644
index 0000000..39af1c3
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/arm.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._
+
+object arm {
+ import DefaultJsonProtocol._
+ import common._
+
+ def applyUpdateToArm(json: JsValue, orig: Arm): Arm = 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 armFormat: RootJsonFormat[Arm] = new RootJsonFormat[Arm] {
+ override def write(obj: Arm): JsValue =
+ JsObject(
+ "id" -> obj.id.toJson,
+ "name" -> obj.name.toJson,
+ "originalName" -> obj.originalName.toJson,
+ "trialId" -> obj.trialId.toJson
+ )
+
+ override def read(json: JsValue): Arm = json.asJsObject.getFields("trialId", "name") match {
+ case Seq(trialId, name) =>
+ Arm(
+ 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/bridgeuploadqueue.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/bridgeuploadqueue.scala
new file mode 100644
index 0000000..77fb4d2
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/bridgeuploadqueue.scala
@@ -0,0 +1,68 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import xyz.driver.pdsuicommon.concurrent.BridgeUploadQueue
+import xyz.driver.pdsuicommon.concurrent.BridgeUploadQueue.Item
+
+object bridgeuploadqueue {
+ import DefaultJsonProtocol._
+ import common._
+
+ implicit val queueUploadItemFormat: RootJsonFormat[BridgeUploadQueue.Item] = new RootJsonFormat[Item] {
+ override def write(obj: Item) =
+ JsObject(
+ "kind" -> obj.kind.toJson,
+ "tag" -> obj.tag.toJson,
+ "created" -> obj.created.toJson,
+ "attempts" -> obj.attempts.toJson,
+ "nextAttempt" -> obj.nextAttempt.toJson,
+ "completed" -> obj.completed.toJson
+ )
+
+ override def read(json: JsValue): Item = json match {
+ case JsObject(fields) =>
+ val kind = fields
+ .get("kind")
+ .map(_.convertTo[String])
+ .getOrElse(deserializationError(s"BridgeUploadQueue.Item json object does not contain `kind` field: $json"))
+
+ val tag = fields
+ .get("tag")
+ .map(_.convertTo[String])
+ .getOrElse(deserializationError(s"BridgeUploadQueue.Item json object does not contain `tag` field: $json"))
+
+ val created = fields
+ .get("created")
+ .map(_.convertTo[LocalDateTime])
+ .getOrElse(
+ deserializationError(s"BridgeUploadQueue.Item json object does not contain `created` field: $json"))
+
+ val attempts = fields
+ .get("attempts")
+ .map(_.convertTo[Int])
+ .getOrElse(
+ deserializationError(s"BridgeUploadQueue.Item json object does not contain `attempts` field: $json"))
+
+ val nextAttempt = fields
+ .get("nextAttempt")
+ .map(_.convertTo[LocalDateTime])
+ .getOrElse(
+ deserializationError(s"BridgeUploadQueue.Item json object does not contain `nextAttempt` field: $json"))
+
+ BridgeUploadQueue.Item(
+ kind = kind,
+ tag = tag,
+ created = created,
+ attempts = attempts,
+ nextAttempt = nextAttempt,
+ completed = true,
+ dependencyKind = None,
+ dependencyTag = None
+ )
+
+ case _ => deserializationError(s"Expected Json Object as BridgeUploadQueue.Item, but got $json")
+ }
+ }
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/common.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/common.scala
new file mode 100644
index 0000000..dbd0a43
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/common.scala
@@ -0,0 +1,74 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.{LocalDate, LocalDateTime, ZoneId, ZonedDateTime}
+
+import spray.json._
+import xyz.driver.pdsuicommon.domain.{FuzzyValue, LongId, StringId, UuidId}
+
+object common {
+
+ implicit def longIdFormat[T] = new RootJsonFormat[LongId[T]] {
+ override def write(id: LongId[T]): JsNumber = JsNumber(id.id)
+ override def read(json: JsValue): LongId[T] = json match {
+ case JsNumber(value) => LongId(value.toLong)
+ case _ => deserializationError(s"Expected number as LongId, but got $json")
+ }
+ }
+
+ implicit def stringIdFormat[T] = new RootJsonFormat[StringId[T]] {
+ override def write(id: StringId[T]): JsString = JsString(id.toString)
+ override def read(json: JsValue): StringId[T] = json match {
+ case JsString(value) => StringId(value)
+ case _ => deserializationError(s"Expected string as StringId, but got $json")
+ }
+ }
+
+ implicit def uuidIdFormat[T] = new RootJsonFormat[UuidId[T]] {
+ override def write(id: UuidId[T]): JsString = JsString(id.toString)
+ override def read(json: JsValue): UuidId[T] = json match {
+ case JsString(value) => UuidId(value)
+ case _ => deserializationError(s"Expected string as UuidId, but got $json")
+ }
+ }
+
+ implicit def dateTimeFormat = new RootJsonFormat[LocalDateTime] {
+ override def write(date: LocalDateTime): JsString = JsString(ZonedDateTime.of(date, ZoneId.of("Z")).toString)
+ override def read(json: JsValue): LocalDateTime = json match {
+ case JsString(value) => ZonedDateTime.parse(value).toLocalDateTime
+ case _ => deserializationError(s"Expected date as LocalDateTime, but got $json")
+ }
+ }
+
+ implicit def zonedDateTimeFormat = new RootJsonFormat[ZonedDateTime] {
+ override def write(date: ZonedDateTime): JsString = JsString(date.toString)
+ override def read(json: JsValue): ZonedDateTime = json match {
+ case JsString(value) => ZonedDateTime.parse(value)
+ case _ => deserializationError(s"Expected date as ZonedDateTime, but got $json")
+ }
+ }
+
+ implicit def dateFormat = new RootJsonFormat[LocalDate] {
+ override def write(date: LocalDate): JsString = JsString(date.toString)
+ override def read(json: JsValue): LocalDate = json match {
+ case JsString(value) => LocalDate.parse(value)
+ case _ => deserializationError(s"Expected date as LocalDate, but got $json")
+ }
+ }
+
+ implicit def fuzzyValueFormat: RootJsonFormat[FuzzyValue] = new RootJsonFormat[FuzzyValue] {
+ override def write(value: FuzzyValue): JsString = JsString(FuzzyValue.valueToString(value))
+ override def read(json: JsValue): FuzzyValue = json match {
+ case JsString(value) => FuzzyValue.fromString(value)
+ case _ => deserializationError(s"Expected value as FuzzyValue, but got $json")
+ }
+ }
+
+ implicit val integerFormat: RootJsonFormat[Integer] = new RootJsonFormat[Integer] {
+ override def write(obj: Integer): JsNumber = JsNumber(obj.intValue())
+ override def read(json: JsValue): Integer = json match {
+ case JsNumber(value) => value.toInt
+ case _ => deserializationError(s"Expected number as Integer, but got $json")
+ }
+ }
+
+}
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
new file mode 100644
index 0000000..732bcad
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/criterion.scala
@@ -0,0 +1,158 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities._
+import xyz.driver.pdsuidomain.services.CriterionService.RichCriterion
+
+object criterion {
+ import DefaultJsonProtocol._
+ import common._
+
+ implicit val criterionLabelWriter = new JsonWriter[CriterionLabel] {
+ override def write(obj: CriterionLabel) = JsObject(
+ "labelId" -> obj.labelId.toJson,
+ "categoryId" -> obj.categoryId.toJson,
+ "value" -> obj.value.map {
+ case true => "Yes"
+ case false => "No"
+ }.toJson,
+ "isDefining" -> obj.isDefining.toJson
+ )
+ }
+
+ def jsValueToCriterionLabel(json: JsValue, criterionId: LongId[Criterion]): CriterionLabel = json match {
+ case JsObject(fields) =>
+ val labelId = fields
+ .get("labelId")
+ .map(_.convertTo[LongId[Label]])
+
+ val categoryId = fields
+ .get("categoryId")
+ .map(_.convertTo[LongId[Category]])
+
+ val value = fields
+ .get("value")
+ .map(_.convertTo[String] match {
+ case "Yes" => true
+ case "No" => false
+ case other =>
+ deserializationError(s"Unknown `value` of CriterionLabel object: expected `yes` or `no`, but got $other")
+ })
+
+ val isDefining = fields
+ .get("isDefining")
+ .map(_.convertTo[Boolean])
+ .getOrElse(deserializationError(s"CriterionLabel json object does not contain `isDefining` field: $json"))
+
+ CriterionLabel(
+ id = LongId(0L),
+ labelId = labelId,
+ criterionId = criterionId,
+ categoryId = categoryId,
+ value = value,
+ isDefining = isDefining
+ )
+
+ case _ => deserializationError(s"Expected Json Object as CriterionLabel, but got $json")
+ }
+
+ def applyUpdateToCriterion(json: JsValue, orig: RichCriterion): RichCriterion = json match {
+ case JsObject(fields) =>
+ val text = fields
+ .get("text")
+ .map(_.convertTo[String])
+
+ val isCompound = fields
+ .get("isCompound")
+ .exists(_.convertTo[Boolean])
+
+ val meta = fields
+ .get("meta")
+ .map(_.convertTo[Option[String]].getOrElse("{}"))
+ .getOrElse(orig.criterion.meta)
+
+ val arms = fields
+ .get("arms")
+ .map(_.convertTo[Option[List[LongId[Arm]]]].getOrElse(List.empty[LongId[Arm]]))
+ .getOrElse(orig.armIds)
+
+ val labels = fields
+ .get("labels")
+ .map(_.convertTo[Option[List[JsValue]]].getOrElse(List.empty[JsValue]))
+ .map(_.map(l => jsValueToCriterionLabel(l, orig.criterion.id)))
+ .getOrElse(orig.labels)
+
+ orig.copy(
+ criterion = orig.criterion.copy(
+ meta = meta,
+ text = text,
+ isCompound = isCompound
+ ),
+ armIds = arms,
+ labels = labels
+ )
+
+ case _ => deserializationError(s"Expected Json Object as partial Criterion, but got $json")
+ }
+
+ val richCriterionFormat = new RootJsonFormat[RichCriterion] {
+ override def write(obj: RichCriterion): JsValue =
+ JsObject(
+ "id" -> obj.criterion.id.toJson,
+ "meta" -> Option(obj.criterion.meta).toJson,
+ "arms" -> obj.armIds.toJson,
+ "text" -> obj.criterion.text.toJson,
+ "isCompound" -> obj.criterion.isCompound.toJson,
+ "labels" -> obj.labels.map(_.toJson).toJson,
+ "trialId" -> obj.criterion.trialId.toJson
+ )
+
+ override def read(json: JsValue): RichCriterion = json match {
+ case JsObject(fields) =>
+ val trialId = fields
+ .get("trialId")
+ .map(_.convertTo[StringId[Trial]])
+ .getOrElse(deserializationError(s"Criterion json object does not contain `trialId` field: $json"))
+
+ val text = fields
+ .get("text")
+ .map(_.convertTo[String])
+
+ val isCompound = fields
+ .get("isCompound")
+ .exists(_.convertTo[Boolean])
+
+ val meta = fields
+ .get("meta")
+ .map(_.convertTo[String])
+ .getOrElse("")
+
+ val arms = fields
+ .get("arms")
+ .map(_.convertTo[List[LongId[Arm]]])
+ .getOrElse(List.empty[LongId[Arm]])
+
+ val labels = fields
+ .get("labels")
+ .map(_.convertTo[List[JsValue]])
+ .map(_.map(l => jsValueToCriterionLabel(l, LongId(0))))
+ .getOrElse(List.empty[CriterionLabel])
+
+ RichCriterion(
+ criterion = Criterion(
+ id = LongId(0),
+ trialId = trialId,
+ text = text,
+ isCompound = isCompound,
+ meta = meta
+ ),
+ armIds = arms,
+ labels = labels
+ )
+
+ case _ => deserializationError(s"Expected Json Object as Criterion, but got $json")
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/document.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/document.scala
new file mode 100644
index 0000000..baf1b4e
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/document.scala
@@ -0,0 +1,164 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.{LocalDate, LocalDateTime}
+
+import spray.json._
+import xyz.driver.core.json.EnumJsonFormat
+import xyz.driver.pdsuicommon.domain.{LongId, TextJson}
+import xyz.driver.pdsuidomain.entities._
+
+object document {
+ import DefaultJsonProtocol._
+ import Document._
+ import common._
+
+ implicit val documentStatusFormat = new EnumJsonFormat[Status](
+ "New" -> Status.New,
+ "Organized" -> Status.Organized,
+ "Extracted" -> Status.Extracted,
+ "Done" -> Status.Done,
+ "Flagged" -> Status.Flagged,
+ "Archived" -> Status.Archived
+ )
+
+ implicit val requiredTypeFormat = new EnumJsonFormat[RequiredType](
+ "OPN" -> RequiredType.OPN,
+ "PN" -> RequiredType.PN
+ )
+
+ implicit val documentMetaFormat: RootJsonFormat[Meta] = jsonFormat3(Meta.apply)
+
+ implicit val fullDocumentMetaFormat = new RootJsonFormat[TextJson[Meta]] {
+ override def write(obj: TextJson[Meta]): JsValue = obj.content.toJson
+ override def read(json: JsValue) = TextJson(documentMetaFormat.read(json))
+ }
+
+ def applyUpdateToDocument(json: JsValue, orig: Document): Document = json match {
+ case JsObject(fields) =>
+ val physician = fields
+ .get("physician")
+ .map(_.convertTo[String])
+
+ val typeId = fields
+ .get("typeId")
+ .map(_.convertTo[Option[LongId[DocumentType]]])
+ .getOrElse(orig.typeId)
+
+ val provider = fields
+ .get("provider")
+ .map(_.convertTo[Option[String]])
+ .getOrElse(orig.providerName)
+
+ val providerTypeId = fields
+ .get("providerTypeId")
+ .map(_.convertTo[Option[LongId[ProviderType]]])
+ .getOrElse(orig.providerTypeId)
+
+ val meta = fields
+ .get("meta")
+ .map(_.convertTo[Option[TextJson[Meta]]])
+ .getOrElse(orig.meta)
+
+ val startDate = fields
+ .get("startDate")
+ .map(_.convertTo[Option[LocalDate]])
+ .getOrElse(orig.startDate)
+
+ val endDate = fields
+ .get("endDate")
+ .map(_.convertTo[Option[LocalDate]])
+ .getOrElse(orig.endDate)
+
+ orig.copy(
+ physician = physician.orElse(orig.physician),
+ typeId = typeId,
+ providerName = provider,
+ providerTypeId = providerTypeId,
+ meta = meta,
+ startDate = startDate,
+ endDate = endDate
+ )
+
+ case _ => deserializationError(s"Expected Json Object as partial Document, but got $json")
+ }
+
+ implicit val documentFormat: RootJsonFormat[Document] = new RootJsonFormat[Document] {
+ override def write(document: Document): JsValue =
+ JsObject(
+ "id" -> document.id.id.toJson,
+ "recordId" -> document.recordId.toJson,
+ "physician" -> document.physician.toJson,
+ "typeId" -> document.typeId.toJson,
+ "provider" -> document.providerName.toJson,
+ "providerTypeId" -> document.providerTypeId.toJson,
+ "requiredType" -> document.requiredType.toJson,
+ "startDate" -> document.startDate.toJson,
+ "endDate" -> document.endDate.toJson,
+ "status" -> document.status.toJson,
+ "previousStatus" -> document.previousStatus.toJson,
+ "assignee" -> document.assignee.toJson,
+ "previousAssignee" -> document.previousAssignee.toJson,
+ "meta" -> document.meta.toJson,
+ "lastActiveUser" -> document.lastActiveUserId.toJson,
+ "lastUpdate" -> document.lastUpdate.toJson
+ )
+
+ override def read(json: JsValue): Document = json match {
+ case JsObject(fields) =>
+ val recordId = fields
+ .get("recordId")
+ .map(_.convertTo[LongId[MedicalRecord]])
+ .getOrElse(deserializationError(s"Document create json object does not contain `recordId` field: $json"))
+
+ val physician = fields
+ .get("physician")
+ .map(_.convertTo[String])
+
+ val typeId = fields
+ .get("typeId")
+ .map(_.convertTo[LongId[DocumentType]])
+
+ val provider = fields
+ .get("provider")
+ .map(_.convertTo[String])
+
+ val providerTypeId = fields
+ .get("providerTypeId")
+ .map(_.convertTo[LongId[ProviderType]])
+
+ val meta = fields
+ .get("meta")
+ .map(_.convertTo[TextJson[Meta]])
+
+ val startDate = fields
+ .get("startDate")
+ .map(_.convertTo[LocalDate])
+
+ val endDate = fields
+ .get("endDate")
+ .map(_.convertTo[LocalDate])
+
+ Document(
+ id = LongId(0),
+ recordId = recordId,
+ status = Document.Status.New,
+ physician = physician,
+ typeId = typeId,
+ startDate = startDate,
+ endDate = endDate,
+ providerName = provider,
+ providerTypeId = providerTypeId,
+ requiredType = None,
+ meta = meta,
+ previousStatus = None,
+ assignee = None,
+ previousAssignee = None,
+ lastActiveUserId = None,
+ lastUpdate = LocalDateTime.MIN
+ )
+
+ case _ => deserializationError(s"Expected Json Object as Document, but got $json")
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/documenthistory.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/documenthistory.scala
new file mode 100644
index 0000000..419c252
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/documenthistory.scala
@@ -0,0 +1,29 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.core.json.EnumJsonFormat
+import xyz.driver.pdsuidomain.entities._
+
+object documenthistory {
+ import DefaultJsonProtocol._
+ import common._
+ import DocumentHistory._
+
+ implicit val documentStateFormat = new EnumJsonFormat[State](
+ "Extract" -> State.Extract,
+ "Review" -> State.Review,
+ "Flag" -> State.Flag
+ )
+
+ implicit val documentActionFormat = new EnumJsonFormat[Action](
+ "Start" -> Action.Start,
+ "Submit" -> Action.Submit,
+ "Unassign" -> Action.Unassign,
+ "Resolve" -> Action.Resolve,
+ "Flag" -> Action.Flag,
+ "Archive" -> Action.Archive
+ )
+
+ implicit val documentHistoryFormat: RootJsonFormat[DocumentHistory] = jsonFormat6(DocumentHistory.apply)
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/documentissue.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/documentissue.scala
new file mode 100644
index 0000000..28b2a5e
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/documentissue.scala
@@ -0,0 +1,77 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import xyz.driver.pdsuicommon.domain.{LongId, StringId, User}
+import xyz.driver.pdsuidomain.entities._
+
+object documentissue {
+ import DefaultJsonProtocol._
+ import common._
+
+ def applyUpdateToDocumentIssue(json: JsValue, orig: DocumentIssue): DocumentIssue = json match {
+ case JsObject(fields) =>
+ val text = fields
+ .get("text")
+ .map(_.convertTo[String])
+ .getOrElse(deserializationError(s"DocumentIssue json object does not contain `text` field: $json"))
+
+ val archiveRequired = fields
+ .get("archiveRequired")
+ .map(_.convertTo[Boolean])
+ .getOrElse(deserializationError(s"DocumentIssue json object does not contain `archiveRequired` field: $json"))
+
+ val startPage = fields.get("startPage").map(_.convertTo[Double])
+ val endPage = fields.get("endPage").map(_.convertTo[Double])
+
+ orig.copy(
+ text = text,
+ archiveRequired = archiveRequired,
+ startPage = startPage,
+ endPage = endPage
+ )
+
+ case _ => deserializationError(s"Expected Json Object as partial DocumentIssue, but got $json")
+
+ }
+
+ def jsValueToDocumentIssue(json: JsValue, documentId: LongId[Document], userId: StringId[User]): DocumentIssue =
+ json match {
+ case JsObject(fields) =>
+ val text = fields
+ .get("text")
+ .map(_.convertTo[String])
+ .getOrElse(deserializationError(s"DocumentIssue json object does not contain `text` field: $json"))
+
+ val startPage = fields.get("startPage").map(_.convertTo[Double])
+ val endPage = fields.get("endPage").map(_.convertTo[Double])
+ DocumentIssue(
+ id = LongId(0),
+ userId = userId,
+ documentId = documentId,
+ lastUpdate = LocalDateTime.MIN,
+ isDraft = true,
+ text = text,
+ archiveRequired = false,
+ startPage = startPage,
+ endPage = endPage
+ )
+
+ case _ => deserializationError(s"Expected Json Object as DocumentIssue, but got $json")
+ }
+
+ implicit val documentIssueWriter = new JsonWriter[DocumentIssue] {
+ override def write(obj: DocumentIssue) = JsObject(
+ "id" -> obj.id.toJson,
+ "startPage" -> obj.startPage.toJson,
+ "endPage" -> obj.endPage.toJson,
+ "text" -> obj.text.toJson,
+ "lastUpdate" -> obj.lastUpdate.toJson,
+ "userId" -> obj.userId.toJson,
+ "isDraft" -> obj.isDraft.toJson,
+ "archiveRequired" -> obj.archiveRequired.toJson
+ )
+ }
+
+}
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
new file mode 100644
index 0000000..20b6ed0
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/export.scala
@@ -0,0 +1,78 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuidomain.entities.export.patient._
+import xyz.driver.pdsuidomain.entities.export.trial.{ExportTrialArm, ExportTrialLabelCriterion, ExportTrialWithLabels}
+
+object export {
+ import DefaultJsonProtocol._
+ import common._
+ import record._
+
+ implicit val patientLabelEvidenceDocumentFormat: RootJsonFormat[ExportPatientLabelEvidenceDocument] = jsonFormat5(
+ ExportPatientLabelEvidenceDocument.apply)
+
+ implicit val patientLabelEvidenceWriter: JsonWriter[ExportPatientLabelEvidence] =
+ new JsonWriter[ExportPatientLabelEvidence] {
+ override def write(obj: ExportPatientLabelEvidence): JsValue =
+ JsObject(
+ "evidenceId" -> obj.id.toJson,
+ "labelValue" -> obj.value.toJson,
+ "evidenceText" -> obj.evidenceText.toJson,
+ "document" -> obj.document.toJson
+ )
+ }
+
+ implicit val patientLabelWriter: JsonWriter[ExportPatientLabel] = new JsonWriter[ExportPatientLabel] {
+ override def write(obj: ExportPatientLabel): JsValue =
+ JsObject(
+ "labelId" -> obj.id.toJson,
+ "evidence" -> obj.evidences.map(_.toJson).toJson
+ )
+ }
+
+ implicit val patientWithLabelsWriter: JsonWriter[ExportPatientWithLabels] = new JsonWriter[ExportPatientWithLabels] {
+ override def write(obj: ExportPatientWithLabels): JsValue =
+ JsObject(
+ "patientId" -> obj.patientId.toJson,
+ "labelVersion" -> obj.labelVersion.toJson,
+ "labels" -> obj.labels.map(_.toJson).toJson
+ )
+ }
+
+ implicit val trialArmFormat: RootJsonFormat[ExportTrialArm] = jsonFormat2(ExportTrialArm.apply)
+
+ implicit val trialLabelCriterionWriter: JsonWriter[ExportTrialLabelCriterion] =
+ new JsonWriter[ExportTrialLabelCriterion] {
+ override def write(obj: ExportTrialLabelCriterion): JsValue =
+ JsObject(
+ "value" -> obj.value
+ .map {
+ case true => "Yes"
+ case false => "No"
+ }
+ .getOrElse("Unknown")
+ .toJson,
+ "labelId" -> obj.labelId.toJson,
+ "criterionId" -> obj.criterionId.toJson,
+ "criterionText" -> obj.criteria.toJson,
+ "armIds" -> obj.armIds.toJson,
+ "isCompound" -> obj.isCompound.toJson,
+ "isDefining" -> obj.isDefining.toJson
+ )
+ }
+
+ implicit val trialWithLabelsWriter: JsonWriter[ExportTrialWithLabels] = new JsonWriter[ExportTrialWithLabels] {
+ override def write(obj: ExportTrialWithLabels) =
+ JsObject(
+ "nctId" -> obj.nctId.toJson,
+ "trialId" -> obj.trialId.toJson,
+ "disease" -> obj.condition.toJson,
+ "lastReviewed" -> obj.lastReviewed.toJson,
+ "labelVersion" -> obj.labelVersion.toJson,
+ "arms" -> obj.arms.toJson,
+ "criteria" -> obj.criteria.map(_.toJson).toJson
+ )
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/extracteddata.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/extracteddata.scala
new file mode 100644
index 0000000..42473bc
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/extracteddata.scala
@@ -0,0 +1,148 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuicommon.domain.{FuzzyValue, LongId, TextJson}
+import xyz.driver.pdsuidomain.entities._
+import xyz.driver.pdsuidomain.services.ExtractedDataService.RichExtractedData
+
+object extracteddata {
+ import DefaultJsonProtocol._
+ import common._
+ import ExtractedData._
+
+ implicit val metaKeywordFormat: RootJsonFormat[Meta.Keyword] = jsonFormat4(Meta.Keyword)
+ implicit val metaTextLayerPositionFormat: RootJsonFormat[Meta.TextLayerPosition] = jsonFormat3(
+ Meta.TextLayerPosition)
+ implicit val metaEvidenceFormat: RootJsonFormat[Meta.Evidence] = jsonFormat3(Meta.Evidence)
+
+ implicit val extractedDataMetaFormat: RootJsonFormat[Meta] = jsonFormat2(Meta.apply)
+ implicit val fullExtractedDataMetaFormat = new RootJsonFormat[TextJson[Meta]] {
+ override def write(obj: TextJson[Meta]): JsValue = obj.content.toJson
+ override def read(json: JsValue): TextJson[Meta] = TextJson(extractedDataMetaFormat.read(json))
+ }
+
+ implicit val extractedDataLabelWriter: JsonWriter[ExtractedDataLabel] = new JsonWriter[ExtractedDataLabel] {
+ override def write(label: ExtractedDataLabel): JsObject = {
+ JsObject(
+ "id" -> label.labelId.toJson,
+ "categoryId" -> label.categoryId.toJson,
+ "value" -> label.value.toJson
+ )
+ }
+ }
+
+ def applyLabelsForExtractedData(json: JsValue, dataId: LongId[ExtractedData]): ExtractedDataLabel = json match {
+ case JsObject(fields) =>
+ val labelId = fields
+ .get("id")
+ .map(_.convertTo[LongId[Label]])
+
+ val categoryId = fields
+ .get("categoryId")
+ .map(_.convertTo[LongId[Category]])
+
+ val value = fields
+ .get("value")
+ .map(_.convertTo[FuzzyValue])
+
+ ExtractedDataLabel(
+ id = LongId(0),
+ dataId = dataId,
+ labelId = labelId,
+ categoryId = categoryId,
+ value = value
+ )
+
+ case _ => deserializationError(s"Expected Json Object as ExtractedDataLabel, but got $json")
+ }
+
+ def applyUpdateToExtractedData(json: JsValue, orig: RichExtractedData): RichExtractedData = json match {
+ case JsObject(fields) =>
+ val keywordId = fields
+ .get("keywordId")
+ .map(_.convertTo[Option[LongId[Keyword]]])
+ .getOrElse(orig.extractedData.keywordId)
+
+ val evidence = fields
+ .get("evidence")
+ .map(_.convertTo[Option[String]])
+ .getOrElse(orig.extractedData.evidenceText)
+
+ val meta = fields
+ .get("meta")
+ .map(_.convertTo[Option[TextJson[Meta]]])
+ .getOrElse(orig.extractedData.meta)
+
+ val labels = fields
+ .get("labels")
+ .map(
+ _.convertTo[Option[List[JsValue]]]
+ .getOrElse(List.empty[JsValue])
+ .map(l => applyLabelsForExtractedData(l, orig.extractedData.id)))
+ .getOrElse(orig.labels)
+
+ val extractedData = orig.extractedData.copy(
+ keywordId = keywordId,
+ evidenceText = evidence,
+ meta = meta
+ )
+
+ orig.copy(
+ extractedData = extractedData,
+ labels = labels
+ )
+
+ case _ => deserializationError(s"Expected Json Object as partial ExtractedData, but got $json")
+ }
+
+ implicit val extractedDataFormat: RootJsonFormat[RichExtractedData] = new RootJsonFormat[RichExtractedData] {
+ override def write(richData: RichExtractedData): JsValue =
+ JsObject(
+ "id" -> richData.extractedData.id.id.toJson,
+ "documentId" -> richData.extractedData.documentId.toJson,
+ "keywordId" -> richData.extractedData.keywordId.toJson,
+ "evidence" -> richData.extractedData.evidenceText.toJson,
+ "meta" -> richData.extractedData.meta.toJson,
+ "labels" -> richData.labels.map(_.toJson).toJson
+ )
+
+ override def read(json: JsValue): RichExtractedData = json match {
+ case JsObject(fields) =>
+ val documentId = fields
+ .get("documentId")
+ .map(_.convertTo[LongId[Document]])
+ .getOrElse(
+ deserializationError(s"ExtractedData create json object does not contain `documentId` field: $json"))
+
+ val keywordId = fields
+ .get("keywordId")
+ .map(_.convertTo[LongId[Keyword]])
+
+ val evidence = fields
+ .get("evidence")
+ .map(_.convertTo[String])
+
+ val meta = fields
+ .get("meta")
+ .map(_.convertTo[TextJson[Meta]])
+
+ val labels = fields
+ .get("labels")
+ .map(_.convertTo[List[JsValue]])
+ .getOrElse(List.empty[JsValue])
+ .map(l => applyLabelsForExtractedData(l, LongId(0)))
+
+ val extractedData = ExtractedData(
+ documentId = documentId,
+ keywordId = keywordId,
+ evidenceText = evidence,
+ meta = meta
+ )
+
+ RichExtractedData(extractedData, labels)
+
+ case _ => deserializationError(s"Expected Json Object as ExtractedData, but got $json")
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/hypothesis.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/hypothesis.scala
new file mode 100644
index 0000000..c05ff23
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/hypothesis.scala
@@ -0,0 +1,12 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuidomain.entities._
+
+object hypothesis {
+ import DefaultJsonProtocol._
+ import common._
+
+ implicit val hypothesisFormat: RootJsonFormat[Hypothesis] = jsonFormat4(Hypothesis.apply)
+
+}
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
new file mode 100644
index 0000000..a8ce950
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/intervention.scala
@@ -0,0 +1,60 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuicommon.domain.LongId
+import xyz.driver.pdsuidomain.entities._
+
+object intervention {
+ import DefaultJsonProtocol._
+ import common._
+
+ implicit val interventionWriter: JsonWriter[InterventionWithArms] = new JsonWriter[InterventionWithArms] {
+ override def write(obj: InterventionWithArms) =
+ JsObject(
+ "id" -> obj.intervention.id.toJson,
+ "name" -> obj.intervention.name.toJson,
+ "typeId" -> obj.intervention.typeId.toJson,
+ "description" -> obj.intervention.description.toJson,
+ "isActive" -> obj.intervention.isActive.toJson,
+ "arms" -> obj.arms.map(_.armId).toJson,
+ "trialId" -> obj.intervention.trialId.toJson,
+ "originalName" -> obj.intervention.originalName.toJson,
+ "originalDescription" -> obj.intervention.originalDescription.toJson,
+ "originalType" -> obj.intervention.originalType.toJson
+ )
+ }
+
+ def applyUpdateToInterventionWithArms(json: JsValue, orig: InterventionWithArms): InterventionWithArms = json match {
+ case JsObject(fields) =>
+ val typeId = fields
+ .get("typeId")
+ .map(_.convertTo[LongId[InterventionType]])
+
+ val description = fields
+ .get("description")
+ .map(_.convertTo[String])
+
+ val isActive = fields
+ .get("isActive")
+ .map(_.convertTo[Boolean])
+
+ val origIntervention = orig.intervention
+ val arms = fields
+ .get("arms")
+ .map(_.convertTo[List[LongId[Arm]]].map(x => InterventionArm(x, orig.intervention.id)))
+
+ orig.copy(
+ intervention = origIntervention.copy(
+ typeId = typeId.orElse(origIntervention.typeId),
+ description = description.getOrElse(origIntervention.description),
+ isActive = isActive.getOrElse(origIntervention.isActive)
+ ),
+ arms = arms.getOrElse(orig.arms)
+ )
+
+ case _ => deserializationError(s"Expected Json Object as partial Intervention, but got $json")
+ }
+
+ implicit val interventionTypeFormat: RootJsonFormat[InterventionType] = jsonFormat2(InterventionType.apply)
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patient.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patient.scala
new file mode 100644
index 0000000..724c391
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patient.scala
@@ -0,0 +1,46 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.core.json.EnumJsonFormat
+import xyz.driver.pdsuidomain.entities._
+
+object patient {
+ import DefaultJsonProtocol._
+ import common._
+ import Patient._
+
+ implicit val patientStatusFormat = new EnumJsonFormat[Status](
+ "New" -> Status.New,
+ "Verified" -> Status.Verified,
+ "Reviewed" -> Status.Reviewed,
+ "Curated" -> Status.Curated,
+ "Done" -> Status.Done,
+ "Flagged" -> Status.Flagged
+ )
+
+ implicit val patientOrderIdFormat = new RootJsonFormat[PatientOrderId] {
+ override def write(orderId: PatientOrderId): JsString = JsString(orderId.toString)
+ override def read(json: JsValue): PatientOrderId = json match {
+ case JsString(value) => PatientOrderId(value)
+ case _ => deserializationError(s"Expected string as PatientOrderId, but got $json")
+ }
+ }
+
+ implicit val patientWriter: JsonWriter[Patient] = new JsonWriter[Patient] {
+ override def write(patient: Patient): JsValue =
+ JsObject(
+ "id" -> patient.id.toJson,
+ "status" -> patient.status.toJson,
+ "name" -> patient.name.toJson,
+ "dob" -> patient.dob.toJson,
+ "assignee" -> patient.assignee.toJson,
+ "previousStatus" -> patient.previousStatus.toJson,
+ "previousAssignee" -> patient.previousAssignee.toJson,
+ "lastActiveUser" -> patient.lastActiveUserId.toJson,
+ "lastUpdate" -> patient.lastUpdate.toJson,
+ "condition" -> patient.condition.toJson,
+ "orderId" -> patient.orderId.toJson
+ )
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientcriterion.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientcriterion.scala
new file mode 100644
index 0000000..53e927d
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientcriterion.scala
@@ -0,0 +1,68 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuicommon.domain.{FuzzyValue, LongId}
+import xyz.driver.pdsuidomain.entities._
+import xyz.driver.pdsuidomain.services.PatientCriterionService.DraftPatientCriterion
+
+object patientcriterion {
+ import DefaultJsonProtocol._
+ import common._
+
+ def applyUpdateToPatientCriterion(json: JsValue, orig: PatientCriterion): PatientCriterion = json match {
+ case JsObject(fields) =>
+ val eligibilityStatus = if (fields.contains("eligibilityStatus")) {
+ fields
+ .get("eligibilityStatus")
+ .map(_.convertTo[FuzzyValue])
+ } else orig.eligibilityStatus
+
+ val verifiedEligibilityStatus = if (fields.contains("verifiedEligibilityStatus")) {
+ fields
+ .get("verifiedEligibilityStatus")
+ .map(_.convertTo[FuzzyValue])
+ } else orig.verifiedEligibilityStatus
+
+ orig.copy(
+ eligibilityStatus = eligibilityStatus,
+ verifiedEligibilityStatus = verifiedEligibilityStatus
+ )
+
+ case _ => deserializationError(s"Expected Json Object as partial PatientCriterion, but got $json")
+ }
+
+ implicit val draftPatientCriterionFormat: RootJsonFormat[DraftPatientCriterion] = jsonFormat3(
+ DraftPatientCriterion.apply)
+ implicit val draftPatientCriterionListReader = new JsonReader[List[DraftPatientCriterion]] {
+ override def read(json: JsValue) = json.convertTo[List[JsValue]].map(_.convertTo[DraftPatientCriterion])
+ }
+
+ implicit val patientCriterionWriter: JsonWriter[(PatientCriterion, LongId[Label], List[PatientCriterionArm])] =
+ new JsonWriter[(PatientCriterion, LongId[Label], List[PatientCriterionArm])] {
+ override def write(obj: (PatientCriterion, LongId[Label], List[PatientCriterionArm])): JsValue = {
+ val criterion = obj._1
+ val labelId = obj._2
+ val arms = obj._3
+ JsObject(
+ "id" -> criterion.id.toJson,
+ "labelId" -> labelId.toJson,
+ "nctId" -> criterion.nctId.toJson,
+ "criterionId" -> criterion.criterionId.toJson,
+ "criterionText" -> criterion.criterionText.toJson,
+ "criterionValue" -> criterion.criterionValue.map {
+ case true => "Yes"
+ case false => "No"
+ }.toJson,
+ "criterionIsDefining" -> criterion.criterionIsDefining.toJson,
+ "criterionIsCompound" -> criterion.criterionValue.isEmpty.toJson,
+ "arms" -> arms.map(_.armName).toJson,
+ "eligibilityStatus" -> criterion.eligibilityStatus.toJson,
+ "verifiedEligibilityStatus" -> criterion.verifiedEligibilityStatus.toJson,
+ "isVerified" -> criterion.isVerified.toJson,
+ "isVisible" -> criterion.isVisible.toJson,
+ "lastUpdate" -> criterion.lastUpdate.toJson
+ )
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientdefiningcriteria.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientdefiningcriteria.scala
new file mode 100644
index 0000000..b97570a
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientdefiningcriteria.scala
@@ -0,0 +1,18 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuidomain.entities.PatientLabel
+
+object patientdefiningcriteria {
+ import DefaultJsonProtocol._
+ import common._
+
+ implicit val patientLabelDefiningCriteriaWriter: JsonWriter[PatientLabel] = new JsonWriter[PatientLabel] {
+ override def write(obj: PatientLabel) =
+ JsObject(
+ "id" -> obj.id.toJson,
+ "value" -> obj.verifiedPrimaryValue.toJson
+ )
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienteligibletrial.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienteligibletrial.scala
new file mode 100644
index 0000000..894e453
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienteligibletrial.scala
@@ -0,0 +1,39 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuidomain.entities._
+import xyz.driver.pdsuidomain.services.PatientEligibleTrialService.RichPatientEligibleTrial
+
+object patienteligibletrial {
+ import DefaultJsonProtocol._
+ import common._
+
+ def applyUpdateToTrialArmGroup(json: JsValue, orig: PatientTrialArmGroupView): PatientTrialArmGroupView =
+ json match {
+ case JsObject(fields) =>
+ val isVerified = fields
+ .get("isVerified")
+ .map(_.convertTo[Boolean])
+ .getOrElse(orig.isVerified)
+
+ orig.copy(isVerified = isVerified)
+
+ case _ => deserializationError(s"Expected Json Object as partial PatientTrialArmGroupView, but got $json")
+ }
+
+ implicit val patientEligibleTrialWriter: JsonWriter[RichPatientEligibleTrial] =
+ new JsonWriter[RichPatientEligibleTrial] {
+ override def write(obj: RichPatientEligibleTrial) =
+ JsObject(
+ "id" -> obj.group.id.toJson,
+ "patientId" -> obj.group.patientId.toJson,
+ "trialId" -> obj.group.trialId.toJson,
+ "trialTitle" -> obj.trial.title.toJson,
+ "arms" -> obj.arms.map(_.armName).toJson,
+ "hypothesisId" -> obj.trial.hypothesisId.toJson,
+ "verifiedEligibilityStatus" -> obj.group.verifiedEligibilityStatus.toJson,
+ "isVerified" -> obj.group.isVerified.toJson
+ )
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienthistory.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienthistory.scala
new file mode 100644
index 0000000..da7a664
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienthistory.scala
@@ -0,0 +1,30 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.core.json.EnumJsonFormat
+import xyz.driver.pdsuidomain.entities._
+
+object patienthistory {
+ import DefaultJsonProtocol._
+ import common._
+ import PatientHistory._
+
+ implicit val patientStateFormat = new EnumJsonFormat[State](
+ "Verify" -> State.Verify,
+ "Curate" -> State.Curate,
+ "Review" -> State.Review,
+ "Flag" -> State.Flag
+ )
+
+ implicit val patientActionFormat = new EnumJsonFormat[Action](
+ "Start" -> Action.Start,
+ "Submit" -> Action.Submit,
+ "Unassign" -> Action.Unassign,
+ "Resolve" -> Action.Resolve,
+ "Flag" -> Action.Flag,
+ "Archive" -> Action.Archive
+ )
+
+ implicit val patientHistoryFormat: RootJsonFormat[PatientHistory] = jsonFormat6(PatientHistory.apply)
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienthypothesis.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienthypothesis.scala
new file mode 100644
index 0000000..4f2783c
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patienthypothesis.scala
@@ -0,0 +1,37 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuidomain.entities._
+
+object patienthypothesis {
+ import DefaultJsonProtocol._
+ import common._
+
+ def applyUpdateToPatientHypothesis(json: JsValue, orig: PatientHypothesis): PatientHypothesis = json match {
+ case JsObject(fields) =>
+ val rationale = if (fields.contains("rationale")) {
+ fields.get("rationale").map(_.convertTo[String])
+ } else orig.rationale
+
+ orig.copy(rationale = rationale)
+
+ case _ => deserializationError(s"Expected Json Object as partial PatientHypothesis, but got $json")
+ }
+
+ implicit val patientHypothesisWriter: JsonWriter[(PatientHypothesis, Boolean)] =
+ new JsonWriter[(PatientHypothesis, Boolean)] {
+ override def write(obj: (PatientHypothesis, Boolean)): JsValue = {
+ val patientHypothesis = obj._1
+ val isRationaleRequired = obj._2
+ JsObject(
+ "id" -> patientHypothesis.id.toJson,
+ "patientId" -> patientHypothesis.patientId.toJson,
+ "hypothesisId" -> patientHypothesis.hypothesisId.toJson,
+ "matchedTrials" -> patientHypothesis.matchedTrials.toJson,
+ "rationale" -> patientHypothesis.rationale.toJson,
+ "isRationaleRequired" -> isRationaleRequired.toJson
+ )
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientissue.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientissue.scala
new file mode 100644
index 0000000..7d35bd1
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientissue.scala
@@ -0,0 +1,54 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import xyz.driver.pdsuicommon.domain.{LongId, StringId, User, UuidId}
+import xyz.driver.pdsuidomain.entities._
+
+object patientissue {
+ import DefaultJsonProtocol._
+ import common._
+
+ def applyUpdateToPatientIssue(json: JsValue, orig: PatientIssue): PatientIssue = {
+ json.asJsObject.getFields("text", "archiveRequired") match {
+ case Seq(text, archiveRequired) =>
+ orig.copy(
+ text = text.convertTo[String],
+ archiveRequired = archiveRequired.convertTo[Boolean]
+ )
+
+ case _ => deserializationError(s"Expected Json Object as partial PatientIssue, but got $json")
+ }
+ }
+
+ def jsValueToPatientIssue(json: JsValue, patientId: UuidId[Patient], userId: StringId[User]): PatientIssue = {
+ json.asJsObject.getFields("text") match {
+ case Seq(text) =>
+ PatientIssue(
+ id = LongId(0),
+ userId = userId,
+ patientId = patientId,
+ lastUpdate = LocalDateTime.MIN,
+ isDraft = true,
+ text = text.convertTo[String],
+ archiveRequired = false
+ )
+
+ case _ => deserializationError(s"Expected Json Object as PatientIssue, but got $json")
+ }
+
+ }
+
+ implicit val patientIssueWriter = new JsonWriter[PatientIssue] {
+ override def write(obj: PatientIssue) = JsObject(
+ "id" -> obj.id.toJson,
+ "text" -> obj.text.toJson,
+ "lastUpdate" -> obj.lastUpdate.toJson,
+ "userId" -> obj.userId.toJson,
+ "isDraft" -> obj.isDraft.toJson,
+ "archiveRequired" -> obj.archiveRequired.toJson
+ )
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientlabel.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientlabel.scala
new file mode 100644
index 0000000..3b52833
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/patientlabel.scala
@@ -0,0 +1,64 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuicommon.domain.FuzzyValue
+import xyz.driver.pdsuidomain.entities._
+
+object patientlabel {
+ import DefaultJsonProtocol._
+ import common._
+
+ def applyUpdateToPatientLabel(json: JsValue, orig: PatientLabel): PatientLabel = json match {
+ case JsObject(fields) =>
+ val primaryValue = fields
+ .get("primaryValue")
+ .map(_.convertTo[Option[FuzzyValue]])
+ .getOrElse(orig.primaryValue)
+
+ val verifiedPrimaryValue = fields
+ .get("verifiedPrimaryValue")
+ .map(_.convertTo[Option[FuzzyValue]])
+ .getOrElse(orig.verifiedPrimaryValue)
+
+ orig.copy(
+ primaryValue = primaryValue,
+ verifiedPrimaryValue = verifiedPrimaryValue
+ )
+
+ case _ => deserializationError(s"Expected Json Object as PatientLabel, but got $json")
+ }
+
+ implicit val patientLabelWriter: JsonWriter[(PatientLabel, Boolean)] = new JsonWriter[(PatientLabel, Boolean)] {
+ override def write(obj: (PatientLabel, Boolean)): JsValue = {
+ val patientLabel = obj._1
+ val isVerified = obj._2
+ JsObject(
+ "id" -> patientLabel.id.toJson,
+ "labelId" -> patientLabel.labelId.toJson,
+ "primaryValue" -> patientLabel.primaryValue.toJson,
+ "verifiedPrimaryValue" -> patientLabel.verifiedPrimaryValue.toJson,
+ "score" -> patientLabel.score.toJson,
+ "isImplicitMatch" -> patientLabel.isImplicitMatch.toJson,
+ "isVisible" -> patientLabel.isVisible.toJson,
+ "isVerified" -> isVerified.toJson
+ )
+ }
+ }
+
+ implicit val patientLabelEvidenceWriter: JsonWriter[PatientLabelEvidenceView] =
+ new JsonWriter[PatientLabelEvidenceView] {
+ override def write(evidence: PatientLabelEvidenceView): JsValue =
+ JsObject(
+ "id" -> evidence.id.toJson,
+ "value" -> evidence.value.toJson,
+ "evidenceText" -> evidence.evidenceText.toJson,
+ "documentId" -> evidence.documentId.toJson,
+ "evidenceId" -> evidence.evidenceId.toJson,
+ "reportId" -> evidence.reportId.toJson,
+ "documentType" -> evidence.documentType.toJson,
+ "date" -> evidence.date.toJson,
+ "providerType" -> evidence.providerType.toJson
+ )
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/record.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/record.scala
new file mode 100644
index 0000000..e378dbd
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/record.scala
@@ -0,0 +1,237 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+import java.util.UUID
+
+import spray.json._
+import xyz.driver.core.json.{EnumJsonFormat, GadtJsonFormat}
+import xyz.driver.pdsuicommon.domain.{LongId, TextJson, UuidId}
+import xyz.driver.pdsuidomain.entities.MedicalRecord.Meta._
+import xyz.driver.pdsuidomain.entities._
+
+object record {
+ import DefaultJsonProtocol._
+ import MedicalRecord._
+ import common._
+
+ implicit val recordStatusFormat = new EnumJsonFormat[Status](
+ "Unprocessed" -> Status.Unprocessed,
+ "PreOrganized" -> Status.PreOrganized,
+ "New" -> Status.New,
+ "Cleaned" -> Status.Cleaned,
+ "PreOrganized" -> Status.PreOrganized,
+ "PreOrganizing" -> Status.PreOrganizing,
+ "Reviewed" -> Status.Reviewed,
+ "Organized" -> Status.Organized,
+ "Done" -> Status.Done,
+ "Flagged" -> Status.Flagged,
+ "Archived" -> Status.Archived
+ )
+
+ implicit val requestIdFormat = new RootJsonFormat[RecordRequestId] {
+ override def write(requestId: RecordRequestId): JsString = JsString(requestId.toString)
+ override def read(json: JsValue): RecordRequestId = json match {
+ case JsString(value) => RecordRequestId(UUID.fromString(value))
+ case _ => deserializationError(s"Expected string as RecordRequestId, but got $json")
+ }
+ }
+
+ implicit val caseIdFormat = new RootJsonFormat[CaseId] {
+ override def write(caseId: CaseId): JsString = JsString(caseId.toString)
+ override def read(json: JsValue): CaseId = json match {
+ case JsString(value) => CaseId(value)
+ case _ => deserializationError(s"Expected string as CaseId, but got $json")
+ }
+ }
+
+ implicit val duplicateMetaFormat: RootJsonFormat[Duplicate] = new RootJsonFormat[Duplicate] {
+ override def write(obj: Duplicate) =
+ JsObject(
+ "type" -> "duplicate".toJson,
+ "predicted" -> obj.predicted.toJson,
+ "startPage" -> obj.startPage.toJson,
+ "endPage" -> obj.endPage.toJson,
+ "startOriginalPage" -> obj.startOriginalPage.toJson,
+ "endOriginalPage" -> obj.endOriginalPage.toJson
+ )
+
+ override def read(json: JsValue): Duplicate = json match {
+ case JsObject(fields) =>
+ val predicted = fields
+ .get("predicted")
+ .map(_.convertTo[Boolean])
+
+ val startPage = fields
+ .get("startPage")
+ .map(_.convertTo[Double])
+ .getOrElse(deserializationError(s"Duplicate meta json object does not contain `startPage` field: $json"))
+
+ val endPage = fields
+ .get("endPage")
+ .map(_.convertTo[Double])
+ .getOrElse(deserializationError(s"Duplicate meta json object does not contain `endPage` field: $json"))
+
+ val startOriginalPage = fields
+ .get("startOriginalPage")
+ .map(_.convertTo[Double])
+ .getOrElse(
+ deserializationError(s"Duplicate meta json object does not contain `startOriginalPage` field: $json"))
+
+ val endOriginalPage = fields
+ .get("endOriginalPage")
+ .map(_.convertTo[Double])
+
+ Duplicate(
+ predicted = predicted,
+ startPage = startPage,
+ endPage = endPage,
+ startOriginalPage = startOriginalPage,
+ endOriginalPage = endOriginalPage
+ )
+
+ case _ => deserializationError(s"Expected JsObject as Duplicate meta of medical record, but got $json")
+ }
+ }
+
+ implicit val reorderMetaFormat: RootJsonFormat[Reorder] = new RootJsonFormat[Reorder] {
+ override def write(obj: Reorder) =
+ JsObject(
+ "type" -> "reorder".toJson,
+ "predicted" -> obj.predicted.toJson,
+ "items" -> obj.items.toJson
+ )
+
+ override def read(json: JsValue): Reorder = json match {
+ case JsObject(fields) =>
+ val predicted = fields
+ .get("predicted")
+ .map(_.convertTo[Boolean])
+
+ val items = fields
+ .get("items")
+ .map(_.convertTo[Seq[Int]])
+ .getOrElse(deserializationError(s"Reorder meta json object does not contain `items` field: $json"))
+
+ Reorder(
+ predicted = predicted,
+ items = items
+ )
+
+ case _ => deserializationError(s"Expected JsObject as Reorder meta of medical record, but got $json")
+ }
+ }
+
+ implicit val rotateMetaFormat: RootJsonFormat[Rotation] = new RootJsonFormat[Rotation] {
+ override def write(obj: Rotation) =
+ JsObject(
+ "type" -> "rotation".toJson,
+ "predicted" -> obj.predicted.toJson,
+ "items" -> obj.items.toJson
+ )
+
+ override def read(json: JsValue): Rotation = json match {
+ case JsObject(fields) =>
+ val predicted = fields
+ .get("predicted")
+ .map(_.convertTo[Boolean])
+
+ val items = fields
+ .get("items")
+ .map(_.convertTo[Map[String, Int]])
+ .getOrElse(deserializationError(s"Rotation meta json object does not contain `items` field: $json"))
+
+ Rotation(
+ predicted = predicted,
+ items = items
+ )
+
+ case _ => deserializationError(s"Expected JsObject as Rotation meta of medical record, but got $json")
+ }
+ }
+
+ implicit val recordMetaTypeFormat: GadtJsonFormat[MedicalRecord.Meta] = {
+ GadtJsonFormat.create[Meta]("type")({ case m => m.metaType }) {
+ case "duplicate" => duplicateMetaFormat
+ case "reorder" => reorderMetaFormat
+ case "rotation" => rotateMetaFormat
+ }
+ }
+
+ implicit val recordMetaFormat = new RootJsonFormat[TextJson[List[Meta]]] {
+ override def write(obj: TextJson[List[Meta]]): JsArray = JsArray(obj.content.map(_.toJson).toVector)
+ override def read(json: JsValue): TextJson[List[Meta]] = json match {
+ case JsArray(values) => TextJson[List[Meta]](values.map(_.convertTo[Meta]).toList)
+ case _ => deserializationError(s"Expected array as Meta, but got $json")
+ }
+ }
+
+ implicit val recordFormat: RootJsonFormat[MedicalRecord] =
+ new RootJsonFormat[MedicalRecord] {
+ override def write(record: MedicalRecord): JsValue =
+ JsObject(
+ "id" -> record.id.id.toJson,
+ "patientId" -> record.patientId.toJson,
+ "caseId" -> record.caseId.toJson,
+ "disease" -> record.disease.toJson,
+ "physician" -> record.physician.toJson,
+ "status" -> record.status.toJson,
+ "previousStatus" -> record.previousStatus.toJson,
+ "assignee" -> record.assignee.toJson,
+ "previousAssignee" -> record.previousAssignee.toJson,
+ "requestId" -> record.requestId.toJson,
+ "meta" -> record.meta.getOrElse(TextJson[List[Meta]](List.empty)).toJson,
+ "lastActiveUser" -> record.lastActiveUserId.toJson,
+ "lastUpdate" -> record.lastUpdate.toJson
+ )
+
+ override def read(json: JsValue): MedicalRecord = json match {
+ case JsObject(fields) =>
+ val disease = fields
+ .get("disease")
+ .map(_.convertTo[String])
+ .getOrElse(deserializationError(s"MedicalRecord json object does not contain `disease` field: $json"))
+
+ val patientId = fields
+ .get("patientId")
+ .map(_.convertTo[UuidId[Patient]])
+ .getOrElse(deserializationError(s"MedicalRecord json object does not contain `patientId` field: $json"))
+
+ val requestId = fields
+ .get("requestId")
+ .map(_.convertTo[RecordRequestId])
+ .getOrElse(deserializationError(s"MedicalRecord json object does not contain `requestId` field: $json"))
+
+ MedicalRecord(
+ id = LongId(0),
+ status = MedicalRecord.Status.New,
+ previousStatus = None,
+ assignee = None,
+ previousAssignee = None,
+ lastActiveUserId = None,
+ patientId = patientId,
+ requestId = requestId,
+ disease = disease,
+ caseId = None,
+ physician = None,
+ meta = None,
+ predictedMeta = None,
+ predictedDocuments = None,
+ lastUpdate = LocalDateTime.now()
+ )
+
+ case _ => deserializationError(s"Expected Json Object as MedicalRecord, but got $json")
+ }
+ }
+
+ def applyUpdateToMedicalRecord(json: JsValue, orig: MedicalRecord): MedicalRecord = json match {
+ case JsObject(fields) =>
+ val meta = fields
+ .get("meta")
+ .map(_.convertTo[Option[TextJson[List[Meta]]]])
+ .getOrElse(orig.meta)
+ orig.copy(meta = meta)
+
+ case _ => deserializationError(s"Expected Json Object as partial MedicalRecord, but got $json")
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/recordhistory.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/recordhistory.scala
new file mode 100644
index 0000000..bd14d43
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/recordhistory.scala
@@ -0,0 +1,30 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.core.json.EnumJsonFormat
+import xyz.driver.pdsuidomain.entities._
+
+object recordhistory {
+ import DefaultJsonProtocol._
+ import common._
+ import MedicalRecordHistory._
+
+ implicit val recordStateFormat = new EnumJsonFormat[State](
+ "Clean" -> State.Clean,
+ "Organize" -> State.Organize,
+ "Review" -> State.Review,
+ "Flag" -> State.Flag
+ )
+
+ implicit val recordActionFormat = new EnumJsonFormat[Action](
+ "Start" -> Action.Start,
+ "Submit" -> Action.Submit,
+ "Unassign" -> Action.Unassign,
+ "Resolve" -> Action.Resolve,
+ "Flag" -> Action.Flag,
+ "Archive" -> Action.Archive
+ )
+
+ implicit val recordHistoryFormat: RootJsonFormat[MedicalRecordHistory] = jsonFormat6(MedicalRecordHistory.apply)
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/recordissue.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/recordissue.scala
new file mode 100644
index 0000000..4ae04d0
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/recordissue.scala
@@ -0,0 +1,79 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import xyz.driver.pdsuicommon.domain.{LongId, StringId, User}
+import xyz.driver.pdsuidomain.entities._
+
+object recordissue {
+ import DefaultJsonProtocol._
+ import common._
+
+ def applyUpdateToRecordIssue(json: JsValue, orig: MedicalRecordIssue): MedicalRecordIssue = json match {
+ case JsObject(fields) =>
+ val text = fields
+ .get("text")
+ .map(_.convertTo[String])
+ .getOrElse(deserializationError(s"MedicalRecordIssue json object does not contain `text` field: $json"))
+
+ val archiveRequired = fields
+ .get("archiveRequired")
+ .map(_.convertTo[Boolean])
+ .getOrElse(
+ deserializationError(s"MedicalRecordIssue json object does not contain `archiveRequired` field: $json"))
+
+ val startPage = fields.get("startPage").map(_.convertTo[Double])
+ val endPage = fields.get("endPage").map(_.convertTo[Double])
+
+ orig.copy(
+ text = text,
+ archiveRequired = archiveRequired,
+ startPage = startPage,
+ endPage = endPage
+ )
+
+ case _ => deserializationError(s"Expected Json Object as partial MedicalRecordIssue, but got $json")
+
+ }
+
+ def jsValueToRecordIssue(json: JsValue,
+ recordId: LongId[MedicalRecord],
+ userId: StringId[User]): MedicalRecordIssue = json match {
+ case JsObject(fields) =>
+ val text = fields
+ .get("text")
+ .map(_.convertTo[String])
+ .getOrElse(deserializationError(s"MedicalRecordIssue json object does not contain `text` field: $json"))
+
+ val startPage = fields.get("startPage").map(_.convertTo[Double])
+ val endPage = fields.get("endPage").map(_.convertTo[Double])
+ MedicalRecordIssue(
+ id = LongId(0),
+ userId = userId,
+ recordId = recordId,
+ lastUpdate = LocalDateTime.MIN,
+ isDraft = true,
+ text = text,
+ archiveRequired = false,
+ startPage = startPage,
+ endPage = endPage
+ )
+
+ case _ => deserializationError(s"Expected Json Object as MedicalRecordIssue, but got $json")
+ }
+
+ implicit val recordIssueWriter = new JsonWriter[MedicalRecordIssue] {
+ override def write(obj: MedicalRecordIssue) = JsObject(
+ "id" -> obj.id.toJson,
+ "startPage" -> obj.startPage.toJson,
+ "endPage" -> obj.endPage.toJson,
+ "text" -> obj.text.toJson,
+ "lastUpdate" -> obj.lastUpdate.toJson,
+ "userId" -> obj.userId.toJson,
+ "isDraft" -> obj.isDraft.toJson,
+ "archiveRequired" -> obj.archiveRequired.toJson
+ )
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/studydesign.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/studydesign.scala
new file mode 100644
index 0000000..e801666
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/studydesign.scala
@@ -0,0 +1,12 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.pdsuidomain.entities._
+
+object studydesign {
+ import DefaultJsonProtocol._
+ import common._
+
+ implicit val studyDesignFormat: RootJsonFormat[StudyDesign] = jsonFormat2(StudyDesign.apply)
+
+}
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
new file mode 100644
index 0000000..c1751bf
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trial.scala
@@ -0,0 +1,90 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.{ZoneId, ZonedDateTime}
+
+import spray.json._
+import xyz.driver.core.json.EnumJsonFormat
+import xyz.driver.pdsuicommon.domain.{LongId, UuidId}
+import xyz.driver.pdsuidomain.entities._
+
+object trial {
+ import DefaultJsonProtocol._
+ import common._
+ import Trial._
+
+ implicit val trialStatusFormat = new EnumJsonFormat[Status](
+ "New" -> Status.New,
+ "ReviewSummary" -> Status.ReviewSummary,
+ "Summarized" -> Status.Summarized,
+ "PendingUpdate" -> Status.PendingUpdate,
+ "Update" -> Status.Update,
+ "ReviewCriteria" -> Status.ReviewCriteria,
+ "Done" -> Status.Done,
+ "Flagged" -> Status.Flagged,
+ "Archived" -> Status.Archived
+ )
+
+ implicit val conditionFormat = new EnumJsonFormat[Condition](
+ "Breast" -> Condition.Breast,
+ "Lung" -> Condition.Lung,
+ "Prostate" -> Condition.Prostate
+ )
+
+ implicit val trialWriter: JsonWriter[Trial] = new JsonWriter[Trial] {
+ override def write(obj: Trial) =
+ JsObject(
+ "id" -> obj.id.toJson,
+ "externalid" -> obj.externalId.toJson,
+ "lastUpdate" -> ZonedDateTime.of(obj.lastUpdate, ZoneId.of("Z")).toJson,
+ "status" -> obj.status.toJson,
+ "assignee" -> obj.assignee.toJson,
+ "previousStatus" -> obj.previousStatus.toJson,
+ "previousAssignee" -> obj.previousAssignee.toJson,
+ "lastActiveUser" -> obj.lastActiveUserId.toJson,
+ "condition" -> obj.condition.toJson,
+ "phase" -> obj.phase.toJson,
+ "hypothesisId" -> obj.hypothesisId.toJson,
+ "studyDesignId" -> obj.studyDesignId.toJson,
+ "originalStudyDesignId" -> obj.originalStudyDesign.toJson,
+ "isPartner" -> obj.isPartner.toJson,
+ "overview" -> obj.overview.toJson,
+ "overviewTemplate" -> obj.overviewTemplate.toJson,
+ "isUpdated" -> obj.isUpdated.toJson,
+ "title" -> obj.title.toJson,
+ "originalTitle" -> obj.originalTitle.toJson
+ )
+ }
+
+ def applyUpdateToTrial(json: JsValue, orig: Trial): Trial = json match {
+ case JsObject(fields) =>
+ val hypothesisId = fields
+ .get("hypothesisId")
+ .map(_.convertTo[Option[UuidId[Hypothesis]]])
+ .getOrElse(orig.hypothesisId)
+
+ val studyDesignId = fields
+ .get("studyDesignId")
+ .map(_.convertTo[Option[LongId[StudyDesign]]])
+ .getOrElse(orig.studyDesignId)
+
+ val overview = fields
+ .get("overview")
+ .map(_.convertTo[Option[String]])
+ .getOrElse(orig.overview)
+
+ val title = fields
+ .get("title")
+ .map(_.convertTo[Option[String]].getOrElse(""))
+ .getOrElse(orig.title)
+
+ orig.copy(
+ hypothesisId = hypothesisId,
+ studyDesignId = studyDesignId,
+ overview = overview,
+ title = title
+ )
+
+ case _ => deserializationError(s"Expected Json Object as Trial, but got $json")
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trialhistory.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trialhistory.scala
new file mode 100644
index 0000000..844c5f5
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trialhistory.scala
@@ -0,0 +1,30 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import xyz.driver.core.json.EnumJsonFormat
+import xyz.driver.pdsuidomain.entities._
+
+object trialhistory {
+ import DefaultJsonProtocol._
+ import common._
+ import TrialHistory._
+
+ implicit val trialStateFormat = new EnumJsonFormat[State](
+ "Summarize" -> State.Summarize,
+ "Criteriarize" -> State.Criteriarize,
+ "Review" -> State.Review,
+ "Flag" -> State.Flag
+ )
+
+ implicit val trialActionFormat = new EnumJsonFormat[Action](
+ "Start" -> Action.Start,
+ "Submit" -> Action.Submit,
+ "Unassign" -> Action.Unassign,
+ "Resolve" -> Action.Resolve,
+ "Flag" -> Action.Flag,
+ "Archive" -> Action.Archive
+ )
+
+ implicit val trialHistoryFormat: RootJsonFormat[TrialHistory] = jsonFormat6(TrialHistory.apply)
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trialissue.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trialissue.scala
new file mode 100644
index 0000000..572f44d
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/trialissue.scala
@@ -0,0 +1,60 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import xyz.driver.pdsuicommon.domain.{LongId, StringId, User}
+import xyz.driver.pdsuidomain.entities._
+
+object trialissue {
+ import DefaultJsonProtocol._
+ import common._
+
+ def applyUpdateToTrialIssue(json: JsValue, orig: TrialIssue): TrialIssue = {
+ json.asJsObject.getFields("text", "evidence", "archiveRequired", "meta") match {
+ case Seq(text, evidence, archiveRequired, meta) =>
+ orig.copy(
+ text = text.convertTo[String],
+ evidence = evidence.convertTo[String],
+ archiveRequired = archiveRequired.convertTo[Boolean],
+ meta = meta.convertTo[String]
+ )
+
+ case _ => deserializationError(s"Expected Json Object as partial TrialIssue, but got $json")
+ }
+ }
+
+ def jsValueToTrialIssue(json: JsValue, trialId: StringId[Trial], userId: StringId[User]): TrialIssue = {
+ json.asJsObject.getFields("text", "evidence", "meta") match {
+ case Seq(text, evidence, meta) =>
+ TrialIssue(
+ id = LongId(0),
+ userId = userId,
+ trialId = trialId,
+ lastUpdate = LocalDateTime.MIN,
+ isDraft = true,
+ text = text.convertTo[String],
+ evidence = evidence.convertTo[String],
+ archiveRequired = false,
+ meta = meta.convertTo[String]
+ )
+
+ case _ => deserializationError(s"Expected Json Object as TrialIssue, but got $json")
+ }
+
+ }
+
+ implicit val trialIssueWriter = new JsonWriter[TrialIssue] {
+ override def write(obj: TrialIssue) = JsObject(
+ "id" -> obj.id.toJson,
+ "text" -> obj.text.toJson,
+ "lastUpdate" -> obj.lastUpdate.toJson,
+ "userId" -> obj.userId.toJson,
+ "isDraft" -> obj.isDraft.toJson,
+ "evidence" -> obj.evidence.toJson,
+ "archiveRequired" -> obj.archiveRequired.toJson,
+ "meta" -> obj.meta.toJson
+ )
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/ApiDocumentSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/ApiDocumentSuite.scala
deleted file mode 100644
index d9d62dd..0000000
--- a/src/test/scala/xyz/driver/pdsuidomain/formats/json/ApiDocumentSuite.scala
+++ /dev/null
@@ -1,78 +0,0 @@
-package xyz.driver.pdsuidomain.formats.json
-
-/*
-import java.time.LocalDateTime
-
-import org.scalatest.FreeSpecLike
-import play.api.libs.json.Json
-
-import scala.collection.breakOut
-
-class ApiDocumentSuite extends FreeSpecLike {
-
- "ApiDocument" - {
- "conforms to specification when serialized" in {
- val document = ApiDocument(
- id = 1L,
- recordId = 123L,
- physician = Some("physician"),
- lastUpdate = LocalDateTime.now(),
- `type` = "some-type",
- startDate = LocalDateTime.now(),
- endDate = Some(LocalDateTime.now()),
- provider = "test-provider",
- providerType = "test-provider-type",
- status = "New",
- assignee = Some(5L),
- previousAssignee = None,
- meta = "{}"
- )
-
- val actualJson = serialize(document)
- val matcher =
- """^\{
- |"id":"[^"]+",
- |"recordId":"[^"]+",
- |"physician":"[^"]+",
- |"lastUpdate":"[^"]+",
- |"type":"[^"]+",
- |"startDate":"[^"]+",
- |"endDate":"[^"]+",
- |"provider":"[^"]+",
- |"providerType":"[^"]+",
- |"status":"[^"]+",
- |"assignee":"[^"]+",
- |"meta":\{[^\}]*\}
- |\}""".stripMargin.lines.mkString.r
-
- assert(
- matcher.pattern.matcher(actualJson).matches(),
- s"""see https://driverinc.atlassian.net/wiki/display/RA/REST+API+Specification#RESTAPISpecification-DocumentObject
- |pattern = ${matcher.pattern}
- |json = $actualJson""".stripMargin
- )
- }
-
- "has optional fields according to specification" in {
- val expectedOptionalFields = Set("physician", "endDate", "assignee", "previousAssignee")
-
- val klass = classOf[ApiDocument]
- val actualOptionalFields: Set[String] = klass.getDeclaredFields.collect({
- case x if x.getType == classOf[Option[_]] => x.getName
- })(breakOut)
-
- assert(
- actualOptionalFields === expectedOptionalFields,
- """actual vs expected
- |see https://driverinc.atlassian.net/wiki/display/RA/REST+API+Specification#RESTAPISpecification-DocumentObject
- """.stripMargin.trim
- )
- }
- }
-
- private def serialize(document: ApiDocument): String = {
- Json.stringify(Json.toJson(document))
- }
-
-}
- */
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/ApiPartialDocumentSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/ApiPartialDocumentSuite.scala
deleted file mode 100644
index 2ae52f9..0000000
--- a/src/test/scala/xyz/driver/pdsuidomain/formats/json/ApiPartialDocumentSuite.scala
+++ /dev/null
@@ -1,263 +0,0 @@
-package xyz.driver.pdsuidomain.formats.json
-
-/*
-import java.time.LocalDateTime
-
-import xyz.driver.pdsuicommon.domain._
-import org.davidbild.tristate.Tristate
-import org.scalatest.FreeSpecLike
-import play.api.libs.json.Json
-
-class ApiPartialDocumentSuite extends FreeSpecLike {
-
- "serialization" - {
- "can be deserialized" in deserialize(defaultJson)
-
- "endDate" - {
- def jsonWithEndDate(rawValue: String) = json("endDate" -> rawValue)
- def jsonWithoutEndDate = json()
-
- "when specified" - {
- "if non-empty object - should be parsed as date" in {
- val rawEndDate = "2007-12-03T10:15:30.000"
- val apiPartialEntity = deserialize(jsonWithEndDate(quoted(rawEndDate)))
- assert(apiPartialEntity.endDate.exists(_ == LocalDateTime.parse(rawEndDate)))
- }
-
- "if null - should be parsed as Absent" in {
- val apiPartialEntity = deserialize(jsonWithEndDate("null"))
- assert(apiPartialEntity.endDate.isAbsent)
- }
- }
-
- "when unspecified - should be parsed as Unspecified" in {
- val apiPartialEntity = deserialize(jsonWithoutEndDate)
- assert(apiPartialEntity.endDate.isUnspecified)
- }
- }
-
- "assignee" - {
- def jsonWithAssignee(rawValue: String) = json("assignee" -> rawValue)
- def jsonWithoutAssignee = json()
-
- "when specified" - {
- "if non-empty object - should be parsed as UUID" in {
- val rawAssignee = 123
- val apiPartialEntity = deserialize(jsonWithAssignee(quoted(rawAssignee.toString)))
- assert(apiPartialEntity.assignee.exists(_ == rawAssignee))
- }
-
- "if null - should be parsed as Absent" in {
- val apiPartialEntity = deserialize(jsonWithAssignee("null"))
- assert(apiPartialEntity.assignee.isAbsent)
- }
- }
-
- "when unspecified - should be parsed as Unspecified" in {
- val apiPartialEntity = deserialize(jsonWithoutAssignee)
- assert(apiPartialEntity.assignee.isUnspecified)
- }
- }
-
- "meta" - {
- def jsonWithMeta(rawValue: String) = json("meta" -> rawValue)
- def jsonWithoutMeta = json()
-
- "when specified" - {
- "if non-empty object - should be parsed as normalized JSON-string" in {
- val apiPartialEntity = deserialize(jsonWithMeta(""" { "foo" : 1} """))
- assert(apiPartialEntity.meta.exists(_ == """{"foo":1}"""))
- }
-
- "if null - should be parsed as Absent" in {
- val apiPartialEntity = deserialize(jsonWithMeta("null"))
- assert(apiPartialEntity.meta.isAbsent)
- }
-
- "if empty object ({}) - should be parsed as Absent (same as null case)" in {
- val apiPartialEntity = deserialize(jsonWithMeta(" { } "))
- assert(apiPartialEntity.meta.isAbsent)
- }
- }
-
- "when unspecified - should be parsed as Unspecified" in {
- val apiPartialEntity = deserialize(jsonWithoutMeta)
- assert(apiPartialEntity.meta.isUnspecified)
- }
- }
-
- def deserialize(json: String): ApiPartialDocument = {
- Json.parse(json).as[ApiPartialDocument]
- }
- }
-
- "applyTo" - {
- "endDate" - {
- "should choose a value of the api partial document" - {
- "if it present" in test(Tristate.Present(LocalDateTime.now().plusDays(1)))
- "if it absent" in test(Tristate.Absent)
-
- def test(newEndDate: Tristate[LocalDateTime]): Unit = {
- val origDocument = documentExample
- val apiPartialDocument = apiPartialDocumentExample.copy(endDate = newEndDate)
-
- val newDocument = apiPartialDocument.applyTo(origDocument)
- assert(newDocument.endDate === newEndDate.toOption)
- }
- }
-
- "should choose a value of the original document if it unspecified" in {
- val newEndDate = Tristate.Unspecified
- val origDocument = documentExample
- val apiPartialDocument = apiPartialDocumentExample.copy(endDate = newEndDate)
-
- val newDocument = apiPartialDocument.applyTo(origDocument)
- assert(newDocument.endDate == origDocument.endDate)
- }
- }
-
- "assignee" - {
- "should choose a value of the api partial document" - {
- "if it present" in test(Tristate.Present(123))
- "if it absent" in test(Tristate.Absent)
-
- def test(newAssignee: Tristate[Long]): Unit = {
- val origDocument = documentExample
- val apiPartialDocument = apiPartialDocumentExample.copy(assignee = newAssignee)
-
- val newDocument = apiPartialDocument.applyTo(origDocument)
- assert(newDocument.assignee === newAssignee.toOption.map(StringId[User]))
- }
- }
-
- "should choose a value of the original document if it unspecified" in {
- val newAssignee = Tristate.Unspecified
- val origDocument = documentExample
- val apiPartialDocument = apiPartialDocumentExample.copy(assignee = newAssignee)
-
- val newDocument = apiPartialDocument.applyTo(origDocument)
- assert(newDocument.assignee == origDocument.assignee)
- }
- }
-
- /*"meta" - {
- val documentId = Id[Document]()
- def test(origMeta: Option[RawMeta], metaUpdate: Tristate[String], expectedNewMeta: Option[RawMeta]): Unit = {
- val apiPartialDocument = apiPartialDocumentExample.copy(meta = metaUpdate)
-
- val actualNewMeta = apiPartialDocument.applyTo(documentId, origMeta)
- assert(actualNewMeta == expectedNewMeta)
- }
-
- "should choose a new meta's value" - {
- "if it present" - {
- "when original meta is present" in test(
- origMeta = Some(RawMeta(documentId, """{"foo":42}""")),
- metaUpdate = Tristate.Present("""{"bar":1}"""),
- expectedNewMeta = Some(RawMeta(documentId, """{"bar":1}"""))
- )
-
- "when original meta is absent" in test(
- origMeta = None,
- metaUpdate = Tristate.Present("""{"bar":1}"""),
- expectedNewMeta = Some(RawMeta(documentId, """{"bar":1}"""))
- )
- }
-
- "if it absent" - {
- "when original meta is present" in test(
- origMeta = Some(RawMeta(documentId, """{"foo":42}""")),
- metaUpdate = Tristate.Absent,
- expectedNewMeta = None
- )
-
- "when original meta is absent" in test(
- origMeta = None,
- metaUpdate = Tristate.Absent,
- expectedNewMeta = None
- )
- }
- }
-
- "should choose an original meta if a new one is unspecified" - {
- "when original meta is present" in test(
- origMeta = Some(RawMeta(documentId, """{"foo":42}""")),
- metaUpdate = Tristate.Unspecified,
- expectedNewMeta = Some(RawMeta(documentId, """{"foo":42}"""))
- )
-
- "when original meta is absent" in test(
- origMeta = None,
- metaUpdate = Tristate.Unspecified,
- expectedNewMeta = None
- )
- }
- }*/
- }
-
- private def documentExample = Document(
- id = LongId(1),
- status = Document.Status.Organized,
- assignee = Some(LongId(1)),
- previousAssignee = None,
- recordId = LongId(1),
- physician = None,
- documentType = "type",
- providerName = "provider name",
- providerType = "provider type",
- meta = None,
- startDate = LocalDateTime.now,
- endDate = None,
- lastUpdate = LocalDateTime.now
- )
-
- private def apiPartialDocumentExample = ApiPartialDocument(
- recordId = Some(12),
- physician = Some("new physician"),
- `type` = Some("new type"),
- startDate = Some(LocalDateTime.now),
- endDate = Tristate.Present(LocalDateTime.now),
- provider = Some("new provider name"),
- providerType = Some("new provider type"),
- status = Some("Extracted"),
- assignee = Tristate.Present(13),
- meta = Tristate.Present("""{"foo":42}""")
- )
-
- private def quoted(v: String): String = s""""$v""""
-
- private def defaultJson = json(
- "endDate" -> quoted("2007-12-03T10:15:30.000"),
- "assignee" -> quoted("c8b1b818-e1eb-4831-b0c8-26753b109deb"),
- "meta" -> """{"foo": 1}"""
- )
-
- /**
- * Without fields:
- * - endDate
- * - assignee
- * - meta
- */
- private def json(addFields: (String, String)*): String = {
- val addJson = addFields
- .collect {
- case (k, v) if v.nonEmpty => s""" "$k": $v """
- }
- .mkString(",\n")
-
- s"""{
- |"recordId":"bc542d3d-a928-42b8-824d-ca1520b07500",
- |"patientId":"foobar",
- |"caseId":"bazquux",
- |"physician":"zed",
- |"lastUpdate":"2007-12-03T10:15:30.000",
- |"type":"type1",
- |"startDate":"2007-10-01T09:40:00.000",
- |"provider":"some provider name",
- |"providerType":"some provider type",
- |"status":"New"${if (addJson.isEmpty) "" else ","}
- |$addJson
- |}""".stripMargin
- }
-}
- */
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ArmFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ArmFormatSuite.scala
new file mode 100644
index 0000000..e7d37a0
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ArmFormatSuite.scala
@@ -0,0 +1,36 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities.Arm
+
+class ArmFormatSuite extends FlatSpec with Matchers {
+ import arm._
+
+ "Json format for Arm" should "read and write correct JSON" in {
+ val arm = Arm(
+ id = LongId(10),
+ trialId = StringId("NCT000001"),
+ name = "arm name",
+ originalName = "orig arm name"
+ )
+ val writtenJson = armFormat.write(arm)
+
+ writtenJson should be("""{"id":10,"trialId":"NCT000001","name":"arm name","originalName":"orig arm name"}""".parseJson)
+
+ val createArmJson = """{"trialId":"NCT000001","name":"arm name"}""".parseJson
+ val parsedArm = armFormat.read(createArmJson)
+ val expectedCreatedArm = arm.copy(
+ id = LongId(0),
+ originalName = "arm name"
+ )
+ parsedArm should be(expectedCreatedArm)
+
+ val updateArmJson = """{"name":"new arm name"}""".parseJson
+ val expectedUpdatedArm = arm.copy(name = "new arm name")
+ val parsedUpdateArm = applyUpdateToArm(updateArmJson, arm)
+ parsedUpdateArm should be(expectedUpdatedArm)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/BridgeUploadQueueFormat.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/BridgeUploadQueueFormat.scala
new file mode 100644
index 0000000..854f51f
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/BridgeUploadQueueFormat.scala
@@ -0,0 +1,32 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.concurrent.BridgeUploadQueue
+
+class BridgeUploadQueueFormat extends FlatSpec with Matchers {
+ import bridgeuploadqueue._
+
+ "Json format for BridgeUploadQueue.Item" should "read and write correct JSON" in {
+ val item = BridgeUploadQueue.Item(
+ kind = "kind",
+ tag = "tag",
+ created = LocalDateTime.parse("2017-08-10T18:00:00"),
+ attempts = 0,
+ nextAttempt = LocalDateTime.parse("2017-08-10T18:10:00"),
+ completed = false,
+ dependencyKind = Some("dependency king"),
+ dependencyTag = None
+ )
+ val writtenJson = queueUploadItemFormat.write(item)
+
+ writtenJson should be(
+ """{"kind":"kind","tag":"tag","created":"2017-08-10T18:00Z","attempts":0,"nextAttempt":"2017-08-10T18:10Z","completed":false}""".parseJson)
+
+ val parsedItem = queueUploadItemFormat.read(writtenJson)
+ parsedItem should be(item.copy(dependencyKind = None, completed = true))
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/CriterionFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/CriterionFormatSuite.scala
new file mode 100644
index 0000000..d24c4c1
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/CriterionFormatSuite.scala
@@ -0,0 +1,68 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities.{Arm, Criterion, CriterionLabel}
+import xyz.driver.pdsuidomain.services.CriterionService.RichCriterion
+
+class CriterionFormatSuite extends FlatSpec with Matchers {
+ import criterion._
+
+ "Json format for Criterion" should "read and write correct JSON" in {
+ val criterion = Criterion(
+ id = LongId(10),
+ trialId = StringId("NCT000001"),
+ text = Some("text"),
+ isCompound = false,
+ meta = "{}"
+ )
+ val labels = List(
+ CriterionLabel(
+ id = LongId(1L),
+ labelId = Some(LongId(101)),
+ criterionId = criterion.id,
+ categoryId = Some(LongId(3)),
+ value = Some(true),
+ isDefining = true
+ ),
+ CriterionLabel(
+ id = LongId(2L),
+ labelId = Some(LongId(102)),
+ criterionId = criterion.id,
+ categoryId = Some(LongId(3)),
+ value = Some(false),
+ isDefining = true
+ )
+ )
+ val arms = List(LongId[Arm](20), LongId[Arm](21), LongId[Arm](21))
+ val richCriterion = RichCriterion(
+ criterion = criterion,
+ armIds = arms,
+ labels = labels
+ )
+ val writtenJson = richCriterionFormat.write(richCriterion)
+
+ writtenJson should be(
+ """{"text":"text","isCompound":false,"trialId":"NCT000001","arms":[20,21,21],"id":10,"meta":"{}",
+ "labels":[{"labelId":101,"categoryId":3,"value":"Yes","isDefining":true},
+ {"labelId":102,"categoryId":3,"value":"No","isDefining":true}]}""".parseJson)
+
+ val createCriterionJson =
+ """{"text":"text","isCompound":false,"trialId":"NCT000001",
+ "arms":[20,21,21],"meta":"{}","labels":[{"labelId":101,"categoryId":3,"value":"Yes","isDefining":true},
+ {"labelId":102,"categoryId":3,"value":"No","isDefining":true}]}""".parseJson
+ val parsedRichCriterion = richCriterionFormat.read(createCriterionJson)
+ val expectedRichCriterion = richCriterion.copy(
+ criterion = criterion.copy(id = LongId(0)),
+ labels = labels.map(_.copy(id = LongId(0), criterionId = LongId(0)))
+ )
+ parsedRichCriterion should be(expectedRichCriterion)
+
+ val updateCriterionJson = """{"meta":null,"text":"new text","isCompound":true}""".parseJson
+ val expectedUpdatedCriterion = richCriterion.copy(criterion = criterion.copy(text = Some("new text"), isCompound = true, meta = "{}"))
+ val parsedUpdateCriterion = applyUpdateToCriterion(updateCriterionJson, richCriterion)
+ parsedUpdateCriterion should be(expectedUpdatedCriterion)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentFormatSuite.scala
new file mode 100644
index 0000000..9394735
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentFormatSuite.scala
@@ -0,0 +1,74 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.{LocalDate, LocalDateTime}
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, TextJson}
+import xyz.driver.pdsuidomain.entities.Document
+
+class DocumentFormatSuite extends FlatSpec with Matchers {
+ import document._
+
+ "Json format for Document" should "read and write correct JSON" in {
+ val orig = Document(
+ id = LongId(1),
+ status = Document.Status.New,
+ assignee = None,
+ previousStatus = None,
+ previousAssignee = None,
+ lastActiveUserId = None,
+ lastUpdate = LocalDateTime.parse("2017-08-10T18:00:00"),
+ recordId = LongId(101),
+ physician = Some("physician"),
+ typeId = Some(LongId(10)),
+ providerName = Some("provider 21"),
+ providerTypeId = Some(LongId(21)),
+ requiredType = Some(Document.RequiredType.OPN),
+ meta = None,
+ startDate = None,
+ endDate = None
+ )
+ val writtenJson = documentFormat.write(orig)
+
+ writtenJson should be (
+ """{"id":1,"recordId":101,"physician":"physician","typeId":10,"provider":"provider 21","providerTypeId":21,
+ "requiredType":"OPN","startDate":null,"endDate":null,"status":"New","assignee":null,"previousStatus":null,
+ "previousAssignee":null,"lastActiveUser":null,"lastUpdate":"2017-08-10T18:00Z","meta":null}""".parseJson)
+
+ val createDocumentJson =
+ """{"recordId":101,"physician":"physician","typeId":10,"provider":"provider 21","providerTypeId":21}""".parseJson
+ val expectedCreatedDocument = orig.copy(
+ id = LongId(0),
+ lastUpdate = LocalDateTime.MIN,
+ requiredType = None
+ )
+ val parsedCreatedDocument = documentFormat.read(createDocumentJson)
+ parsedCreatedDocument should be(expectedCreatedDocument)
+
+ val updateDocumentJson =
+ """{"startDate":"2017-08-10","endDate":"2018-08-10","meta":{"predicted":true,"startPage":1.0,"endPage":2.0}}""".parseJson
+ val expectedUpdatedDocument = orig.copy(
+ startDate = Some(LocalDate.parse("2017-08-10")),
+ endDate = Some(LocalDate.parse("2018-08-10")),
+ meta = Some(TextJson(Document.Meta(predicted = Some(true), startPage = 1.0, endPage = 2.0)))
+ )
+ val parsedUpdatedDocument = applyUpdateToDocument(updateDocumentJson, orig)
+ parsedUpdatedDocument should be(expectedUpdatedDocument)
+ }
+
+ "Json format for Document.Meta" should "read and write correct JSON" in {
+ val meta = Document.Meta(predicted = None, startPage = 1.0, endPage = 2.0)
+ val writtenJson = documentMetaFormat.write(meta)
+ writtenJson should be ("""{"startPage":1.0,"endPage":2.0}""".parseJson)
+
+ val metaJsonWithoutPredicted = """{"startPage":1.0,"endPage":2.0}""".parseJson
+ val parsedMetaWithoutPredicted = documentMetaFormat.read(metaJsonWithoutPredicted)
+ parsedMetaWithoutPredicted should be(meta)
+
+ val metaJsonWithPredicted = """{"predicted":true,"startPage":1.0,"endPage":2.0}""".parseJson
+ val parsedMetaWithPredicted = documentMetaFormat.read(metaJsonWithPredicted)
+ parsedMetaWithPredicted should be(meta.copy(predicted = Some(true)))
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentHistoryFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentHistoryFormatSuite.scala
new file mode 100644
index 0000000..ddbda1d
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentHistoryFormatSuite.scala
@@ -0,0 +1,32 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities.DocumentHistory
+
+class DocumentHistoryFormatSuite extends FlatSpec with Matchers {
+ import documenthistory._
+
+ "Json format for DocumentHistory" should "read and write correct JSON" in {
+ val documentHistory = DocumentHistory(
+ id = LongId(10),
+ documentId = LongId(1),
+ executor = StringId("userId-001"),
+ state = DocumentHistory.State.Extract,
+ action = DocumentHistory.Action.Start,
+ created = LocalDateTime.parse("2017-08-10T18:00:00")
+ )
+ val writtenJson = documentHistoryFormat.write(documentHistory)
+
+ writtenJson should be(
+ """{"id":10,"executor":"userId-001","documentId":1,"state":"Extract",
+ "action":"Start","created":"2017-08-10T18:00Z"}""".parseJson)
+
+ val parsedDocumentHistory = documentHistoryFormat.read(writtenJson)
+ parsedDocumentHistory should be(documentHistory)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentIssueFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentIssueFormatSuite.scala
new file mode 100644
index 0000000..1a8e3f0
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/DocumentIssueFormatSuite.scala
@@ -0,0 +1,47 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities.DocumentIssue
+
+class DocumentIssueFormatSuite extends FlatSpec with Matchers {
+ import documentissue._
+
+ "Json format for DocumentIssue" should "read and write correct JSON" in {
+ val documentIssue = DocumentIssue(
+ id = LongId(10),
+ documentId = LongId(1),
+ userId = StringId("userId-001"),
+ lastUpdate = LocalDateTime.parse("2017-08-10T18:00:00"),
+ isDraft = false,
+ text = "message text",
+ archiveRequired = false,
+ startPage = Some(1.0),
+ endPage = Some(2.0)
+ )
+ val writtenJson = documentIssueWriter.write(documentIssue)
+
+ writtenJson should be(
+ """{"id":10,"userId":"userId-001","lastUpdate":"2017-08-10T18:00Z","isDraft":false,
+ "text":"message text","archiveRequired":false,"startPage":1.0,"endPage":2.0}""".parseJson)
+
+ val createDocumentIssueJson = """{"text":"message text","startPage":1.0,"endPage":2.0}""".parseJson
+ val expectedCreatedDocumentIssue = documentIssue.copy(id = LongId(0), lastUpdate = LocalDateTime.MIN, isDraft = true)
+ val parsedCreateDocumentIssue = jsValueToDocumentIssue(createDocumentIssueJson, LongId(1), StringId("userId-001"))
+ parsedCreateDocumentIssue should be(expectedCreatedDocumentIssue)
+
+ val updateDocumentIssueJson =
+ """{"text":"new issue text","evidence":"issue evidence","archiveRequired":true,"startPage":1.0,"endPage":4.0}""".parseJson
+ val expectedUpdatedDocumentIssue = documentIssue.copy(
+ text = "new issue text",
+ archiveRequired = true,
+ endPage = Some(4.0)
+ )
+ val parsedUpdateDocumentIssue = applyUpdateToDocumentIssue(updateDocumentIssueJson, documentIssue)
+ parsedUpdateDocumentIssue should be(expectedUpdatedDocumentIssue)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ExportFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ExportFormatSuite.scala
new file mode 100644
index 0000000..d0d4d1a
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ExportFormatSuite.scala
@@ -0,0 +1,124 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.{LocalDate, LocalDateTime}
+import java.util.UUID
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{FuzzyValue, LongId, StringId, UuidId}
+import xyz.driver.pdsuidomain.entities.RecordRequestId
+
+class ExportFormatSuite extends FlatSpec with Matchers {
+ import export._
+
+ "Json format for ExportPatientWithLabels" should "read and write correct JSON" in {
+ import xyz.driver.pdsuidomain.entities.export.patient._
+ val document = ExportPatientLabelEvidenceDocument(
+ documentId = LongId(101),
+ requestId = RecordRequestId(UUID.fromString("7b54a75d-4197-4b27-9045-b9b6cb131be9")),
+ documentType = "document type",
+ providerType = "provider type",
+ date = LocalDate.parse("2017-08-10")
+ )
+ val labels = List(
+ ExportPatientLabel(
+ id = LongId(1),
+ evidences = List(
+ ExportPatientLabelEvidence(
+ id = LongId(11),
+ value = FuzzyValue.Yes,
+ evidenceText = "evidence text 11",
+ document = document
+ ),
+ ExportPatientLabelEvidence(
+ id = LongId(12),
+ value = FuzzyValue.No,
+ evidenceText = "evidence text 12",
+ document = document
+ )
+ )
+ ),
+ ExportPatientLabel(
+ id = LongId(2),
+ evidences = List(
+ ExportPatientLabelEvidence(
+ id = LongId(12),
+ value = FuzzyValue.Yes,
+ evidenceText = "evidence text 12",
+ document = document
+ ),
+ ExportPatientLabelEvidence(
+ id = LongId(13),
+ value = FuzzyValue.Yes,
+ evidenceText = "evidence text 13",
+ document = document
+ )
+ )
+ )
+ )
+ val patientWithLabels = ExportPatientWithLabels(
+ patientId = UuidId("748b5884-3528-4cb9-904b-7a8151d6e343"),
+ labelVersion = 1L,
+ labels = labels
+ )
+
+ val writtenJson = patientWithLabelsWriter.write(patientWithLabels)
+ writtenJson should be(
+ """{"patientId":"748b5884-3528-4cb9-904b-7a8151d6e343","labelVersion":1,"labels":[{"labelId":1,"evidence":[{"evidenceId":11,
+ "labelValue":"Yes","evidenceText":"evidence text 11","document":{"documentId":101,"requestId":"7b54a75d-4197-4b27-9045-b9b6cb131be9",
+ "documentType":"document type","providerType":"provider type","date":"2017-08-10"}},{"evidenceId":12,"labelValue":"No",
+ "evidenceText":"evidence text 12","document":{"documentId":101,"requestId":"7b54a75d-4197-4b27-9045-b9b6cb131be9",
+ "documentType":"document type","providerType":"provider type","date":"2017-08-10"}}]},
+ {"labelId":2,"evidence":[{"evidenceId":12,"labelValue":"Yes","evidenceText":"evidence text 12","document":
+ {"documentId":101,"requestId":"7b54a75d-4197-4b27-9045-b9b6cb131be9","documentType":"document type",
+ "providerType":"provider type","date":"2017-08-10"}},{"evidenceId":13,"labelValue":"Yes","evidenceText":"evidence text 13",
+ "document":{"documentId":101,"requestId":"7b54a75d-4197-4b27-9045-b9b6cb131be9","documentType":"document type",
+ "providerType":"provider type","date":"2017-08-10"}}]}]}""".parseJson)
+ }
+
+ "Json format for ApiExportTrialWithLabels" should "read and write correct JSON" in {
+ import xyz.driver.pdsuidomain.entities.export.trial._
+ val arms = List(
+ ExportTrialArm(armId = LongId(1), armName = "arm 1"),
+ ExportTrialArm(armId = LongId(2), armName = "arm 2")
+ )
+ val criteriaList = List(
+ ExportTrialLabelCriterion(
+ criterionId = LongId(10),
+ value = Some(true),
+ labelId = LongId(21),
+ armIds = Set(LongId(1), LongId(2)),
+ criteria = "criteria 10 text",
+ isCompound = false,
+ isDefining = false
+ ),
+ ExportTrialLabelCriterion(
+ criterionId = LongId(11),
+ value = None,
+ labelId = LongId(21),
+ armIds = Set(LongId(2)),
+ criteria = "criteria 11 text",
+ isCompound = true,
+ isDefining = false
+ )
+ )
+ val trialWithLabels = ExportTrialWithLabels(
+ nctId = StringId("NCT000001"),
+ trialId = UuidId("40892a07-c638-49d2-9795-1edfefbbcc7c"),
+ condition = "Breast",
+ lastReviewed = LocalDateTime.parse("2017-08-10T18:00:00"),
+ labelVersion = 1L,
+ arms = arms,
+ criteria = criteriaList
+ )
+
+ val writtenJson = trialWithLabelsWriter.write(trialWithLabels)
+ writtenJson should be(
+ """{"nctId":"NCT000001","trialId":"40892a07-c638-49d2-9795-1edfefbbcc7c","disease":"Breast","lastReviewed":"2017-08-10T18:00Z",
+ "labelVersion":1,"arms":[{"armId":1,"armName":"arm 1"},{"armId":2,"armName":"arm 2"}],"criteria":[
+ {"value":"Yes","labelId":21,"criterionId":10,"criterionText":"criteria 10 text","armIds":[1,2],"isCompound":false,"isDefining":false},
+ {"value":"Unknown","labelId":21,"criterionId":11,"criterionText":"criteria 11 text","armIds":[2],"isCompound":true,"isDefining":false}]}""".parseJson)
+ }
+
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ExtractedDataFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ExtractedDataFormatSuite.scala
new file mode 100644
index 0000000..a4b8bab
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/ExtractedDataFormatSuite.scala
@@ -0,0 +1,95 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{FuzzyValue, LongId, TextJson}
+import xyz.driver.pdsuidomain.entities.ExtractedData.Meta
+import xyz.driver.pdsuidomain.entities.{ExtractedData, ExtractedDataLabel}
+import xyz.driver.pdsuidomain.services.ExtractedDataService.RichExtractedData
+
+class ExtractedDataFormatSuite extends FlatSpec with Matchers {
+ import extracteddata._
+
+ "Json format for ExtractedData" should "read and write correct JSON" in {
+ val extractedData = ExtractedData(
+ id = LongId(1),
+ documentId = LongId(101),
+ keywordId = Some(LongId(201)),
+ evidenceText = Some("evidence text"),
+ meta = None
+ )
+ val extractedDataLabels = List(
+ ExtractedDataLabel(
+ id = LongId(1),
+ dataId = extractedData.id,
+ labelId = None,
+ categoryId = None,
+ value = Some(FuzzyValue.Yes)
+ ),
+ ExtractedDataLabel(
+ id = LongId(2),
+ dataId = extractedData.id,
+ labelId = Some(LongId(12)),
+ categoryId = Some(LongId(1)),
+ value = Some(FuzzyValue.No)
+ )
+ )
+ val origRichExtractedData = RichExtractedData(
+ extractedData = extractedData,
+ labels = extractedDataLabels
+ )
+ val writtenJson = extractedDataFormat.write(origRichExtractedData)
+
+ writtenJson should be (
+ """{"id":1,"documentId":101,"keywordId":201,"evidence":"evidence text","meta":null,
+ "labels":[{"id":null,"categoryId":null,"value":"Yes"},{"id":12,"categoryId":1,"value":"No"}]}""".parseJson)
+
+ val createExtractedDataJson =
+ """{"documentId":101,"keywordId":201,"evidence":"evidence text",
+ "labels":[{"value":"Yes"},{"id":12,"categoryId":1,"value":"No"}]}""".parseJson
+ val expectedCreatedExtractedData = origRichExtractedData.copy(
+ extractedData = extractedData.copy(id = LongId(0)),
+ labels = extractedDataLabels.map(_.copy(id = LongId(0), dataId = LongId(0)))
+ )
+ val parsedCreatedExtractedData = extractedDataFormat.read(createExtractedDataJson)
+ parsedCreatedExtractedData should be(expectedCreatedExtractedData)
+
+ val updateExtractedDataJson =
+ """{"evidence":"new evidence text","meta":{"keyword":{"page":1,"index":2,"sortIndex":"ASC"},
+ "evidence":{"pageRatio":1.0,"start":{"page":1,"index":3,"offset":2},"end":{"page":2,"index":3,"offset":10}}},
+ "labels":[{"id":20,"categoryId":1,"value":"Yes"},{"id":12,"categoryId":1,"value":"No"}]}""".parseJson
+ val updatedExtractedDataLabels = List(
+ ExtractedDataLabel(
+ id = LongId(0),
+ dataId = extractedData.id,
+ labelId = Some(LongId(20)),
+ categoryId = Some(LongId(1)),
+ value = Some(FuzzyValue.Yes)
+ ),
+ ExtractedDataLabel(
+ id = LongId(0),
+ dataId = extractedData.id,
+ labelId = Some(LongId(12)),
+ categoryId = Some(LongId(1)),
+ value = Some(FuzzyValue.No)
+ )
+ )
+ val expectedUpdatedExtractedData = origRichExtractedData.copy(
+ extractedData = extractedData.copy(
+ evidenceText = Some("new evidence text"),
+ meta = Some(TextJson(Meta(
+ keyword = Meta.Keyword(page = 1, pageRatio = None, index = 2, sortIndex = "ASC"),
+ evidence = Meta.Evidence(
+ pageRatio = 1.0,
+ start = Meta.TextLayerPosition(page = 1, index = 3, offset = 2),
+ end = Meta.TextLayerPosition(page = 2, index = 3, offset = 10)
+ )
+ )))
+ ),
+ labels = updatedExtractedDataLabels
+ )
+ val parsedUpdatedExtractedData = applyUpdateToExtractedData(updateExtractedDataJson, origRichExtractedData)
+ parsedUpdatedExtractedData should be(expectedUpdatedExtractedData)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/HypothesisFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/HypothesisFormatSuite.scala
new file mode 100644
index 0000000..306fb17
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/HypothesisFormatSuite.scala
@@ -0,0 +1,28 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.UuidId
+import xyz.driver.pdsuidomain.entities.Hypothesis
+
+class HypothesisFormatSuite extends FlatSpec with Matchers {
+ import hypothesis._
+
+ "Json format for Hypothesis" should "read and write correct JSON" in {
+ val hypothesis = Hypothesis(
+ id = UuidId("3b80b2e2-5372-4cf5-a342-6e4ebe10fafd"),
+ name = "hypothesis name",
+ treatmentType = "treatment type",
+ description = "descr"
+ )
+ val writtenJson = hypothesisFormat.write(hypothesis)
+
+ writtenJson should be(
+ """{"id":"3b80b2e2-5372-4cf5-a342-6e4ebe10fafd","name":"hypothesis name",
+ "treatmentType":"treatment type","description":"descr"}""".parseJson)
+
+ val parsedHypothesis = hypothesisFormat.read(writtenJson)
+ parsedHypothesis should be(hypothesis)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/InterventionFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/InterventionFormatSuite.scala
new file mode 100644
index 0000000..784a655
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/InterventionFormatSuite.scala
@@ -0,0 +1,63 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities.{Intervention, InterventionArm, InterventionType, InterventionWithArms}
+
+class InterventionFormatSuite extends FlatSpec with Matchers {
+ import intervention._
+
+ "Json format for Intervention" should "read and write correct JSON" in {
+ val intervention = Intervention(
+ id = LongId(1),
+ trialId = StringId("NCT000001"),
+ name = "intervention name",
+ originalName = "orig name",
+ typeId = Some(LongId(10)),
+ originalType = Some("orig type"),
+ description = "",
+ originalDescription = "",
+ isActive = true
+ )
+ val arms = List(
+ InterventionArm(interventionId = intervention.id, armId = LongId(20)),
+ InterventionArm(interventionId = intervention.id, armId = LongId(21)),
+ InterventionArm(interventionId = intervention.id, armId = LongId(22))
+ )
+ val orig = InterventionWithArms(
+ intervention = intervention,
+ arms = arms
+ )
+ val writtenJson = interventionWriter.write(orig)
+
+ writtenJson should be(
+ """{"id":1,"name":"intervention name","typeId":10,"description":"","isActive":true,"arms":[20,21,22],
+ "trialId":"NCT000001","originalName":"orig name","originalDescription":"","originalType":"orig type"}""".parseJson)
+
+ val updateInterventionJson = """{"description":"descr","arms":[21,22]}""".parseJson
+ val expectedUpdatedIntervention = orig.copy(
+ intervention = intervention.copy(description = "descr"),
+ arms = List(
+ InterventionArm(interventionId = intervention.id, armId = LongId(21)),
+ InterventionArm(interventionId = intervention.id, armId = LongId(22))
+ )
+ )
+ val parsedUpdateIntervention = applyUpdateToInterventionWithArms(updateInterventionJson, orig)
+ parsedUpdateIntervention should be(expectedUpdatedIntervention)
+ }
+
+ "Json format for InterventionType" should "read and write correct JSON" in {
+ val interventionType = InterventionType(
+ id = LongId(10),
+ name = "type name"
+ )
+ val writtenJson = interventionTypeFormat.write(interventionType)
+
+ writtenJson should be("""{"id":10,"name":"type name"}""".parseJson)
+
+ val parsedInterventionType = interventionTypeFormat.read(writtenJson)
+ parsedInterventionType should be(interventionType)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordFormatSuite.scala
new file mode 100644
index 0000000..899e5c9
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordFormatSuite.scala
@@ -0,0 +1,77 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+import java.util.UUID
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, TextJson, UuidId}
+import xyz.driver.pdsuidomain.entities.{MedicalRecord, RecordRequestId}
+
+class MedicalRecordFormatSuite extends FlatSpec with Matchers {
+ import record._
+ import MedicalRecord._
+
+ "Json format for MedicalRecord" should "read and write correct JSON" in {
+ val orig = MedicalRecord(
+ id = LongId(1),
+ status = Status.New,
+ assignee = None,
+ previousStatus = None,
+ previousAssignee = None,
+ lastActiveUserId = None,
+ lastUpdate = LocalDateTime.parse("2017-08-10T18:00:00"),
+ physician = Some("physician"),
+ meta = None,
+ predictedMeta = None,
+ predictedDocuments = None,
+ disease = "Breast",
+ requestId = RecordRequestId(UUID.fromString("7b54a75d-4197-4b27-9045-b9b6cb131be9")),
+ caseId = None,
+ patientId = UuidId("748b5884-3528-4cb9-904b-7a8151d6e343")
+ )
+ val writtenJson = recordFormat.write(orig)
+
+ writtenJson should be (
+ """{"id":1,"status":"New","assignee":null,"previousStatus":null,"previousAssignee":null,"lastActiveUser":null,
+ "lastUpdate":"2017-08-10T18:00Z","meta":[],"patientId":"748b5884-3528-4cb9-904b-7a8151d6e343","caseId":null,
+ "requestId":"7b54a75d-4197-4b27-9045-b9b6cb131be9","disease":"Breast","physician":"physician"}""".parseJson)
+
+ val createRecordJson =
+ """{"disease":"Breast","patientId":"748b5884-3528-4cb9-904b-7a8151d6e343","requestId":"7b54a75d-4197-4b27-9045-b9b6cb131be9"}""".parseJson
+ val expectedCreatedRecord = MedicalRecord(
+ id = LongId(0),
+ status = MedicalRecord.Status.New,
+ previousStatus = None,
+ assignee = None,
+ previousAssignee = None,
+ lastActiveUserId = None,
+ patientId = UuidId("748b5884-3528-4cb9-904b-7a8151d6e343"),
+ requestId = RecordRequestId(UUID.fromString("7b54a75d-4197-4b27-9045-b9b6cb131be9")),
+ disease = "Breast",
+ caseId = None,
+ physician = None,
+ meta = None,
+ predictedMeta = None,
+ predictedDocuments = None,
+ lastUpdate = LocalDateTime.now()
+ )
+ val parsedCreatedRecord = recordFormat.read(createRecordJson).copy(lastUpdate = expectedCreatedRecord.lastUpdate)
+ parsedCreatedRecord should be(expectedCreatedRecord)
+
+ val updateRecordJson =
+ """{"meta":[{"type":"duplicate","predicted":true,"startPage":1.0,"endPage":2.0,"startOriginalPage":1.0},
+ {"type":"reorder","items":[1,2]},
+ {"type":"rotation","items":{"item1":1,"item2":2}}]}""".parseJson
+ val expectedUpdatedRecord = orig.copy(
+ meta = Some(TextJson(List(
+ Meta.Duplicate(predicted = Some(true), startPage = 1.0, endPage = 2.0, startOriginalPage = 1.0, endOriginalPage = None),
+ Meta.Reorder(predicted = None, items = Seq(1, 2)),
+ Meta.Rotation(predicted = None, items = Map("item1" -> 1, "item2" -> 2))
+ )))
+ )
+ val parsedUpdatedRecord = applyUpdateToMedicalRecord(updateRecordJson, orig)
+ parsedUpdatedRecord should be(expectedUpdatedRecord)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordHistoryFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordHistoryFormatSuite.scala
new file mode 100644
index 0000000..5cd6c8d
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordHistoryFormatSuite.scala
@@ -0,0 +1,32 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities.MedicalRecordHistory
+
+class MedicalRecordHistoryFormatSuite extends FlatSpec with Matchers {
+ import recordhistory._
+
+ "Json format for MedicalRecordHistory" should "read and write correct JSON" in {
+ val recordHistory = MedicalRecordHistory(
+ id = LongId(10),
+ recordId = LongId(1),
+ executor = StringId("userId-001"),
+ state = MedicalRecordHistory.State.Clean,
+ action = MedicalRecordHistory.Action.Start,
+ created = LocalDateTime.parse("2017-08-10T18:00:00")
+ )
+ val writtenJson = recordHistoryFormat.write(recordHistory)
+
+ writtenJson should be(
+ """{"id":10,"executor":"userId-001","recordId":1,"state":"Clean",
+ "action":"Start","created":"2017-08-10T18:00Z"}""".parseJson)
+
+ val parsedRecordHistory = recordHistoryFormat.read(writtenJson)
+ parsedRecordHistory should be(recordHistory)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordIssueFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordIssueFormatSuite.scala
new file mode 100644
index 0000000..9b89c97
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/MedicalRecordIssueFormatSuite.scala
@@ -0,0 +1,47 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities.MedicalRecordIssue
+
+class MedicalRecordIssueFormatSuite extends FlatSpec with Matchers {
+ import recordissue._
+
+ "Json format for MedicalRecordIssue" should "read and write correct JSON" in {
+ val recordIssue = MedicalRecordIssue(
+ id = LongId(10),
+ recordId = LongId(1),
+ userId = StringId("userId-001"),
+ lastUpdate = LocalDateTime.parse("2017-08-10T18:00:00"),
+ isDraft = false,
+ text = "message text",
+ archiveRequired = false,
+ startPage = Some(1.0),
+ endPage = Some(2.0)
+ )
+ val writtenJson = recordIssueWriter.write(recordIssue)
+
+ writtenJson should be(
+ """{"id":10,"userId":"userId-001","lastUpdate":"2017-08-10T18:00Z","isDraft":false,
+ "text":"message text","archiveRequired":false,"startPage":1.0,"endPage":2.0}""".parseJson)
+
+ val createRecordIssueJson = """{"text":"message text","startPage":1.0,"endPage":2.0}""".parseJson
+ val expectedCreatedRecordIssue = recordIssue.copy(id = LongId(0), lastUpdate = LocalDateTime.MIN, isDraft = true)
+ val parsedCreateRecordIssue = jsValueToRecordIssue(createRecordIssueJson, LongId(1), StringId("userId-001"))
+ parsedCreateRecordIssue should be(expectedCreatedRecordIssue)
+
+ val updateRecordIssueJson =
+ """{"text":"new issue text","evidence":"issue evidence","archiveRequired":true,"startPage":1.0,"endPage":4.0}""".parseJson
+ val expectedUpdatedRecordIssue = recordIssue.copy(
+ text = "new issue text",
+ archiveRequired = true,
+ endPage = Some(4.0)
+ )
+ val parsedUpdateRecordIssue = applyUpdateToRecordIssue(updateRecordIssueJson, recordIssue)
+ parsedUpdateRecordIssue should be(expectedUpdatedRecordIssue)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientCriterionFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientCriterionFormatSuite.scala
new file mode 100644
index 0000000..0f5e4e2
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientCriterionFormatSuite.scala
@@ -0,0 +1,55 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{FuzzyValue, LongId, StringId}
+import xyz.driver.pdsuidomain.entities.{PatientCriterion, PatientCriterionArm}
+import xyz.driver.pdsuidomain.services.PatientCriterionService.DraftPatientCriterion
+
+class PatientCriterionFormatSuite extends FlatSpec with Matchers {
+ import patientcriterion._
+
+ "Json format for PatientCriterion" should "read and write correct JSON" in {
+ val orig = PatientCriterion(
+ id = LongId(1),
+ patientLabelId = LongId(1),
+ trialId = 0L,
+ nctId = StringId("NCT00001"),
+ criterionId = LongId(101),
+ criterionText = "criterion text",
+ criterionValue = Some(true),
+ criterionIsDefining = false,
+ eligibilityStatus = Some(FuzzyValue.Yes),
+ verifiedEligibilityStatus = None,
+ isVisible = true,
+ isVerified = true,
+ lastUpdate = LocalDateTime.parse("2017-08-10T18:00:00")
+ )
+ val arms = List(
+ PatientCriterionArm(patientCriterionId = LongId(1), armId = LongId(31), armName = "arm 31"),
+ PatientCriterionArm(patientCriterionId = LongId(1), armId = LongId(32), armName = "arm 32")
+ )
+ val writtenJson = patientCriterionWriter.write((orig, LongId(21), arms))
+
+ writtenJson should be (
+ """{"id":1,"labelId":21,"nctId":"NCT00001","criterionId":101,"criterionText":"criterion text","criterionValue":"Yes",
+ "criterionIsDefining":false,"criterionIsCompound":false,"eligibilityStatus":"Yes","verifiedEligibilityStatus":null,
+ "isVisible":true,"isVerified":true,"lastUpdate":"2017-08-10T18:00Z","arms":["arm 31","arm 32"]}""".parseJson)
+
+ val updatePatientCriterionJson = """{"verifiedEligibilityStatus":"No"}""".parseJson
+ val expectedUpdatedPatientCriterion = orig.copy(verifiedEligibilityStatus = Some(FuzzyValue.No))
+ val parsedUpdatePatientCriterion = applyUpdateToPatientCriterion(updatePatientCriterionJson, orig)
+ parsedUpdatePatientCriterion should be(expectedUpdatedPatientCriterion)
+
+ val updateBulkPatientCriterionJson = """[{"id":1,"eligibilityStatus":"No"},{"id":2,"isVerified":false}]""".parseJson
+ val expectedDraftPatientCriterionList = List(
+ DraftPatientCriterion(id = LongId(1), eligibilityStatus = Some(FuzzyValue.No), isVerified = None),
+ DraftPatientCriterion(id = LongId(2), eligibilityStatus = None, isVerified = Some(false))
+ )
+ val parsedDraftPatientCriterionList = draftPatientCriterionListReader.read(updateBulkPatientCriterionJson)
+ parsedDraftPatientCriterionList should be(expectedDraftPatientCriterionList)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientEligibleTrialFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientEligibleTrialFormatSuite.scala
new file mode 100644
index 0000000..ad54946
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientEligibleTrialFormatSuite.scala
@@ -0,0 +1,62 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{FuzzyValue, LongId, StringId, UuidId}
+import xyz.driver.pdsuidomain.entities.{PatientCriterionArm, PatientTrialArmGroupView, Trial}
+import xyz.driver.pdsuidomain.services.PatientEligibleTrialService.RichPatientEligibleTrial
+
+class PatientEligibleTrialFormatSuite extends FlatSpec with Matchers {
+ import patienteligibletrial._
+
+ "Json format for PatientEligibleTrial" should "read and write correct JSON" in {
+ val trial = Trial(
+ id = StringId("NCT000001"),
+ externalId = UuidId("40892a07-c638-49d2-9795-1edfefbbcc7c"),
+ status = Trial.Status.Done,
+ assignee = None,
+ previousStatus = None,
+ previousAssignee = None,
+ lastActiveUserId = None,
+ lastUpdate = LocalDateTime.parse("2017-08-10T18:16:19"),
+ condition = Trial.Condition.Breast,
+ phase = "",
+ hypothesisId = Some(UuidId("e76e2fc4-a29c-44fb-a81b-8856d06bb1d4")),
+ studyDesignId = Some(LongId(321)),
+ originalStudyDesign = None,
+ isPartner = false,
+ overview = None,
+ overviewTemplate = "",
+ isUpdated = false,
+ title = "trial title",
+ originalTitle = "orig trial title"
+ )
+ val group = PatientTrialArmGroupView(
+ id = LongId(1),
+ patientId = UuidId("748b5884-3528-4cb9-904b-7a8151d6e343"),
+ trialId = StringId("NCT000001"),
+ hypothesisId = UuidId("e76e2fc4-a29c-44fb-a81b-8856d06bb1d4"),
+ eligibilityStatus = Some(FuzzyValue.Yes),
+ verifiedEligibilityStatus = Some(FuzzyValue.Yes),
+ isVerified = false
+ )
+ val arms = List(
+ PatientCriterionArm(patientCriterionId = LongId(1), armId = LongId(31), armName = "arm 31"),
+ PatientCriterionArm(patientCriterionId = LongId(1), armId = LongId(32), armName = "arm 32")
+ )
+ val orig = RichPatientEligibleTrial(trial, group, arms)
+ val writtenJson = patientEligibleTrialWriter.write(orig)
+
+ writtenJson should be (
+ """{"id":1,"patientId":"748b5884-3528-4cb9-904b-7a8151d6e343","trialId":"NCT000001","trialTitle":"trial title",
+ "hypothesisId":"e76e2fc4-a29c-44fb-a81b-8856d06bb1d4","verifiedEligibilityStatus":"Yes","isVerified":false,"arms":["arm 31","arm 32"]}""".parseJson)
+
+ val updatePatientEligibleTrialJson = """{"isVerified":true}""".parseJson
+ val expectedUpdatedPatientTrialArmGroup = group.copy(isVerified = true)
+ val parsedUpdatePatientTrialArmGroup = applyUpdateToTrialArmGroup(updatePatientEligibleTrialJson, group)
+ parsedUpdatePatientTrialArmGroup should be(expectedUpdatedPatientTrialArmGroup)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientFormatSuite.scala
new file mode 100644
index 0000000..2761d6a
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientFormatSuite.scala
@@ -0,0 +1,36 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.{LocalDate, LocalDateTime}
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.UuidId
+import xyz.driver.pdsuidomain.entities.{Patient, PatientOrderId}
+
+class PatientFormatSuite extends FlatSpec with Matchers {
+ import patient._
+
+ "Json format for Patient" should "read and write correct JSON" in {
+ val orig = Patient(
+ id = UuidId("748b5884-3528-4cb9-904b-7a8151d6e343"),
+ status = Patient.Status.New,
+ name = "John Doe",
+ dob = LocalDate.parse("1980-06-30"),
+ assignee = None,
+ previousStatus = None,
+ previousAssignee = None,
+ lastActiveUserId = None,
+ isUpdateRequired = false,
+ condition = "breast",
+ orderId = PatientOrderId("7b54a75d-4197-4b27-9045-b9b6cb131be9"),
+ lastUpdate = LocalDateTime.parse("2017-08-10T18:00:00")
+ )
+ val writtenJson = patientWriter.write(orig)
+
+ writtenJson should be (
+ """{"id":"748b5884-3528-4cb9-904b-7a8151d6e343","dob":"1980-06-30","name":"John Doe","status":"New","assignee":null,
+ "previousStatus":null,"previousAssignee":null,"lastActiveUser":null,"lastUpdate":"2017-08-10T18:00Z",
+ "orderId":"7b54a75d-4197-4b27-9045-b9b6cb131be9","condition":"breast"}""".parseJson)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientHistoryFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientHistoryFormatSuite.scala
new file mode 100644
index 0000000..c6a5a9f
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientHistoryFormatSuite.scala
@@ -0,0 +1,32 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId, UuidId}
+import xyz.driver.pdsuidomain.entities.PatientHistory
+
+class PatientHistoryFormatSuite extends FlatSpec with Matchers {
+ import patienthistory._
+
+ "Json format for PatientHistory" should "read and write correct JSON" in {
+ val patientHistory = PatientHistory(
+ id = LongId(10),
+ patientId = UuidId("40892a07-c638-49d2-9795-1edfefbbcc7c"),
+ executor = StringId("userId-001"),
+ state = PatientHistory.State.Verify,
+ action = PatientHistory.Action.Start,
+ created = LocalDateTime.parse("2017-08-10T18:00:00")
+ )
+ val writtenJson = patientHistoryFormat.write(patientHistory)
+
+ writtenJson should be(
+ """{"id":10,"executor":"userId-001","patientId":"40892a07-c638-49d2-9795-1edfefbbcc7c","state":"Verify",
+ "action":"Start","created":"2017-08-10T18:00Z"}""".parseJson)
+
+ val parsedPatientHistory = patientHistoryFormat.read(writtenJson)
+ parsedPatientHistory should be(patientHistory)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientHypothesisFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientHypothesisFormatSuite.scala
new file mode 100644
index 0000000..2999cc1
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientHypothesisFormatSuite.scala
@@ -0,0 +1,31 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.UuidId
+import xyz.driver.pdsuidomain.entities.PatientHypothesis
+
+class PatientHypothesisFormatSuite extends FlatSpec with Matchers {
+ import patienthypothesis._
+
+ "Json format for PatientHypothesis" should "read and write correct JSON" in {
+ val orig = PatientHypothesis(
+ id = UuidId("815d9715-1089-4775-b120-3afb983b9a97"),
+ patientId = UuidId("748b5884-3528-4cb9-904b-7a8151d6e343"),
+ hypothesisId = UuidId("e76e2fc4-a29c-44fb-a81b-8856d06bb1d4"),
+ rationale = None,
+ matchedTrials = 1
+ )
+ val writtenJson = patientHypothesisWriter.write((orig, true))
+
+ writtenJson should be (
+ """{"id":"815d9715-1089-4775-b120-3afb983b9a97","patientId":"748b5884-3528-4cb9-904b-7a8151d6e343",
+ "hypothesisId":"e76e2fc4-a29c-44fb-a81b-8856d06bb1d4","rationale":null,"matchedTrials":1,"isRationaleRequired":true}""".parseJson)
+
+ val updatePatientHypothesisJson = """{"rationale":"rationale"}""".parseJson
+ val expectedUpdatedPatientHypothesis = orig.copy(rationale = Some("rationale"))
+ val parsedUpdatePatientHypothesis = applyUpdateToPatientHypothesis(updatePatientHypothesisJson, orig)
+ parsedUpdatePatientHypothesis should be(expectedUpdatedPatientHypothesis)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientIssueFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientIssueFormatSuite.scala
new file mode 100644
index 0000000..1e2a11e
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientIssueFormatSuite.scala
@@ -0,0 +1,44 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId, UuidId}
+import xyz.driver.pdsuidomain.entities.PatientIssue
+
+class PatientIssueFormatSuite extends FlatSpec with Matchers {
+ import patientissue._
+
+ "Json format for PatientIssue" should "read and write correct JSON" in {
+ val patientIssue = PatientIssue(
+ id = LongId(10),
+ patientId = UuidId("40892a07-c638-49d2-9795-1edfefbbcc7c"),
+ userId = StringId("userId-001"),
+ lastUpdate = LocalDateTime.parse("2017-08-10T18:00:00"),
+ isDraft = false,
+ text = "message text",
+ archiveRequired = false
+ )
+ val writtenJson = patientIssueWriter.write(patientIssue)
+
+ writtenJson should be(
+ """{"id":10,"userId":"userId-001","lastUpdate":"2017-08-10T18:00Z","isDraft":false,
+ "text":"message text","archiveRequired":false}""".parseJson)
+
+ val createPatientIssueJson = """{"text":"message text"}""".parseJson
+ val expectedCreatedPatientIssue = patientIssue.copy(id = LongId(0), lastUpdate = LocalDateTime.MIN, isDraft = true)
+ val parsedCreatePatientIssue = jsValueToPatientIssue(createPatientIssueJson, UuidId("40892a07-c638-49d2-9795-1edfefbbcc7c"), StringId("userId-001"))
+ parsedCreatePatientIssue should be(expectedCreatedPatientIssue)
+
+ val updatePatientIssueJson =
+ """{"text":"new issue text","evidence":"issue evidence","archiveRequired":true}""".parseJson
+ val expectedUpdatedPatientIssue = patientIssue.copy(
+ text = "new issue text",
+ archiveRequired = true
+ )
+ val parsedUpdatePatientIssue = applyUpdateToPatientIssue(updatePatientIssueJson, patientIssue)
+ parsedUpdatePatientIssue should be(expectedUpdatedPatientIssue)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientLabelFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientLabelFormatSuite.scala
new file mode 100644
index 0000000..e18239c
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/PatientLabelFormatSuite.scala
@@ -0,0 +1,76 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDate
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{FuzzyValue, LongId, UuidId}
+import xyz.driver.pdsuidomain.entities.{PatientLabel, PatientLabelEvidenceView}
+
+class PatientLabelFormatSuite extends FlatSpec with Matchers {
+
+ "Json format for PatientLabel" should "read and write correct JSON" in {
+ import patientlabel._
+ val orig = PatientLabel(
+ id = LongId(1),
+ patientId = UuidId("748b5884-3528-4cb9-904b-7a8151d6e343"),
+ labelId = LongId(20),
+ primaryValue = Some(FuzzyValue.Yes),
+ verifiedPrimaryValue = None,
+ isVisible = true,
+ score = 1,
+ isImplicitMatch = false
+ )
+ val writtenJson = patientLabelWriter.write((orig, true))
+
+ writtenJson should be (
+ """{"id":1,"labelId":20,"primaryValue":"Yes","verifiedPrimaryValue":null,"isVisible":true,"isVerified":true,
+ "score":1,"isImplicitMatch":false}""".parseJson)
+
+ val updatePatientLabelJson = """{"verifiedPrimaryValue":"No"}""".parseJson
+ val expectedUpdatedPatientLabel = orig.copy(verifiedPrimaryValue = Some(FuzzyValue.No))
+ val parsedUpdatePatientLabel = applyUpdateToPatientLabel(updatePatientLabelJson, orig)
+ parsedUpdatePatientLabel should be(expectedUpdatedPatientLabel)
+ }
+
+ "Json format for PatientLabelEvidence" should "read and write correct JSON" in {
+ import patientlabel._
+ val orig = PatientLabelEvidenceView(
+ id = LongId(1),
+ value = FuzzyValue.Maybe,
+ evidenceText = "evidence text",
+ documentId = Some(LongId(21)),
+ evidenceId = Some(LongId(10)),
+ reportId = None,
+ documentType = "document type",
+ date = Some(LocalDate.parse("2017-08-10")),
+ providerType = "provider type",
+ patientId = UuidId("748b5884-3528-4cb9-904b-7a8151d6e343"),
+ labelId = LongId(20),
+ isImplicitMatch = false
+ )
+ val writtenJson = patientLabelEvidenceWriter.write(orig)
+
+ writtenJson should be (
+ """{"id":1,"value":"Maybe","evidenceText":"evidence text","documentId":21,"evidenceId":10,"reportId":null,
+ "documentType":"document type","date":"2017-08-10","providerType":"provider type"}""".parseJson)
+ }
+
+ "Json format for PatientLabelDefiningCriteria" should "read and write correct JSON" in {
+ import patientdefiningcriteria._
+ val orig = PatientLabel(
+ id = LongId(1),
+ patientId = UuidId("748b5884-3528-4cb9-904b-7a8151d6e343"),
+ labelId = LongId(20),
+ primaryValue = Some(FuzzyValue.Yes),
+ verifiedPrimaryValue = Some(FuzzyValue.Yes),
+ isVisible = true,
+ score = 1,
+ isImplicitMatch = false
+ )
+ val writtenJson = patientLabelDefiningCriteriaWriter.write(orig)
+
+ writtenJson should be ("""{"id":1,"value":"Yes"}""".parseJson)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/StudyDesignFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/StudyDesignFormatSuite.scala
new file mode 100644
index 0000000..9cf9b5f
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/StudyDesignFormatSuite.scala
@@ -0,0 +1,24 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.LongId
+import xyz.driver.pdsuidomain.entities.StudyDesign
+
+class StudyDesignFormatSuite extends FlatSpec with Matchers {
+ import studydesign._
+
+ "Json format for StudyDesign" should "read and write correct JSON" in {
+ val studyDesign = StudyDesign(
+ id = LongId(10),
+ name = "study design name"
+ )
+ val writtenJson = studyDesignFormat.write(studyDesign)
+
+ writtenJson should be("""{"id":10,"name":"study design name"}""".parseJson)
+
+ val parsedStudyDesign = studyDesignFormat.read(writtenJson)
+ parsedStudyDesign should be(studyDesign)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialFormatSuite.scala
new file mode 100644
index 0000000..59cf779
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialFormatSuite.scala
@@ -0,0 +1,50 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId, UuidId}
+import xyz.driver.pdsuidomain.entities.Trial
+
+class TrialFormatSuite extends FlatSpec with Matchers {
+ import trial._
+
+ "Json format for Trial" should "read and write correct JSON" in {
+ val orig = Trial(
+ id = StringId("NCT000001"),
+ externalId = UuidId("40892a07-c638-49d2-9795-1edfefbbcc7c"),
+ status = Trial.Status.New,
+ assignee = None,
+ previousStatus = None,
+ previousAssignee = None,
+ lastActiveUserId = None,
+ lastUpdate = LocalDateTime.parse("2017-08-10T18:16:19"),
+ condition = Trial.Condition.Breast,
+ phase = "",
+ hypothesisId = Some(UuidId("3b80b2e2-5372-4cf5-a342-6e4ebe10fafd")),
+ studyDesignId = Some(LongId(321)),
+ originalStudyDesign = None,
+ isPartner = false,
+ overview = None,
+ overviewTemplate = "",
+ isUpdated = false,
+ title = "trial title",
+ originalTitle = "orig trial title"
+ )
+ val writtenJson = trialWriter.write(orig)
+
+ writtenJson should be (
+ """{"isPartner":false,"assignee":null,"lastUpdate":"2017-08-10T18:16:19Z","previousStatus":null,
+ "isUpdated":false,"overviewTemplate":"","phase":"","originalStudyDesignId":null,
+ "hypothesisId":"3b80b2e2-5372-4cf5-a342-6e4ebe10fafd","originalTitle":"orig trial title",
+ "studyDesignId":321,"lastActiveUser":null,"externalid":"40892a07-c638-49d2-9795-1edfefbbcc7c",
+ "id":"NCT000001","condition":"Breast","status":"New","overview":null,"previousAssignee":null,"title":"trial title"}""".parseJson)
+
+ val updateTrialJson = """{"hypothesisId":null,"overview":"new overview"}""".parseJson
+ val expectedUpdatedTrial = orig.copy(hypothesisId = None, overview = Some("new overview"))
+ val parsedUpdateTrial = applyUpdateToTrial(updateTrialJson, orig)
+ parsedUpdateTrial should be(expectedUpdatedTrial)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialHistoryFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialHistoryFormatSuite.scala
new file mode 100644
index 0000000..dbb143c
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialHistoryFormatSuite.scala
@@ -0,0 +1,32 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities.TrialHistory
+
+class TrialHistoryFormatSuite extends FlatSpec with Matchers {
+ import trialhistory._
+
+ "Json format for TrialHistory" should "read and write correct JSON" in {
+ val trialHistory = TrialHistory(
+ id = LongId(10),
+ trialId = StringId("NCT000001"),
+ executor = StringId("userId-001"),
+ state = TrialHistory.State.Summarize,
+ action = TrialHistory.Action.Start,
+ created = LocalDateTime.parse("2017-08-10T18:00:00")
+ )
+ val writtenJson = trialHistoryFormat.write(trialHistory)
+
+ writtenJson should be(
+ """{"id":10,"executor":"userId-001","trialId":"NCT000001","state":"Summarize",
+ "action":"Start","created":"2017-08-10T18:00Z"}""".parseJson)
+
+ val parsedTrialHistory = trialHistoryFormat.read(writtenJson)
+ parsedTrialHistory should be(trialHistory)
+ }
+
+}
diff --git a/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialIssueFormatSuite.scala b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialIssueFormatSuite.scala
new file mode 100644
index 0000000..02e14ba
--- /dev/null
+++ b/src/test/scala/xyz/driver/pdsuidomain/formats/json/sprayformats/TrialIssueFormatSuite.scala
@@ -0,0 +1,49 @@
+package xyz.driver.pdsuidomain.formats.json.sprayformats
+
+import java.time.LocalDateTime
+
+import spray.json._
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities.TrialIssue
+
+class TrialIssueFormatSuite extends FlatSpec with Matchers {
+ import trialissue._
+
+ "Json format for TrialIssue" should "read and write correct JSON" in {
+ val trialIssue = TrialIssue(
+ id = LongId(10),
+ trialId = StringId("NCT000001"),
+ userId = StringId("userId-001"),
+ lastUpdate = LocalDateTime.parse("2017-08-10T18:00:00"),
+ isDraft = false,
+ text = "message text",
+ evidence = "evidence",
+ archiveRequired = false,
+ meta = "{}"
+ )
+ val writtenJson = trialIssueWriter.write(trialIssue)
+
+ writtenJson should be(
+ """{"id":10,"userId":"userId-001","lastUpdate":"2017-08-10T18:00Z","isDraft":false,
+ "text":"message text","evidence":"evidence","archiveRequired":false,"meta":"{}"}""".parseJson)
+
+ val createTrialIssueJson = """{"text":"message text","evidence":"evidence","meta":"{}"}""".parseJson
+ val expectedCreatedTrialIssue = trialIssue.copy(id = LongId(0), lastUpdate = LocalDateTime.MIN, isDraft = true)
+ val parsedCreateTrialIssue = jsValueToTrialIssue(createTrialIssueJson, StringId("NCT000001"), StringId("userId-001"))
+ parsedCreateTrialIssue should be(expectedCreatedTrialIssue)
+
+ val updateTrialIssueJson =
+ """{"text":"new issue text","evidence":"issue evidence","archiveRequired":true,
+ "meta":"{\"startPage\":1.0,\"endPage\":2.0}"}""".parseJson
+ val expectedUpdatedTrialIssue = trialIssue.copy(
+ text = "new issue text",
+ evidence = "issue evidence",
+ archiveRequired = true,
+ meta = """{"startPage":1.0,"endPage":2.0}"""
+ )
+ val parsedUpdateTrialIssue = applyUpdateToTrialIssue(updateTrialIssueJson, trialIssue)
+ parsedUpdateTrialIssue should be(expectedUpdatedTrialIssue)
+ }
+
+}