aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jakob@driver.xyz>2017-07-05 19:02:13 -0700
committerJakob Odersky <jakob@driver.xyz>2017-07-12 21:04:25 -0700
commitf9ac0adf5c3bcfcde03bd3ea2bc2471b0d0f99fe (patch)
tree9e26568fe6598074a6de8815b465cbfc7ff69b7c
parent3d902b5197db861c30325c159dc10cfb211ae209 (diff)
downloadrest-query-f9ac0adf5c3bcfcde03bd3ea2bc2471b0d0f99fe.tar.gz
rest-query-f9ac0adf5c3bcfcde03bd3ea2bc2471b0d0f99fe.tar.bz2
rest-query-f9ac0adf5c3bcfcde03bd3ea2bc2471b0d0f99fe.zip
Implement REST services for trial curation
-rw-r--r--build.sbt29
-rw-r--r--project/build.properties2
-rw-r--r--project/plugins.sbt2
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/auth/AuthenticatedRequestContext.scala5
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/concurrent/BridgeUploadQueueRepositoryAdapter.scala4
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/concurrent/Cron.scala6
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/concurrent/SafeBridgeUploadQueue.scala2
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/db/MySqlContext.scala26
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/db/Pagination.scala2
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/db/QueryBuilder.scala31
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/db/SearchFilterExpr.scala6
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/db/Sorting.scala4
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/domain/Id.scala8
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/domain/User.scala14
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/json/JsResultOps.scala2
-rw-r--r--src/main/scala/xyz/driver/pdsuicommon/serialization/PlayJsonSupport.scala34
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/DirectReport.scala14
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/LinkedPatient.scala2
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/MedicalRecord.scala48
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/Message.scala6
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/RawPatientDocument.scala20
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/RawTrialLabel.scala26
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala24
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/ListResponse.scala4
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/arm/ApiArm.scala15
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/intervention/ApiIntervention.scala39
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/message/ApiMessage.scala22
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/trial/ApiTrial.scala58
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/formats/json/user/ApiPartialUser.scala10
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/ArmService.scala10
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/CategoryService.scala27
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/CriterionService.scala18
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/DocumentService.scala19
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/DocumentTypeService.scala2
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/ExportService.scala6
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/ExtractedDataService.scala18
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/HypothesisService.scala2
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/InterventionService.scala10
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/InterventionTypeService.scala2
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/KeywordService.scala28
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/LabelService.scala27
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/MedicalRecordService.scala18
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/MessageService.scala21
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/PatientCriterionService.scala22
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/PatientEligibleTrialService.scala21
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/PatientHypothesisService.scala12
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/PatientLabelEvidenceService.scala6
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/PatientLabelService.scala16
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/PatientService.scala11
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/ProviderTypeService.scala2
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/QueueUploadService.scala20
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/ScrapedTrialsService.scala8
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/StudyDesignService.scala2
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/TrialHistoryService.scala4
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/TrialIssueService.scala20
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/TrialService.scala16
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/UserHistoryService.scala2
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/UserService.scala34
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/rest/RestArmService.scala99
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/rest/RestCriterionService.scala108
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/rest/RestHelper.scala139
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/rest/RestHypothesisService.scala39
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/rest/RestInterventionService.scala78
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/rest/RestInterventionTypeService.scala40
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/rest/RestMessageService.scala103
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/rest/RestStudyDesignService.scala37
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/services/rest/RestTrialService.scala117
67 files changed, 1226 insertions, 403 deletions
diff --git a/build.sbt b/build.sbt
index 7772f5b..82a3249 100644
--- a/build.sbt
+++ b/build.sbt
@@ -3,26 +3,31 @@ import Keys._
lazy val core = (project in file("."))
.driverLibrary("pds-ui-common")
- .settings(scalastyleSettings ++ /* wartRemoverSettings ++ */ formatSettings)
+ .settings(scalastyleSettings ++ wartRemoverSettings ++ formatSettings)
+ .settings(wartremoverErrors in (Compile, compile) --= Seq(
+ Wart.ImplicitConversion, Wart.MutableDataStructures, Wart.TraversableOps, Wart.OptionPartial))
.settings(sources in (Compile, doc) := Seq.empty, publishArtifact in (Compile, packageDoc) := false)
.settings(libraryDependencies ++= Seq(
- "ch.qos.logback" % "logback-classic" % "1.1.7",
- "org.slf4j" % "slf4j-api" % "1.7.21",
- "com.typesafe.scala-logging" %% "scala-logging" % "3.5.0",
- "com.typesafe" % "config" % "1.3.0",
"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.8.3",
- "com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.8.4",
+ "com.github.pureconfig" %% "pureconfig" % "0.7.2",
+ "com.typesafe.akka" %% "akka-http" % "10.0.9",
"com.typesafe.play" %% "play" % "2.5.15",
- "org.davidbild" %% "tristate-core" % "0.2.0",
- "org.davidbild" %% "tristate-play" % "0.2.0" exclude ("com.typesafe.play", "play-json"),
- "org.asynchttpclient" % "async-http-client" % "2.0.24",
+ "com.typesafe.scala-logging" %% "scala-logging" % "3.5.0",
"io.getquill" %% "quill-jdbc" % "1.2.1",
"io.github.cloudify" %% "spdf" % "1.4.0",
- "com.sendgrid" % "sendgrid-java" % "3.1.0" exclude ("org.mockito", "mockito-core"),
+ "org.davidbild" %% "tristate-core" % "0.2.0",
+ "org.davidbild" %% "tristate-play" % "0.2.0" exclude ("com.typesafe.play", "play-json"),
+ "xyz.driver" %% "core" % "0.13.15",
+ "xyz.driver" %% "domain-model" % "0.10.40",
+ "ch.qos.logback" % "logback-classic" % "1.1.7",
+ "com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.8.4",
"com.github.spullara.mustache.java" % "scala-extensions-2.11" % "0.9.4",
- "de.svenkubiak" % "jBCrypt" % "0.4.1",
"com.google.cloud" % "google-cloud-storage" % "0.9.4-beta",
- "com.github.pureconfig" %% "pureconfig" % "0.7.2",
+ "com.sendgrid" % "sendgrid-java" % "3.1.0" exclude ("org.mockito", "mockito-core"),
+ "com.typesafe" % "config" % "1.3.0",
+ "de.svenkubiak" % "jBCrypt" % "0.4.1",
+ "org.asynchttpclient" % "async-http-client" % "2.0.24",
+ "org.slf4j" % "slf4j-api" % "1.7.21",
"ai.x" %% "diff" % "1.2.0-get-simple-name-fix" % "test",
"org.scalatest" %% "scalatest" % "3.0.0" % "test"
))
diff --git a/project/build.properties b/project/build.properties
index 4c003f6..6561361 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1,4 +1,4 @@
#Activator-generated Properties
#Wed Jul 06 16:08:49 PDT 2016
template.uuid=a675a7df-bee3-48df-9eaa-688d99e5814e
-sbt.version=0.13.8
+sbt.version=0.13.15
diff --git a/project/plugins.sbt b/project/plugins.sbt
index a5ce3ec..83fdd9a 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,4 +1,4 @@
resolvers += "releases" at "https://drivergrp.jfrog.io/drivergrp/releases"
credentials += Credentials("Artifactory Realm", "drivergrp.jfrog.io", "sbt-publisher", "ANC-d8X-Whm-USS")
-addSbtPlugin("xyz.driver" % "sbt-settings" % "0.7.34")
+addSbtPlugin("xyz.driver" % "sbt-settings" % "0.7.39")
diff --git a/src/main/scala/xyz/driver/pdsuicommon/auth/AuthenticatedRequestContext.scala b/src/main/scala/xyz/driver/pdsuicommon/auth/AuthenticatedRequestContext.scala
index a1f93cd..e9da132 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/auth/AuthenticatedRequestContext.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/auth/AuthenticatedRequestContext.scala
@@ -3,7 +3,7 @@ package xyz.driver.pdsuicommon.auth
import xyz.driver.pdsuicommon.logging._
import xyz.driver.pdsuicommon.domain.User
-class AuthenticatedRequestContext(val executor: User, override val requestId: RequestId)
+class AuthenticatedRequestContext(val executor: User, override val requestId: RequestId, val authToken: String = "")
extends AnonymousRequestContext(requestId) {
override def equals(that: Any): Boolean = {
@@ -22,9 +22,10 @@ class AuthenticatedRequestContext(val executor: User, override val requestId: Re
object AuthenticatedRequestContext {
- def apply(executor: User) = new AuthenticatedRequestContext(executor, RequestId())
+ def apply(executor: User, authToken: String) = new AuthenticatedRequestContext(executor, RequestId(), authToken)
implicit def toPhiString(x: AuthenticatedRequestContext): PhiString = {
phi"AuthenticatedRequestContext(executor=${x.executor}, requestId=${x.requestId})"
}
+
}
diff --git a/src/main/scala/xyz/driver/pdsuicommon/concurrent/BridgeUploadQueueRepositoryAdapter.scala b/src/main/scala/xyz/driver/pdsuicommon/concurrent/BridgeUploadQueueRepositoryAdapter.scala
index 48c81c2..3bf9192 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/concurrent/BridgeUploadQueueRepositoryAdapter.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/concurrent/BridgeUploadQueueRepositoryAdapter.scala
@@ -77,8 +77,8 @@ object BridgeUploadQueueRepositoryAdapter {
sealed trait OnAttempt
object OnAttempt {
- case object Complete extends OnAttempt
- case class Continue(interval: Duration) extends OnAttempt
+ case object Complete extends OnAttempt
+ final case class Continue(interval: Duration) extends OnAttempt
implicit def toPhiString(x: OnAttempt): PhiString = Unsafe(x.toString)
}
diff --git a/src/main/scala/xyz/driver/pdsuicommon/concurrent/Cron.scala b/src/main/scala/xyz/driver/pdsuicommon/concurrent/Cron.scala
index dd84beb..6659088 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/concurrent/Cron.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/concurrent/Cron.scala
@@ -45,9 +45,9 @@ class Cron(settings: Cron.Settings) extends Closeable with StrictLogging {
* Checks unused jobs
*/
def verify(): Unit = {
- import scala.collection.JavaConversions.asScalaSet
+ import scala.collection.JavaConverters._
- val unusedJobs = settings.intervals.keySet -- jobs.toSet
+ val unusedJobs = settings.intervals.keySet -- jobs.asScala.toSet
unusedJobs.foreach { job =>
logger.warn(s"The job '$job' is listed, but not registered or ignored")
}
@@ -60,7 +60,7 @@ class Cron(settings: Cron.Settings) extends Closeable with StrictLogging {
object Cron {
- case class Settings(disable: String, intervals: Map[String, FiniteDuration])
+ final case class Settings(disable: String, intervals: Map[String, FiniteDuration])
private class SingletonTask(taskName: String, job: () => Future[Unit])(implicit ec: ExecutionContext)
extends TimerTask with StrictLogging {
diff --git a/src/main/scala/xyz/driver/pdsuicommon/concurrent/SafeBridgeUploadQueue.scala b/src/main/scala/xyz/driver/pdsuicommon/concurrent/SafeBridgeUploadQueue.scala
index 0bc8220..2f7fe6c 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/concurrent/SafeBridgeUploadQueue.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/concurrent/SafeBridgeUploadQueue.scala
@@ -11,7 +11,7 @@ object SafeBridgeUploadQueue {
trait Tag extends Product with Serializable
- case class SafeTask[T <: Tag](tag: T, private[SafeBridgeUploadQueue] val queueItem: BridgeUploadQueue.Item)
+ final case class SafeTask[T <: Tag](tag: T, private[SafeBridgeUploadQueue] val queueItem: BridgeUploadQueue.Item)
object SafeTask {
implicit def toPhiString[T <: Tag](x: SafeTask[T]): PhiString = {
diff --git a/src/main/scala/xyz/driver/pdsuicommon/db/MySqlContext.scala b/src/main/scala/xyz/driver/pdsuicommon/db/MySqlContext.scala
index f804e87..c547bf4 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/db/MySqlContext.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/db/MySqlContext.scala
@@ -18,20 +18,20 @@ import scala.util.{Failure, Success, Try}
object MySqlContext extends PhiLogging {
- case class DbCredentials(user: String,
- password: String,
- host: String,
- port: Int,
- dbName: String,
- dbCreateFlag: Boolean,
- dbContext: String,
- connectionParams: String,
- url: String)
+ final case class DbCredentials(user: String,
+ password: String,
+ host: String,
+ port: Int,
+ dbName: String,
+ dbCreateFlag: Boolean,
+ dbContext: String,
+ connectionParams: String,
+ url: String)
- case class Settings(credentials: DbCredentials,
- connection: Config,
- connectionAttemptsOnStartup: Int,
- threadPoolSize: Int)
+ final case class Settings(credentials: DbCredentials,
+ connection: Config,
+ connectionAttemptsOnStartup: Int,
+ threadPoolSize: Int)
def apply(settings: Settings): MySqlContext = {
// Prevent leaking credentials to a log
diff --git a/src/main/scala/xyz/driver/pdsuicommon/db/Pagination.scala b/src/main/scala/xyz/driver/pdsuicommon/db/Pagination.scala
index e72b5c2..92689dd 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/db/Pagination.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/db/Pagination.scala
@@ -5,7 +5,7 @@ import xyz.driver.pdsuicommon.logging._
/**
* @param pageNumber Starts with 1
*/
-case class Pagination(pageSize: Int, pageNumber: Int)
+final case class Pagination(pageSize: Int, pageNumber: Int)
object Pagination {
diff --git a/src/main/scala/xyz/driver/pdsuicommon/db/QueryBuilder.scala b/src/main/scala/xyz/driver/pdsuicommon/db/QueryBuilder.scala
index f941627..aa32166 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/db/QueryBuilder.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/db/QueryBuilder.scala
@@ -23,15 +23,15 @@ object QueryBuilder {
*/
type Binder = PreparedStatement => PreparedStatement
- case class TableData(tableName: String,
- lastUpdateFieldName: Option[String] = None,
- nullableFields: Set[String] = Set.empty)
+ final case class TableData(tableName: String,
+ lastUpdateFieldName: Option[String] = None,
+ nullableFields: Set[String] = Set.empty)
val AllFields = Set("*")
}
-case class TableLink(keyColumnName: String, foreignTableName: String, foreignKeyColumnName: String)
+final case class TableLink(keyColumnName: String, foreignTableName: String, foreignKeyColumnName: String)
object QueryBuilderParameters {
val AllFields = Set("*")
@@ -57,10 +57,11 @@ sealed trait QueryBuilderParameters {
def toSql(countQuery: Boolean, fields: Set[String], namingStrategy: NamingStrategy): (String, QueryBuilder.Binder) = {
val escapedTableName = namingStrategy.table(tableData.tableName)
val fieldsSql: String = if (countQuery) {
- "count(*)" + (tableData.lastUpdateFieldName match {
+ val suffix: String = (tableData.lastUpdateFieldName match {
case Some(lastUpdateField) => s", max($escapedTableName.${namingStrategy.column(lastUpdateField)})"
case None => ""
})
+ "count(*)" + suffix
} else {
if (fields == QueryBuilderParameters.AllFields) {
s"$escapedTableName.*"
@@ -260,11 +261,11 @@ sealed trait QueryBuilderParameters {
}
-case class PostgresQueryBuilderParameters(tableData: QueryBuilder.TableData,
- links: Map[String, TableLink] = Map.empty,
- filter: SearchFilterExpr = SearchFilterExpr.Empty,
- sorting: Sorting = Sorting.Empty,
- pagination: Option[Pagination] = None)
+final case class PostgresQueryBuilderParameters(tableData: QueryBuilder.TableData,
+ links: Map[String, TableLink] = Map.empty,
+ filter: SearchFilterExpr = SearchFilterExpr.Empty,
+ sorting: Sorting = Sorting.Empty,
+ pagination: Option[Pagination] = None)
extends QueryBuilderParameters {
def limitToSql(): String = {
@@ -279,11 +280,11 @@ case class PostgresQueryBuilderParameters(tableData: QueryBuilder.TableData,
/**
* @param links Links to another tables grouped by foreignTableName
*/
-case class MysqlQueryBuilderParameters(tableData: QueryBuilder.TableData,
- links: Map[String, TableLink] = Map.empty,
- filter: SearchFilterExpr = SearchFilterExpr.Empty,
- sorting: Sorting = Sorting.Empty,
- pagination: Option[Pagination] = None)
+final case class MysqlQueryBuilderParameters(tableData: QueryBuilder.TableData,
+ links: Map[String, TableLink] = Map.empty,
+ filter: SearchFilterExpr = SearchFilterExpr.Empty,
+ sorting: Sorting = Sorting.Empty,
+ pagination: Option[Pagination] = None)
extends QueryBuilderParameters {
def limitToSql(): String =
diff --git a/src/main/scala/xyz/driver/pdsuicommon/db/SearchFilterExpr.scala b/src/main/scala/xyz/driver/pdsuicommon/db/SearchFilterExpr.scala
index 4b66f22..0577921 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/db/SearchFilterExpr.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/db/SearchFilterExpr.scala
@@ -16,7 +16,7 @@ object SearchFilterExpr {
value = "false"
)
- case class Dimension(tableName: Option[String], name: String) {
+ final case class Dimension(tableName: Option[String], name: String) {
def isForeign: Boolean = tableName.isDefined
}
@@ -33,13 +33,13 @@ object SearchFilterExpr {
}
object Atom {
- case class Binary(dimension: Dimension, op: SearchFilterBinaryOperation, value: AnyRef) extends Atom
+ final case class Binary(dimension: Dimension, op: SearchFilterBinaryOperation, value: AnyRef) extends Atom
object Binary {
def apply(field: String, op: SearchFilterBinaryOperation, value: AnyRef): Binary =
Binary(Dimension(None, field), op, value)
}
- case class NAry(dimension: Dimension, op: SearchFilterNAryOperation, values: Seq[AnyRef]) extends Atom
+ final case class NAry(dimension: Dimension, op: SearchFilterNAryOperation, values: Seq[AnyRef]) extends Atom
object NAry {
def apply(field: String, op: SearchFilterNAryOperation, values: Seq[AnyRef]): NAry =
NAry(Dimension(None, field), op, values)
diff --git a/src/main/scala/xyz/driver/pdsuicommon/db/Sorting.scala b/src/main/scala/xyz/driver/pdsuicommon/db/Sorting.scala
index b796b83..a2c5a75 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/db/Sorting.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/db/Sorting.scala
@@ -23,11 +23,11 @@ object Sorting {
* @param name Dimension name
* @param order Order
*/
- case class Dimension(tableName: Option[String], name: String, order: SortingOrder) extends Sorting {
+ final case class Dimension(tableName: Option[String], name: String, order: SortingOrder) extends Sorting {
def isForeign: Boolean = tableName.isDefined
}
- case class Sequential(sorting: Seq[Dimension]) extends Sorting {
+ final case class Sequential(sorting: Seq[Dimension]) extends Sorting {
override def toString: String = if (isEmpty(this)) "Empty" else super.toString
}
diff --git a/src/main/scala/xyz/driver/pdsuicommon/domain/Id.scala b/src/main/scala/xyz/driver/pdsuicommon/domain/Id.scala
index 1bb70f8..e238245 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/domain/Id.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/domain/Id.scala
@@ -6,9 +6,9 @@ import xyz.driver.pdsuicommon.logging._
sealed trait Id[+T]
-case class CompoundId[Id1 <: Id[_], Id2 <: Id[_]](part1: Id1, part2: Id2) extends Id[(Id1, Id2)]
+final case class CompoundId[Id1 <: Id[_], Id2 <: Id[_]](part1: Id1, part2: Id2) extends Id[(Id1, Id2)]
-case class LongId[+T](id: Long) extends Id[T] {
+final case class LongId[+T](id: Long) extends Id[T] {
override def toString: String = id.toString
def is(longId: Long): Boolean = {
@@ -20,7 +20,7 @@ object LongId {
implicit def toPhiString[T](x: LongId[T]): PhiString = Unsafe(s"LongId(${x.id})")
}
-case class StringId[+T](id: String) extends Id[T] {
+final case class StringId[+T](id: String) extends Id[T] {
override def toString: String = id
def is(stringId: String): Boolean = {
@@ -32,7 +32,7 @@ object StringId {
implicit def toPhiString[T](x: StringId[T]): PhiString = Unsafe(s"StringId(${x.id})")
}
-case class UuidId[+T](id: UUID) extends Id[T] {
+final case class UuidId[+T](id: UUID) extends Id[T] {
override def toString: String = id.toString
}
diff --git a/src/main/scala/xyz/driver/pdsuicommon/domain/User.scala b/src/main/scala/xyz/driver/pdsuicommon/domain/User.scala
index 8d2d86d..4920176 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/domain/User.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/domain/User.scala
@@ -8,13 +8,13 @@ import xyz.driver.pdsuicommon.logging._
import xyz.driver.pdsuicommon.domain.User.Role
import xyz.driver.pdsuicommon.utils.Utils
-case class User(id: StringId[User],
- email: Email,
- name: String,
- role: Role,
- passwordHash: PasswordHash,
- latestActivity: Option[LocalDateTime],
- deleted: Option[LocalDateTime])
+final case class User(id: StringId[User],
+ email: Email,
+ name: String,
+ role: Role,
+ passwordHash: PasswordHash,
+ latestActivity: Option[LocalDateTime],
+ deleted: Option[LocalDateTime])
object User {
diff --git a/src/main/scala/xyz/driver/pdsuicommon/json/JsResultOps.scala b/src/main/scala/xyz/driver/pdsuicommon/json/JsResultOps.scala
index 07dfefc..4ff4034 100644
--- a/src/main/scala/xyz/driver/pdsuicommon/json/JsResultOps.scala
+++ b/src/main/scala/xyz/driver/pdsuicommon/json/JsResultOps.scala
@@ -7,7 +7,7 @@ import scala.util.{Failure, Success, Try}
final class JsResultOps[T](val self: JsResult[T]) extends AnyVal {
def toTry: Try[T] = {
- self.fold(
+ self.fold[Try[T]](
errors => Failure(new JsonValidationException(errors)),
Success(_)
)
diff --git a/src/main/scala/xyz/driver/pdsuicommon/serialization/PlayJsonSupport.scala b/src/main/scala/xyz/driver/pdsuicommon/serialization/PlayJsonSupport.scala
new file mode 100644
index 0000000..5158dab
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuicommon/serialization/PlayJsonSupport.scala
@@ -0,0 +1,34 @@
+package xyz.driver.pdsuicommon.serialization
+
+import akka.http.scaladsl.server.{RejectionError, ValidationRejection}
+import akka.http.scaladsl.unmarshalling.Unmarshaller
+import play.api.libs.json.{Reads, Writes}
+import play.api.libs.json.Json
+import akka.http.scaladsl.marshalling.ToEntityMarshaller
+import akka.http.scaladsl.unmarshalling.FromEntityUnmarshaller
+import akka.http.scaladsl.model.MediaTypes.`application/json`
+
+trait PlayJsonSupport {
+ import akka.http.scaladsl.marshalling.Marshaller
+
+ implicit def playJsonUnmarshaller[A: Reads]: FromEntityUnmarshaller[A] = {
+ val reads = implicitly[Reads[A]]
+ Unmarshaller.stringUnmarshaller
+ .forContentTypes(`application/json`)
+ .map(Json.parse)
+ .map(reads.reads)
+ .map(_.recoverTotal { error =>
+ throw RejectionError(ValidationRejection(s"Error reading JSON response as ${reads}."))
+ })
+ }
+
+ implicit def playJsonMarshaller[A: Writes]: ToEntityMarshaller[A] = {
+ Marshaller
+ .stringMarshaller(`application/json`)
+ .compose(Json.prettyPrint)
+ .compose(implicitly[Writes[A]].writes)
+ }
+
+}
+
+object PlayJsonSupport extends PlayJsonSupport
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/DirectReport.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/DirectReport.scala
index c09a1d8..42ac55b 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/DirectReport.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/DirectReport.scala
@@ -32,10 +32,10 @@ object DirectReport {
}
}
-case class DirectReport(id: UuidId[DirectReport],
- patientId: UuidId[Patient],
- reportType: ReportType,
- date: LocalDate,
- documentType: String,
- providerType: String,
- providerName: String)
+final case class DirectReport(id: UuidId[DirectReport],
+ patientId: UuidId[Patient],
+ reportType: ReportType,
+ date: LocalDate,
+ documentType: String,
+ providerType: String,
+ providerName: String)
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/LinkedPatient.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/LinkedPatient.scala
index 28f279f..d10310a 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/LinkedPatient.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/LinkedPatient.scala
@@ -11,4 +11,4 @@ object LinkedPatient {
}
}
-case class LinkedPatient(userId: StringId[User], patientId: UuidId[Patient], trialId: StringId[Trial])
+final case class LinkedPatient(userId: StringId[User], patientId: UuidId[Patient], trialId: StringId[Trial])
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/MedicalRecord.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/MedicalRecord.scala
index 9f38283..3b53945 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/MedicalRecord.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/MedicalRecord.scala
@@ -32,11 +32,11 @@ object MedicalRecord {
object Meta {
- case class Duplicate(predicted: Option[Boolean],
- startPage: Double,
- endPage: Double,
- startOriginalPage: Double,
- endOriginalPage: Option[Double])
+ final case class Duplicate(predicted: Option[Boolean],
+ startPage: Double,
+ endPage: Double,
+ startOriginalPage: Double,
+ endOriginalPage: Option[Double])
extends Meta {
override val metaType = "duplicate"
override def confirmed: Duplicate = copy(predicted = predicted.map(_ => false))
@@ -50,7 +50,7 @@ object MedicalRecord {
}
}
- case class Reorder(predicted: Option[Boolean], items: Seq[Int]) extends Meta {
+ final case class Reorder(predicted: Option[Boolean], items: Seq[Int]) extends Meta {
override val metaType = "reorder"
override def confirmed: Reorder = copy(predicted = predicted.map(_ => false))
}
@@ -62,7 +62,7 @@ object MedicalRecord {
}
}
- case class Rotation(predicted: Option[Boolean], items: Map[String, Int]) extends Meta {
+ final case class Rotation(predicted: Option[Boolean], items: Map[String, Int]) extends Meta {
override val metaType = "rotation"
override def confirmed: Rotation = copy(predicted = predicted.map(_ => false))
}
@@ -129,7 +129,7 @@ object MedicalRecord {
case object Empty extends PdfSource
/** @param createResource Constructor of the resource which is represents the file */
- case class Channel(createResource: () => ReadableByteChannel) extends PdfSource
+ final case class Channel(createResource: () => ReadableByteChannel) extends PdfSource
}
implicit def toPhiString(x: MedicalRecord): PhiString = {
@@ -139,22 +139,22 @@ object MedicalRecord {
}
}
-case class MedicalRecord(id: LongId[MedicalRecord],
- status: MedicalRecord.Status,
- previousStatus: Option[MedicalRecord.Status],
- assignee: Option[StringId[User]],
- previousAssignee: Option[StringId[User]],
- lastActiveUserId: Option[StringId[User]],
- patientId: UuidId[Patient],
- requestId: RecordRequestId,
- disease: String,
- caseId: Option[CaseId],
- physician: Option[String],
- sourceName: String,
- meta: Option[TextJson[List[Meta]]],
- predictedMeta: Option[TextJson[List[Meta]]],
- predictedDocuments: Option[TextJson[List[Document]]],
- lastUpdate: LocalDateTime) {
+final case class MedicalRecord(id: LongId[MedicalRecord],
+ status: MedicalRecord.Status,
+ previousStatus: Option[MedicalRecord.Status],
+ assignee: Option[StringId[User]],
+ previousAssignee: Option[StringId[User]],
+ lastActiveUserId: Option[StringId[User]],
+ patientId: UuidId[Patient],
+ requestId: RecordRequestId,
+ disease: String,
+ caseId: Option[CaseId],
+ physician: Option[String],
+ sourceName: String,
+ meta: Option[TextJson[List[Meta]]],
+ predictedMeta: Option[TextJson[List[Meta]]],
+ predictedDocuments: Option[TextJson[List[Document]]],
+ lastUpdate: LocalDateTime) {
import MedicalRecord.Status._
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Message.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Message.scala
index f02f481..3bdbac8 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/Message.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Message.scala
@@ -24,10 +24,10 @@ object Message {
implicit def toPhiString(x: Message): PhiString = {
import x._
- val entityId = recordId
- .orElse(documentId)
- .orElse(patientId)
+ val entityId: Option[String] = recordId
.map(_.toString)
+ .orElse(documentId.map(_.toString))
+ .orElse(patientId.map(_.toString))
phi"Message(id=$id, userId=$userId, isDraft=$isDraft, entityId=${Unsafe(entityId)}"
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/RawPatientDocument.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/RawPatientDocument.scala
index 8e72023..b66483c 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/RawPatientDocument.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/RawPatientDocument.scala
@@ -5,16 +5,16 @@ import java.time.LocalDate
import xyz.driver.pdsuicommon.domain.{LongId, UuidId}
import xyz.driver.pdsuicommon.logging._
-case class RawPatientDocument(disease: String,
- patientId: UuidId[Patient],
- requestId: RecordRequestId,
- recordId: LongId[MedicalRecord],
- recordStatus: MedicalRecord.Status,
- documentId: LongId[Document],
- documentType: String,
- documentProviderType: String,
- documentStartDate: LocalDate,
- documentStatus: Document.Status)
+final case class RawPatientDocument(disease: String,
+ patientId: UuidId[Patient],
+ requestId: RecordRequestId,
+ recordId: LongId[MedicalRecord],
+ recordStatus: MedicalRecord.Status,
+ documentId: LongId[Document],
+ documentType: String,
+ documentProviderType: String,
+ documentStartDate: LocalDate,
+ documentStatus: Document.Status)
object RawPatientDocument {
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/RawTrialLabel.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/RawTrialLabel.scala
index 82204c2..9e69c87 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/RawTrialLabel.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/RawTrialLabel.scala
@@ -5,19 +5,19 @@ import java.time.LocalDateTime
import xyz.driver.pdsuicommon.domain.{LongId, StringId, UuidId}
import xyz.driver.pdsuicommon.logging._
-case class RawTrialLabel(nctId: StringId[Trial],
- trialId: UuidId[Trial],
- condition: String,
- lastReviewed: LocalDateTime,
- armName: String,
- armId: LongId[Arm],
- labelId: LongId[Label],
- value: Option[Boolean],
- criterionId: LongId[Criterion],
- criteria: String,
- criterionArmId: LongId[Arm],
- isCompound: Boolean,
- isDefining: Boolean)
+final case class RawTrialLabel(nctId: StringId[Trial],
+ trialId: UuidId[Trial],
+ condition: String,
+ lastReviewed: LocalDateTime,
+ armName: String,
+ armId: LongId[Arm],
+ labelId: LongId[Label],
+ value: Option[Boolean],
+ criterionId: LongId[Criterion],
+ criteria: String,
+ criterionArmId: LongId[Arm],
+ isCompound: Boolean,
+ isDefining: Boolean)
object RawTrialLabel {
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala
index 3fe8176..f5c6974 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala
@@ -52,16 +52,15 @@ object Trial {
implicit def toPhiString(x: Status): PhiString = Unsafe(Utils.getClassSimpleName(x.getClass))
}
- case class PdfSource(path: Path) extends AnyVal
+ final case class PdfSource(path: Path) extends AnyVal
implicit def toPhiString(x: Trial): PhiString = {
import x._
phi"Trial(id=$id, externalId=$externalId, status=$status, previousStatus=$previousStatus, " +
- phi"lastActiveUserId=$lastActiveUserId, assignee=$assignee, previousAssignee=$previousAssignee, " +
- phi"isSummaryReviewed=$isSummaryReviewed, isCriteriaReviewed=$isCriteriaReviewed)"
+ phi"lastActiveUserId=$lastActiveUserId, assignee=$assignee, previousAssignee=$previousAssignee, "
}
- case class Locations(locations: List[String])
+ final case class Locations(locations: List[String])
sealed trait Condition
@@ -71,7 +70,13 @@ object Trial {
case object Lung extends Condition
case object Prostate extends Condition
- val All = Set(Breast, Lung, Prostate)
+ def fromString(condition: String): Condition = condition match {
+ case "Breast" => Breast
+ case "Lung" => Lung
+ case "Prostate" => Prostate
+ }
+
+ val All: Set[Condition] = Set(Breast, Lung, Prostate)
}
}
@@ -93,14 +98,7 @@ final case class Trial(id: StringId[Trial],
overviewTemplate: String,
isUpdated: Boolean,
title: String,
- originalTitle: String,
- isSummaryReviewed: Boolean,
- isCriteriaReviewed: Boolean,
- eligibilityCriteriaChecksum: String,
- briefSummaryChecksum: String,
- detailedDescriptionChecksum: String,
- armDescriptionChecksum: String) {
-
+ originalTitle: String) {
import Trial.Status._
if (previousStatus.nonEmpty) {
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/ListResponse.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/ListResponse.scala
index c823df5..3fbeac8 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/ListResponse.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/ListResponse.scala
@@ -7,11 +7,11 @@ import xyz.driver.pdsuicommon.json.Serialization.seqJsonFormat
import play.api.libs.functional.syntax._
import play.api.libs.json._
-case class ListResponse[+T](items: Seq[T], meta: ListResponse.Meta)
+final case class ListResponse[+T](items: Seq[T], meta: ListResponse.Meta)
object ListResponse {
- case class Meta(itemsCount: Int, pageNumber: Int, pageSize: Int, lastUpdate: Option[LocalDateTime])
+ final case class Meta(itemsCount: Int, pageNumber: Int, pageSize: Int, lastUpdate: Option[LocalDateTime])
object Meta {
def apply(itemsCount: Int, pagination: Pagination, lastUpdate: Option[LocalDateTime]): Meta = {
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/arm/ApiArm.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/arm/ApiArm.scala
index 2185e3a..32e2b54 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/arm/ApiArm.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/arm/ApiArm.scala
@@ -1,22 +1,35 @@
package xyz.driver.pdsuidomain.formats.json.arm
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
import xyz.driver.pdsuidomain.entities.Arm
import play.api.libs.functional.syntax._
import play.api.libs.json._
-final case class ApiArm(id: Long, name: String, trialId: String)
+final case class ApiArm(id: Long, name: String, originalName: String, trialId: String) {
+
+ def toDomain: Arm = Arm(
+ id = LongId(this.id),
+ name = this.name,
+ originalName = this.originalName,
+ trialId = StringId(this.trialId),
+ deleted = None // if we have an ApiArm object, the Arm itself has not been deleted
+ )
+
+}
object ApiArm {
implicit val format: Format[ApiArm] = (
(JsPath \ "id").format[Long] and
(JsPath \ "name").format[String] and
+ (JsPath \ "originalName").format[String] and
(JsPath \ "trialId").format[String]
)(ApiArm.apply, unlift(ApiArm.unapply))
def fromDomain(arm: Arm): ApiArm = ApiArm(
id = arm.id.id,
name = arm.name,
+ originalName = arm.originalName,
trialId = arm.trialId.id
)
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/intervention/ApiIntervention.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/intervention/ApiIntervention.scala
index 39e0000..39acbde 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/intervention/ApiIntervention.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/intervention/ApiIntervention.scala
@@ -1,6 +1,7 @@
package xyz.driver.pdsuidomain.formats.json.intervention
-import xyz.driver.pdsuidomain.entities.InterventionWithArms
+import xyz.driver.pdsuicommon.domain.{LongId, StringId}
+import xyz.driver.pdsuidomain.entities.{Intervention, InterventionArm, InterventionWithArms}
import play.api.libs.functional.syntax._
import play.api.libs.json.{Format, JsPath}
@@ -10,7 +11,31 @@ final case class ApiIntervention(id: Long,
description: String,
isActive: Boolean,
arms: List[Long],
- trialId: String)
+ trialId: String,
+ originalName: String,
+ originalDescription: String,
+ originalType: Option[String]) {
+
+ def toDomain = {
+ val intervention = Intervention(
+ id = LongId(this.id),
+ trialId = StringId(this.trialId),
+ name = this.name,
+ originalName = this.originalName,
+ typeId = this.typeId.map(id => LongId(id)),
+ originalType = this.originalType.map(id => id.toString),
+ description = this.description,
+ originalDescription = this.originalDescription,
+ isActive = this.isActive
+ )
+
+ InterventionWithArms(intervention, this.arms.map { armId =>
+ InterventionArm(LongId(armId), intervention.id)
+ })
+
+ }
+
+}
object ApiIntervention {
@@ -21,7 +46,10 @@ object ApiIntervention {
(JsPath \ "description").format[String] and
(JsPath \ "isActive").format[Boolean] and
(JsPath \ "arms").format[List[Long]] and
- (JsPath \ "trialId").format[String]
+ (JsPath \ "trialId").format[String] and
+ (JsPath \ "originalName").format[String] and
+ (JsPath \ "originalDescription").format[String] and
+ (JsPath \ "originalType").formatNullable[String]
)(ApiIntervention.apply, unlift(ApiIntervention.unapply))
def fromDomain(interventionWithArms: InterventionWithArms): ApiIntervention = {
@@ -35,7 +63,10 @@ object ApiIntervention {
description = intervention.description,
isActive = intervention.isActive,
arms = arms.map(_.armId.id),
- trialId = intervention.trialId.id
+ trialId = intervention.trialId.id,
+ originalName = intervention.originalName,
+ originalDescription = intervention.originalDescription,
+ originalType = intervention.originalType
)
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/message/ApiMessage.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/message/ApiMessage.scala
index 2591509..425eeac 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/message/ApiMessage.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/message/ApiMessage.scala
@@ -4,6 +4,7 @@ import java.time.{ZoneId, ZonedDateTime}
import play.api.libs.functional.syntax._
import play.api.libs.json.{Format, JsPath}
+import xyz.driver.pdsuicommon.domain.{LongId, StringId, UuidId}
import xyz.driver.pdsuidomain.entities.Message
final case class ApiMessage(id: Long,
@@ -19,7 +20,26 @@ final case class ApiMessage(id: Long,
endPage: Option[Double],
evidence: Option[String],
archiveRequired: Option[Boolean],
- meta: Option[String])
+ meta: Option[String]) {
+
+ def toDomain = Message(
+ id = LongId(this.id),
+ text = this.text,
+ lastUpdate = this.lastUpdate.toLocalDateTime(),
+ userId = StringId(this.userId),
+ isDraft = this.isDraft,
+ recordId = this.recordId.map(id => LongId(id)),
+ documentId = this.documentId.map(id => LongId(id)),
+ patientId = this.patientId.map(id => UuidId(id)),
+ trialId = this.trialId.map(id => StringId(id)),
+ startPage = this.startPage,
+ endPage = this.endPage,
+ evidence = this.evidence,
+ archiveRequired = this.archiveRequired,
+ meta = this.meta
+ )
+
+}
object ApiMessage {
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial/ApiTrial.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial/ApiTrial.scala
index 940f1f0..2556feb 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial/ApiTrial.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/trial/ApiTrial.scala
@@ -2,65 +2,99 @@ package xyz.driver.pdsuidomain.formats.json.trial
import java.time.{ZoneId, ZonedDateTime}
import java.util.UUID
+import xyz.driver.pdsuicommon.domain.{LongId, StringId, UuidId}
import xyz.driver.pdsuidomain.entities.Trial
import play.api.libs.functional.syntax._
import play.api.libs.json._
final case class ApiTrial(id: String,
- lastUpdate: Option[ZonedDateTime],
+ externalId: UUID,
+ lastUpdate: ZonedDateTime,
status: String,
assignee: Option[String],
previousStatus: Option[String],
previousAssignee: Option[String],
lastActiveUser: Option[String],
- condition: Option[String],
- phase: Option[String],
+ condition: String,
+ phase: String,
hypothesisId: Option[UUID],
studyDesignId: Option[Long],
+ originalStudyDesign: Option[String],
isPartner: Boolean,
overview: Option[String],
overviewTemplate: String,
isUpdated: Boolean,
- title: String)
+ title: String,
+ originalTitle: String) {
+
+ def toDomain = Trial(
+ id = StringId(this.id),
+ externalId = UuidId(this.externalId),
+ status = TrialStatus.statusFromString(this.status),
+ assignee = this.assignee.map(id => StringId(id)),
+ previousStatus = this.previousStatus.map(s => TrialStatus.statusFromString(s)),
+ previousAssignee = this.previousAssignee.map(id => StringId(id)),
+ lastActiveUserId = this.lastActiveUser.map(id => StringId(id)),
+ lastUpdate = this.lastUpdate.toLocalDateTime(),
+ condition = Trial.Condition.fromString(this.condition),
+ phase = this.phase,
+ hypothesisId = this.hypothesisId.map(id => UuidId(id)),
+ studyDesignId = this.studyDesignId.map(id => LongId(id)),
+ originalStudyDesign = this.originalStudyDesign,
+ isPartner = this.isPartner,
+ overview = this.overview,
+ overviewTemplate = this.overviewTemplate,
+ isUpdated = this.isUpdated,
+ title = this.title,
+ originalTitle = this.originalTitle
+ )
+
+}
object ApiTrial {
implicit val format: Format[ApiTrial] = (
(JsPath \ "id").format[String] and
- (JsPath \ "lastUpdate").formatNullable[ZonedDateTime] and
+ (JsPath \ "externalid").format[UUID] and
+ (JsPath \ "lastUpdate").format[ZonedDateTime] and
(JsPath \ "status").format[String] and
(JsPath \ "assignee").formatNullable[String] and
(JsPath \ "previousStatus").formatNullable[String] and
(JsPath \ "previousAssignee").formatNullable[String] and
(JsPath \ "lastActiveUser").formatNullable[String] and
- (JsPath \ "condition").formatNullable[String] and
- (JsPath \ "phase").formatNullable[String] and
+ (JsPath \ "condition").format[String] and
+ (JsPath \ "phase").format[String] and
(JsPath \ "hypothesisId").formatNullable[UUID] and
(JsPath \ "studyDesignId").formatNullable[Long] and
+ (JsPath \ "originalStudyDesignId").formatNullable[String] and
(JsPath \ "isPartner").format[Boolean] and
(JsPath \ "overview").formatNullable[String] and
(JsPath \ "overviewTemplate").format[String] and
(JsPath \ "isUpdated").format[Boolean] and
- (JsPath \ "title").format[String]
+ (JsPath \ "title").format[String] and
+ (JsPath \ "otiginalTitle").format[String]
)(ApiTrial.apply, unlift(ApiTrial.unapply))
def fromDomain(trial: Trial): ApiTrial = ApiTrial(
id = trial.id.id,
+ externalId = trial.externalId.id,
status = TrialStatus.statusToString(trial.status),
assignee = trial.assignee.map(_.id),
previousStatus = trial.previousStatus.map(TrialStatus.statusToString),
previousAssignee = trial.previousAssignee.map(_.id),
lastActiveUser = trial.lastActiveUserId.map(_.id),
- lastUpdate = Option(ZonedDateTime.of(trial.lastUpdate, ZoneId.of("Z"))),
- condition = Option(trial.condition.toString),
- phase = Option(trial.phase),
+ lastUpdate = ZonedDateTime.of(trial.lastUpdate, ZoneId.of("Z")),
+ condition = trial.condition.toString,
+ phase = trial.phase,
hypothesisId = trial.hypothesisId.map(_.id),
studyDesignId = trial.studyDesignId.map(_.id),
+ originalStudyDesign = trial.originalStudyDesign,
isPartner = trial.isPartner,
overview = trial.overview,
overviewTemplate = trial.overviewTemplate,
isUpdated = trial.isUpdated,
- title = trial.title
+ title = trial.title,
+ originalTitle = trial.originalTitle
)
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/user/ApiPartialUser.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/user/ApiPartialUser.scala
index f31efb3..5fad653 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/formats/json/user/ApiPartialUser.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/user/ApiPartialUser.scala
@@ -63,10 +63,12 @@ object ApiPartialUser {
implicit val format: Format[ApiPartialUser] = (
(JsPath \ "email").formatNullable[String](Format(Reads.email, Writes.StringWrites)) and
- (JsPath \ "name").formatNullable[String](Format(
- Reads.filterNot[String](ValidationError("Username is too long (max length is 255 chars)", 255))(_.length > 255),
- Writes.StringWrites
- )) and
+ (JsPath \ "name").formatNullable[String](
+ Format(
+ Reads.filterNot[String](ValidationError("Username is too long (max length is 255 chars)", 255))(
+ _.length > 255),
+ Writes.StringWrites
+ )) and
(JsPath \ "roleId").formatNullable[String](
Format(Reads
.of[String]
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/ArmService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/ArmService.scala
index 8c89505..1f907c8 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/ArmService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/ArmService.scala
@@ -22,7 +22,7 @@ object ArmService {
sealed trait GetByIdReply
object GetByIdReply {
- case class Entity(x: Arm) extends GetByIdReply
+ final case class Entity(x: Arm) extends GetByIdReply
type Error = GetByIdReply with DomainError
@@ -31,7 +31,7 @@ object ArmService {
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
+ final case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
extends GetByIdReply with DomainError
}
@@ -39,7 +39,7 @@ object ArmService {
object GetListReply {
type Error = GetListReply with DomainError
- case class EntityList(xs: Seq[Arm], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[Arm], totalFound: Int) extends GetListReply
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -71,7 +71,7 @@ object ArmService {
sealed trait CreateReply
object CreateReply {
- case class Created(x: Arm) extends CreateReply
+ final case class Created(x: Arm) extends CreateReply
type Error = CreateReply with DomainError
@@ -101,7 +101,7 @@ object ArmService {
case object AuthorizationError
extends DeleteReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends DeleteReply with DomainError
+ final case class CommonError(userMessage: String) extends DeleteReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/CategoryService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/CategoryService.scala
deleted file mode 100644
index f8d820b..0000000
--- a/src/main/scala/xyz/driver/pdsuidomain/services/CategoryService.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-package xyz.driver.pdsuidomain.services
-
-import xyz.driver.pdsuicommon.auth.AuthenticatedRequestContext
-import xyz.driver.pdsuicommon.db.Sorting
-import xyz.driver.pdsuicommon.error.DomainError
-import xyz.driver.pdsuidomain.entities.CategoryWithLabels
-
-import scala.concurrent.Future
-
-object CategoryService {
- sealed trait GetListReply
- object GetListReply {
- case class EntityList(xs: Seq[CategoryWithLabels], totalFound: Int) extends GetListReply
-
- case object AuthorizationError extends GetListReply with DomainError.AuthorizationError {
- def userMessage: String = "Access denied"
- }
- }
-}
-
-trait CategoryService {
-
- import CategoryService._
-
- def getAll(sorting: Option[Sorting] = None)(
- implicit requestContext: AuthenticatedRequestContext): Future[GetListReply]
-}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/CriterionService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/CriterionService.scala
index ffb7843..fd9268b 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/CriterionService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/CriterionService.scala
@@ -21,7 +21,7 @@ object CriterionService {
def userMessage: String = "Access denied"
}
- case class RichCriterion(criterion: Criterion, armIds: Seq[LongId[Arm]], labels: Seq[CriterionLabel])
+ final case class RichCriterion(criterion: Criterion, armIds: Seq[LongId[Arm]], labels: Seq[CriterionLabel])
object RichCriterion {
implicit def toPhiString(x: RichCriterion): PhiString = {
import x._
@@ -33,17 +33,17 @@ object CriterionService {
object CreateReply {
type Error = CreateReply with DomainError
- case class Created(x: RichCriterion) extends CreateReply
+ final case class Created(x: RichCriterion) extends CreateReply
case object AuthorizationError
extends CreateReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends CreateReply with DomainError
+ final case class CommonError(userMessage: String) extends CreateReply with DomainError
}
sealed trait GetByIdReply
object GetByIdReply {
- case class Entity(x: RichCriterion) extends GetByIdReply
+ final case class Entity(x: RichCriterion) extends GetByIdReply
type Error = GetByIdReply with DomainError
@@ -52,7 +52,7 @@ object CriterionService {
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
+ final case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
extends GetByIdReply with DomainError
implicit def toPhiString(reply: GetByIdReply): PhiString = reply match {
@@ -63,7 +63,7 @@ object CriterionService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[RichCriterion], totalFound: Int, lastUpdate: Option[LocalDateTime])
+ final case class EntityList(xs: Seq[RichCriterion], totalFound: Int, lastUpdate: Option[LocalDateTime])
extends GetListReply
case object AuthorizationError
@@ -74,14 +74,14 @@ object CriterionService {
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: RichCriterion) extends UpdateReply
+ final case class Updated(updated: RichCriterion) extends UpdateReply
case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError
case object AuthorizationError
extends UpdateReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
}
sealed trait DeleteReply
@@ -95,7 +95,7 @@ object CriterionService {
case object AuthorizationError
extends DeleteReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends DeleteReply with DomainError
+ final case class CommonError(userMessage: String) extends DeleteReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/DocumentService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/DocumentService.scala
index 2c01a7e..9338a59 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/DocumentService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/DocumentService.scala
@@ -23,7 +23,7 @@ object DocumentService {
sealed trait GetByIdReply
object GetByIdReply {
- case class Entity(x: Document) extends GetByIdReply
+ final case class Entity(x: Document) extends GetByIdReply
type Error = GetByIdReply with DomainError
@@ -32,7 +32,7 @@ object DocumentService {
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
+ final case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
extends GetByIdReply with DomainError
implicit def toPhiString(reply: GetByIdReply): PhiString = reply match {
@@ -43,19 +43,20 @@ object DocumentService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[Document], totalFound: Int, lastUpdate: Option[LocalDateTime]) extends GetListReply
+ final case class EntityList(xs: Seq[Document], totalFound: Int, lastUpdate: Option[LocalDateTime])
+ extends GetListReply
type Error = GetListReply with DomainError
case object AuthorizationError
extends GetListReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends GetListReply with DomainError
+ final case class CommonError(userMessage: String) extends GetListReply with DomainError
}
sealed trait CreateReply
object CreateReply {
- case class Created(x: Document) extends CreateReply
+ final case class Created(x: Document) extends CreateReply
type Error = CreateReply with DomainError
@@ -64,12 +65,12 @@ object DocumentService {
case object AuthorizationError
extends CreateReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends CreateReply with DomainError
+ final case class CommonError(userMessage: String) extends CreateReply with DomainError
}
sealed trait UpdateReply
object UpdateReply {
- case class Updated(updated: Document) extends UpdateReply
+ final case class Updated(updated: Document) extends UpdateReply
type Error = UpdateReply with DomainError
@@ -78,7 +79,7 @@ object DocumentService {
case object AuthorizationError
extends UpdateReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
implicit def toPhiString(reply: UpdateReply): PhiString = reply match {
case Updated(x) => phi"Updated($x)"
@@ -97,7 +98,7 @@ object DocumentService {
case object AuthorizationError
extends DeleteReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends DeleteReply with DomainError
+ final case class CommonError(userMessage: String) extends DeleteReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/DocumentTypeService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/DocumentTypeService.scala
index 1268cbf..0f1bf76 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/DocumentTypeService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/DocumentTypeService.scala
@@ -11,7 +11,7 @@ import scala.concurrent.Future
object DocumentTypeService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[DocumentType], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[DocumentType], totalFound: Int) extends GetListReply
case object AuthorizationError extends GetListReply with DomainError.AuthorizationError {
def userMessage: String = "Access denied"
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/ExportService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/ExportService.scala
index ddc927d..a313703 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/ExportService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/ExportService.scala
@@ -18,7 +18,7 @@ object ExportService {
object GetPatientReply {
type Error = GetPatientReply with DomainError
- case class Entity(x: ExportPatientWithLabels) extends GetPatientReply
+ final case class Entity(x: ExportPatientWithLabels) extends GetPatientReply
case object NotFoundError extends GetPatientReply with DomainError.NotFoundError {
def userMessage: String = "Patient not found"
@@ -27,7 +27,7 @@ object ExportService {
sealed trait GetTrialListReply
object GetTrialListReply {
- case class EntityList(xs: Seq[ExportTrial], totalFound: Int, lastUpdate: Option[LocalDateTime])
+ final case class EntityList(xs: Seq[ExportTrial], totalFound: Int, lastUpdate: Option[LocalDateTime])
extends GetTrialListReply
}
@@ -35,7 +35,7 @@ object ExportService {
object GetTrialReply {
type Error = GetTrialReply with DomainError
- case class Entity(x: ExportTrialWithLabels) extends GetTrialReply
+ final case class Entity(x: ExportTrialWithLabels) extends GetTrialReply
case object NotFoundError extends GetTrialReply with DomainError.NotFoundError {
def userMessage: String = "Trial not found"
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/ExtractedDataService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/ExtractedDataService.scala
index 93cb3ea..afb994e 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/ExtractedDataService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/ExtractedDataService.scala
@@ -19,7 +19,7 @@ object ExtractedDataService {
def userMessage: String = "Access denied"
}
- case class RichExtractedData(extractedData: ExtractedData, labels: List[ExtractedDataLabel])
+ final case class RichExtractedData(extractedData: ExtractedData, labels: List[ExtractedDataLabel])
object RichExtractedData {
implicit def toPhiString(x: RichExtractedData): PhiString = {
@@ -31,19 +31,19 @@ object ExtractedDataService {
sealed trait GetByIdReply
object GetByIdReply {
type Error = GetByIdReply with DomainError
- case class Entity(x: RichExtractedData) extends GetByIdReply
+ final case class Entity(x: RichExtractedData) extends GetByIdReply
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
case object NotFoundError extends GetByIdReply with DefaultNotFoundError with DomainError.NotFoundError
- case class CommonError(userMessage: String) extends GetByIdReply with DomainError
+ final case class CommonError(userMessage: String) extends GetByIdReply with DomainError
}
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[RichExtractedData], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[RichExtractedData], totalFound: Int) extends GetListReply
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -52,25 +52,25 @@ object ExtractedDataService {
sealed trait CreateReply
object CreateReply {
type Error = CreateReply with DomainError
- case class Created(x: RichExtractedData) extends CreateReply
+ final case class Created(x: RichExtractedData) extends CreateReply
case object AuthorizationError
extends CreateReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends CreateReply with DomainError
+ final case class CommonError(userMessage: String) extends CreateReply with DomainError
}
sealed trait UpdateReply
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: RichExtractedData) extends UpdateReply
+ final case class Updated(updated: RichExtractedData) extends UpdateReply
case object AuthorizationError
extends UpdateReply with DefaultAccessDeniedError with DomainError.AuthorizationError
case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
}
sealed trait DeleteReply
@@ -83,7 +83,7 @@ object ExtractedDataService {
case object NotFoundError extends DeleteReply with DefaultNotFoundError with DomainError.NotFoundError
- case class CommonError(userMessage: String) extends DeleteReply with DomainError
+ final case class CommonError(userMessage: String) extends DeleteReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/HypothesisService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/HypothesisService.scala
index 7fccf7f..52cd6c8 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/HypothesisService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/HypothesisService.scala
@@ -10,7 +10,7 @@ import scala.concurrent.Future
object HypothesisService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[Hypothesis], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[Hypothesis], totalFound: Int) extends GetListReply
case object AuthorizationError extends GetListReply with DomainError.AuthorizationError {
def userMessage: String = "Access denied"
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/InterventionService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/InterventionService.scala
index a4b380f..439e456 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/InterventionService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/InterventionService.scala
@@ -21,7 +21,7 @@ object InterventionService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[InterventionWithArms], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[InterventionWithArms], totalFound: Int) extends GetListReply
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -29,7 +29,7 @@ object InterventionService {
sealed trait GetByIdReply
object GetByIdReply {
- case class Entity(x: InterventionWithArms) extends GetByIdReply
+ final case class Entity(x: InterventionWithArms) extends GetByIdReply
type Error = GetByIdReply with DomainError
@@ -38,7 +38,7 @@ object InterventionService {
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
+ final case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
extends GetByIdReply with DomainError
implicit def toPhiString(reply: GetByIdReply): PhiString = reply match {
@@ -51,14 +51,14 @@ object InterventionService {
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: InterventionWithArms) extends UpdateReply
+ final case class Updated(updated: InterventionWithArms) extends UpdateReply
case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError
case object AuthorizationError
extends UpdateReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/InterventionTypeService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/InterventionTypeService.scala
index 5805655..298a92d 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/InterventionTypeService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/InterventionTypeService.scala
@@ -10,7 +10,7 @@ import scala.concurrent.Future
object InterventionTypeService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[InterventionType], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[InterventionType], totalFound: Int) extends GetListReply
case object AuthorizationError extends GetListReply with DomainError.AuthorizationError {
def userMessage: String = "Access denied"
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/KeywordService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/KeywordService.scala
deleted file mode 100644
index 8824c41..0000000
--- a/src/main/scala/xyz/driver/pdsuidomain/services/KeywordService.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-package xyz.driver.pdsuidomain.services
-
-import xyz.driver.pdsuicommon.auth.AuthenticatedRequestContext
-import xyz.driver.pdsuicommon.db.Sorting
-import xyz.driver.pdsuicommon.error.DomainError
-import xyz.driver.pdsuidomain.entities.KeywordWithLabels
-
-import scala.concurrent.Future
-
-object KeywordService {
-
- sealed trait GetListReply
- object GetListReply {
- case class EntityList(xs: Seq[KeywordWithLabels], totalFound: Int) extends GetListReply
-
- case object AuthorizationError extends GetListReply with DomainError.AuthorizationError {
- def userMessage: String = "Access denied"
- }
- }
-}
-
-trait KeywordService {
-
- import KeywordService._
-
- def getAll(sorting: Option[Sorting] = None)(
- implicit requestContext: AuthenticatedRequestContext): Future[GetListReply]
-}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/LabelService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/LabelService.scala
deleted file mode 100644
index aadc5fb..0000000
--- a/src/main/scala/xyz/driver/pdsuidomain/services/LabelService.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-package xyz.driver.pdsuidomain.services
-
-import xyz.driver.pdsuicommon.auth.AuthenticatedRequestContext
-import xyz.driver.pdsuicommon.db.Sorting
-import xyz.driver.pdsuicommon.error.DomainError
-import xyz.driver.pdsuidomain.entities.Label
-
-import scala.concurrent.Future
-
-object LabelService {
-
- sealed trait GetListReply
- object GetListReply {
- case class EntityList(xs: Seq[Label], totalFound: Int) extends GetListReply
-
- case object AuthorizationError extends GetListReply with DomainError.AuthorizationError {
- def userMessage: String = "Access denied"
- }
- }
-}
-
-trait LabelService {
- import LabelService._
-
- def getAll(sorting: Option[Sorting] = None)(
- implicit requestContext: AuthenticatedRequestContext): Future[GetListReply]
-}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/MedicalRecordService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/MedicalRecordService.scala
index f077d82..b2fc9f9 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/MedicalRecordService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/MedicalRecordService.scala
@@ -25,13 +25,13 @@ object MedicalRecordService {
sealed trait GetByIdReply
object GetByIdReply {
- case class Entity(x: MedicalRecord) extends GetByIdReply
+ final case class Entity(x: MedicalRecord) extends GetByIdReply
type Error = GetByIdReply with DomainError
case object NotFoundError extends GetByIdReply with DomainError.NotFoundError with DefaultNotFoundError
- case class CommonError(userMessage: String) extends GetByIdReply with DomainError
+ final case class CommonError(userMessage: String) extends GetByIdReply with DomainError
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -41,7 +41,7 @@ object MedicalRecordService {
object GetPdfSourceReply {
type Error = GetPdfSourceReply with DomainError
- case class Entity(x: PdfSource.Channel) extends GetPdfSourceReply
+ final case class Entity(x: PdfSource.Channel) extends GetPdfSourceReply
case object AuthorizationError
extends GetPdfSourceReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -52,12 +52,12 @@ object MedicalRecordService {
case object RecordNotFoundError extends GetPdfSourceReply with DomainError.NotFoundError with DefaultNotFoundError
- case class CommonError(userMessage: String) extends GetPdfSourceReply with DomainError
+ final case class CommonError(userMessage: String) extends GetPdfSourceReply with DomainError
}
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[MedicalRecord], totalFound: Int, lastUpdate: Option[LocalDateTime])
+ final case class EntityList(xs: Seq[MedicalRecord], totalFound: Int, lastUpdate: Option[LocalDateTime])
extends GetListReply
case object AuthorizationError
@@ -66,24 +66,24 @@ object MedicalRecordService {
sealed trait CreateReply
object CreateReply {
- case class Created(x: MedicalRecord) extends CreateReply
+ final case class Created(x: MedicalRecord) extends CreateReply
}
sealed trait UpdateReply
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: MedicalRecord) extends UpdateReply
+ final case class Updated(updated: MedicalRecord) extends UpdateReply
case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError
case object AuthorizationError
extends UpdateReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
}
- case class Settings(pdfSourceBucket: String)
+ final case class Settings(pdfSourceBucket: String)
}
trait MedicalRecordService {
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/MessageService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/MessageService.scala
index df57e17..6718f26 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/MessageService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/MessageService.scala
@@ -23,18 +23,18 @@ object MessageService {
sealed trait CreateReply
object CreateReply {
type Error = CreateReply with DomainError
- case class Created(x: Message) extends CreateReply
+ final case class Created(x: Message) extends CreateReply
case object AuthorizationError
extends CreateReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends CreateReply with DomainError
+ final case class CommonError(userMessage: String) extends CreateReply with DomainError
}
sealed trait GetByIdReply
object GetByIdReply {
type Error = GetByIdReply with DomainError
- case class Entity(x: Message) extends GetByIdReply
- case object NotFoundError extends GetByIdReply with DomainError.NotFoundError with DefaultNotFoundError
- case class CommonError(userMessage: String) extends GetByIdReply with DomainError
+ final case class Entity(x: Message) extends GetByIdReply
+ case object NotFoundError extends GetByIdReply with DomainError.NotFoundError with DefaultNotFoundError
+ final case class CommonError(userMessage: String) extends GetByIdReply with DomainError
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
}
@@ -42,7 +42,8 @@ object MessageService {
sealed trait GetListReply
object GetListReply {
type Error = GetListReply with DomainError
- case class EntityList(xs: Seq[Message], totalFound: Int, lastUpdate: Option[LocalDateTime]) extends GetListReply
+ final case class EntityList(xs: Seq[Message], totalFound: Int, lastUpdate: Option[LocalDateTime])
+ extends GetListReply
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
}
@@ -50,10 +51,10 @@ object MessageService {
sealed trait UpdateReply
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: Message) extends UpdateReply
+ final case class Updated(updated: Message) extends UpdateReply
case object AuthorizationError
extends UpdateReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
}
sealed trait DeleteReply
@@ -62,8 +63,8 @@ object MessageService {
case object Deleted extends DeleteReply
case object AuthorizationError
extends DeleteReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case object NotFoundError extends DeleteReply with DomainError.NotFoundError with DefaultNotFoundError
- case class CommonError(userMessage: String) extends DeleteReply with DomainError
+ case object NotFoundError extends DeleteReply with DomainError.NotFoundError with DefaultNotFoundError
+ final case class CommonError(userMessage: String) extends DeleteReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/PatientCriterionService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/PatientCriterionService.scala
index c2f7b50..9ff3879 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/PatientCriterionService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/PatientCriterionService.scala
@@ -13,9 +13,9 @@ import scala.concurrent.Future
object PatientCriterionService {
- case class DraftPatientCriterion(id: LongId[PatientCriterion],
- eligibilityStatus: Option[FuzzyValue],
- isVerified: Option[Boolean]) {
+ final case class DraftPatientCriterion(id: LongId[PatientCriterion],
+ eligibilityStatus: Option[FuzzyValue],
+ isVerified: Option[Boolean]) {
def applyTo(orig: PatientCriterion) = {
orig.copy(
eligibilityStatus = eligibilityStatus.orElse(orig.eligibilityStatus),
@@ -40,9 +40,9 @@ object PatientCriterionService {
object GetListReply {
type Error = GetListReply with DomainError
- case class EntityList(xs: Seq[(PatientCriterion, LongId[Label], List[PatientCriterionArm])],
- totalFound: Int,
- lastUpdate: Option[LocalDateTime])
+ final case class EntityList(xs: Seq[(PatientCriterion, LongId[Label], List[PatientCriterionArm])],
+ totalFound: Int,
+ lastUpdate: Option[LocalDateTime])
extends GetListReply
case object AuthorizationError
@@ -51,7 +51,7 @@ object PatientCriterionService {
case object PatientNotFoundError
extends GetListReply with DomainError.NotFoundError with DefaultPatientNotFoundError
- case class CommonError(userMessage: String) extends GetListReply with DomainError
+ final case class CommonError(userMessage: String) extends GetListReply with DomainError
}
@@ -59,7 +59,7 @@ object PatientCriterionService {
object GetByIdReply {
type Error = GetByIdReply with DomainError
- case class Entity(x: PatientCriterion, labelId: LongId[Label], armList: List[PatientCriterionArm])
+ final case class Entity(x: PatientCriterion, labelId: LongId[Label], armList: List[PatientCriterionArm])
extends GetByIdReply
case object AuthorizationError
@@ -70,7 +70,7 @@ object PatientCriterionService {
case object PatientNotFoundError
extends GetByIdReply with DomainError.NotFoundError with DefaultPatientNotFoundError
- case class CommonError(userMessage: String) extends GetByIdReply with DomainError
+ final case class CommonError(userMessage: String) extends GetByIdReply with DomainError
implicit def toPhiString(reply: GetByIdReply): PhiString = reply match {
case x: DomainError => phi"GetByIdReply.Error($x)"
@@ -82,7 +82,7 @@ object PatientCriterionService {
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(x: PatientCriterion, labelId: LongId[Label], armList: List[PatientCriterionArm])
+ final case class Updated(x: PatientCriterion, labelId: LongId[Label], armList: List[PatientCriterionArm])
extends UpdateReply
case object UpdatedList extends UpdateReply
@@ -93,7 +93,7 @@ object PatientCriterionService {
case object PatientNotFoundError
extends UpdateReply with DomainError.NotFoundError with DefaultPatientNotFoundError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/PatientEligibleTrialService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/PatientEligibleTrialService.scala
index 12cd4f3..2c17f74 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/PatientEligibleTrialService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/PatientEligibleTrialService.scala
@@ -23,7 +23,10 @@ object PatientEligibleTrialService {
def userMessage: String = "Access denied"
}
- case class RichPatientEligibleTrial(trial: Trial, group: PatientTrialArmGroupView, arms: List[PatientCriterionArm])
+ final case class RichPatientEligibleTrial(trial: Trial,
+ group: PatientTrialArmGroupView,
+ arms: List[PatientCriterionArm])
+
object RichPatientEligibleTrial {
implicit def toPhiString(x: RichPatientEligibleTrial): PhiString = {
phi"RichPatientEligibleTrial(group=${x.group}, trial=${x.trial}, arms=${x.arms})"
@@ -32,7 +35,7 @@ object PatientEligibleTrialService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[RichPatientEligibleTrial], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[RichPatientEligibleTrial], totalFound: Int) extends GetListReply
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -40,12 +43,12 @@ object PatientEligibleTrialService {
case object PatientNotFoundError
extends GetListReply with DefaultPatientNotFoundError with DomainError.NotFoundError
- case class CommonError(userMessage: String) extends GetListReply with DomainError
+ final case class CommonError(userMessage: String) extends GetListReply with DomainError
}
sealed trait GetByIdReply
object GetByIdReply {
- case class Entity(x: RichPatientEligibleTrial) extends GetByIdReply
+ final case class Entity(x: RichPatientEligibleTrial) extends GetByIdReply
type Error = GetByIdReply with DomainError
@@ -57,7 +60,7 @@ object PatientEligibleTrialService {
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends GetByIdReply with DomainError
+ final case class CommonError(userMessage: String) extends GetByIdReply with DomainError
implicit def toPhiString(reply: GetByIdReply): PhiString = reply match {
case x: DomainError => phi"GetByIdReply.Error($x)"
@@ -67,7 +70,7 @@ object PatientEligibleTrialService {
sealed trait GetCriterionListOfGroupReply
object GetCriterionListOfGroupReply {
- case class EntityList(xs: Seq[(PatientCriterion, LongId[Label], List[PatientCriterionArm])], totalFound: Int)
+ final case class EntityList(xs: Seq[(PatientCriterion, LongId[Label], List[PatientCriterionArm])], totalFound: Int)
extends GetCriterionListOfGroupReply
type Error = GetCriterionListOfGroupReply with DomainError
@@ -81,14 +84,14 @@ object PatientEligibleTrialService {
case object PatientNotFoundError
extends GetCriterionListOfGroupReply with DefaultPatientNotFoundError with DomainError.NotFoundError
- case class CommonError(userMessage: String) extends GetCriterionListOfGroupReply with DomainError
+ final case class CommonError(userMessage: String) extends GetCriterionListOfGroupReply with DomainError
}
sealed trait UpdateReply
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: RichPatientEligibleTrial) extends UpdateReply
+ final case class Updated(updated: RichPatientEligibleTrial) extends UpdateReply
case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError
@@ -98,7 +101,7 @@ object PatientEligibleTrialService {
case object AuthorizationError
extends UpdateReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
implicit def toPhiString(reply: UpdateReply): PhiString = reply match {
case Updated(x) => phi"Updated($x)"
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/PatientHypothesisService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/PatientHypothesisService.scala
index a15e11f..f782cab 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/PatientHypothesisService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/PatientHypothesisService.scala
@@ -25,7 +25,7 @@ object PatientHypothesisService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[(PatientHypothesis, Boolean)], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[(PatientHypothesis, Boolean)], totalFound: Int) extends GetListReply
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -33,12 +33,12 @@ object PatientHypothesisService {
case object PatientNotFoundError
extends GetListReply with DefaultPatientNotFoundError with DomainError.NotFoundError
- case class CommonError(userMessage: String) extends GetListReply with DomainError
+ final case class CommonError(userMessage: String) extends GetListReply with DomainError
}
sealed trait GetByIdReply
object GetByIdReply {
- case class Entity(x: PatientHypothesis, isRequired: Boolean) extends GetByIdReply
+ final case class Entity(x: PatientHypothesis, isRequired: Boolean) extends GetByIdReply
type Error = GetByIdReply with DomainError
@@ -50,7 +50,7 @@ object PatientHypothesisService {
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends GetByIdReply with DomainError
+ final case class CommonError(userMessage: String) extends GetByIdReply with DomainError
implicit def toPhiString(reply: GetByIdReply): PhiString = reply match {
case x: DomainError => phi"GetByIdReply.Error($x)"
@@ -62,7 +62,7 @@ object PatientHypothesisService {
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: PatientHypothesis) extends UpdateReply
+ final case class Updated(updated: PatientHypothesis) extends UpdateReply
case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError
@@ -72,7 +72,7 @@ object PatientHypothesisService {
case object AuthorizationError
extends UpdateReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
implicit def toPhiString(reply: UpdateReply): PhiString = reply match {
case Updated(x) => phi"Updated($x)"
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/PatientLabelEvidenceService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/PatientLabelEvidenceService.scala
index 2586798..56e2e3d 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/PatientLabelEvidenceService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/PatientLabelEvidenceService.scala
@@ -20,7 +20,7 @@ object PatientLabelEvidenceService {
sealed trait GetByIdReply
object GetByIdReply {
- case class Entity(x: PatientLabelEvidenceView) extends GetByIdReply
+ final case class Entity(x: PatientLabelEvidenceView) extends GetByIdReply
type Error = GetByIdReply with DomainError
@@ -34,7 +34,7 @@ object PatientLabelEvidenceService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[PatientLabelEvidenceView], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[PatientLabelEvidenceView], totalFound: Int) extends GetListReply
type Error = GetListReply with DomainError
@@ -44,7 +44,7 @@ object PatientLabelEvidenceService {
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends GetListReply with DomainError
+ final case class CommonError(userMessage: String) extends GetListReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/PatientLabelService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/PatientLabelService.scala
index 5fa2a4d..71b8bd4 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/PatientLabelService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/PatientLabelService.scala
@@ -25,7 +25,7 @@ object PatientLabelService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[(PatientLabel, Boolean)], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[(PatientLabel, Boolean)], totalFound: Int) extends GetListReply
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -33,12 +33,12 @@ object PatientLabelService {
case object PatientNotFoundError
extends GetListReply with DefaultPatientNotFoundError with DomainError.NotFoundError
- case class CommonError(userMessage: String) extends GetListReply with DomainError
+ final case class CommonError(userMessage: String) extends GetListReply with DomainError
}
sealed trait GetDefiningCriteriaListReply
object GetDefiningCriteriaListReply {
- case class EntityList(xs: Seq[PatientLabel], totalFound: Int) extends GetDefiningCriteriaListReply
+ final case class EntityList(xs: Seq[PatientLabel], totalFound: Int) extends GetDefiningCriteriaListReply
case object AuthorizationError
extends GetDefiningCriteriaListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -46,12 +46,12 @@ object PatientLabelService {
case object PatientNotFoundError
extends GetDefiningCriteriaListReply with DefaultPatientNotFoundError with DomainError.NotFoundError
- case class CommonError(userMessage: String) extends GetDefiningCriteriaListReply with DomainError
+ final case class CommonError(userMessage: String) extends GetDefiningCriteriaListReply with DomainError
}
sealed trait GetByLabelIdReply
object GetByLabelIdReply {
- case class Entity(x: PatientLabel, isVerified: Boolean) extends GetByLabelIdReply
+ final case class Entity(x: PatientLabel, isVerified: Boolean) extends GetByLabelIdReply
type Error = GetByLabelIdReply with DomainError
@@ -63,7 +63,7 @@ object PatientLabelService {
case object AuthorizationError
extends GetByLabelIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends GetByLabelIdReply with DomainError
+ final case class CommonError(userMessage: String) extends GetByLabelIdReply with DomainError
implicit def toPhiString(reply: GetByLabelIdReply): PhiString = reply match {
case x: DomainError => phi"GetByIdReply.Error($x)"
@@ -75,7 +75,7 @@ object PatientLabelService {
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: PatientLabel, isVerified: Boolean) extends UpdateReply
+ final case class Updated(updated: PatientLabel, isVerified: Boolean) extends UpdateReply
case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError
@@ -85,7 +85,7 @@ object PatientLabelService {
case object AuthorizationError
extends UpdateReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
implicit def toPhiString(reply: UpdateReply): PhiString = reply match {
case Updated(x, y) => phi"Updated($x, $y)"
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/PatientService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/PatientService.scala
index 4619011..ce70934 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/PatientService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/PatientService.scala
@@ -23,7 +23,8 @@ object PatientService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[Patient], totalFound: Int, lastUpdate: Option[LocalDateTime]) extends GetListReply
+ final case class EntityList(xs: Seq[Patient], totalFound: Int, lastUpdate: Option[LocalDateTime])
+ extends GetListReply
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -31,7 +32,7 @@ object PatientService {
sealed trait GetByIdReply
object GetByIdReply {
- case class Entity(x: Patient) extends GetByIdReply
+ final case class Entity(x: Patient) extends GetByIdReply
type Error = GetByIdReply with DomainError
@@ -40,7 +41,7 @@ object PatientService {
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
+ final case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
extends GetByIdReply with DomainError
implicit def toPhiString(reply: GetByIdReply): PhiString = reply match {
@@ -53,14 +54,14 @@ object PatientService {
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: Patient) extends UpdateReply
+ final case class Updated(updated: Patient) extends UpdateReply
case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError
case object AuthorizationError
extends UpdateReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
implicit def toPhiString(reply: UpdateReply): PhiString = reply match {
case Updated(x) => phi"Updated($x)"
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/ProviderTypeService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/ProviderTypeService.scala
index ef48aa0..cad17a4 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/ProviderTypeService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/ProviderTypeService.scala
@@ -10,7 +10,7 @@ import scala.concurrent.Future
object ProviderTypeService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[ProviderType], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[ProviderType], totalFound: Int) extends GetListReply
case object AuthorizationError extends GetListReply with DomainError.AuthorizationError {
def userMessage: String = "Access denied"
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/QueueUploadService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/QueueUploadService.scala
index f201fd9..340733d 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/QueueUploadService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/QueueUploadService.scala
@@ -20,28 +20,28 @@ object QueueUploadService {
object CreateReply {
type Error = CreateReply with DomainError
- case class Created(x: BridgeUploadQueue.Item) extends CreateReply
+ final case class Created(x: BridgeUploadQueue.Item) extends CreateReply
case object AuthorizationError
extends CreateReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends CreateReply with DomainError
+ final case class CommonError(userMessage: String) extends CreateReply with DomainError
}
sealed trait GetByIdReply
object GetByIdReply {
type Error = GetByIdReply with DomainError
- case class Entity(x: BridgeUploadQueue.Item) extends GetByIdReply
+ final case class Entity(x: BridgeUploadQueue.Item) extends GetByIdReply
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case object NotFoundError extends GetByIdReply with DomainError.NotFoundError with DefaultNotFoundError
- case class CommonError(userMessage: String) extends GetByIdReply with DomainError
+ case object NotFoundError extends GetByIdReply with DomainError.NotFoundError with DefaultNotFoundError
+ final case class CommonError(userMessage: String) extends GetByIdReply with DomainError
}
sealed trait GetListReply
object GetListReply {
type Error = GetListReply with DomainError
- case class EntityList(xs: Seq[BridgeUploadQueue.Item], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[BridgeUploadQueue.Item], totalFound: Int) extends GetListReply
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -51,10 +51,10 @@ object QueueUploadService {
object ResetReply {
type Error = ResetReply with DomainError
- case class Updated(updated: BridgeUploadQueue.Item) extends ResetReply
- case object AuthorizationError extends ResetReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case object NotFoundError extends ResetReply with DefaultNotFoundError with DomainError.NotFoundError
- case class CommonError(userMessage: String) extends ResetReply with DomainError
+ final case class Updated(updated: BridgeUploadQueue.Item) extends ResetReply
+ case object AuthorizationError extends ResetReply with DomainError.AuthorizationError with DefaultAccessDeniedError
+ case object NotFoundError extends ResetReply with DefaultNotFoundError with DomainError.NotFoundError
+ final case class CommonError(userMessage: String) extends ResetReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/ScrapedTrialsService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/ScrapedTrialsService.scala
index b595584..233495e 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/ScrapedTrialsService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/ScrapedTrialsService.scala
@@ -11,7 +11,7 @@ object ScrapedTrialsService {
object GetRawTrialReply {
type Error = GetRawTrialReply with DomainError
- case class TrialRawEntity(rawTrial: ScrapedTrial) extends GetRawTrialReply
+ final case class TrialRawEntity(rawTrial: ScrapedTrial) extends GetRawTrialReply
case object NotFoundError extends GetRawTrialReply with DomainError.NotFoundError {
override def userMessage: String = "Raw clinical trial not found"
@@ -20,12 +20,12 @@ object ScrapedTrialsService {
sealed trait GetRawTrialOptReply
object GetRawTrialOptReply {
- case class TrialRawEntity(rawTrial: Option[ScrapedTrial]) extends GetRawTrialOptReply
+ final case class TrialRawEntity(rawTrial: Option[ScrapedTrial]) extends GetRawTrialOptReply
}
sealed trait GetAllRawTrialsExceptReply
object GetAllRawTrialsExceptReply {
- case class MultipleRawTrials(rawTrials: Seq[ScrapedTrial]) extends GetAllRawTrialsExceptReply
+ final case class MultipleRawTrials(rawTrials: Seq[ScrapedTrial]) extends GetAllRawTrialsExceptReply
}
sealed trait GetHtmlForReply
@@ -35,7 +35,7 @@ object ScrapedTrialsService {
/**
* @param trialHtmlMap nctId -> html
*/
- case class HtmlMap(trialHtmlMap: TrialHtmlMap) extends GetHtmlForReply
+ final case class HtmlMap(trialHtmlMap: TrialHtmlMap) extends GetHtmlForReply
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/StudyDesignService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/StudyDesignService.scala
index a1ce613..e98c1ec 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/StudyDesignService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/StudyDesignService.scala
@@ -10,7 +10,7 @@ import scala.concurrent.Future
object StudyDesignService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[StudyDesign], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[StudyDesign], totalFound: Int) extends GetListReply
case object AuthorizationError extends GetListReply with DomainError.AuthorizationError {
def userMessage: String = "Access denied"
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/TrialHistoryService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/TrialHistoryService.scala
index 9ad9fc1..bcf1c53 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/TrialHistoryService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/TrialHistoryService.scala
@@ -22,10 +22,10 @@ object TrialHistoryService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[TrialHistory], totalFound: Int, lastUpdate: Option[LocalDateTime])
+ final case class EntityList(xs: Seq[TrialHistory], totalFound: Int, lastUpdate: Option[LocalDateTime])
extends GetListReply
- case object AuthorizationError
+ final case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/TrialIssueService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/TrialIssueService.scala
index df231ac..726feda 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/TrialIssueService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/TrialIssueService.scala
@@ -23,18 +23,18 @@ object TrialIssueService {
sealed trait CreateReply
object CreateReply {
type Error = CreateReply with DomainError
- case class Created(x: TrialIssue) extends CreateReply
+ final case class Created(x: TrialIssue) extends CreateReply
case object AuthorizationError
extends CreateReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends CreateReply with DomainError
+ final case class CommonError(userMessage: String) extends CreateReply with DomainError
}
sealed trait GetByIdReply
object GetByIdReply {
type Error = GetByIdReply with DomainError
- case class Entity(x: TrialIssue) extends GetByIdReply
- case object NotFoundError extends GetByIdReply with DomainError.NotFoundError with DefaultNotFoundError
- case class CommonError(userMessage: String) extends GetByIdReply with DomainError
+ final case class Entity(x: TrialIssue) extends GetByIdReply
+ case object NotFoundError extends GetByIdReply with DomainError.NotFoundError with DefaultNotFoundError
+ final case class CommonError(userMessage: String) extends GetByIdReply with DomainError
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
}
@@ -42,7 +42,7 @@ object TrialIssueService {
sealed trait GetListByTrialIdReply
object GetListByTrialIdReply {
type Error = GetListByTrialIdReply with DomainError
- case class EntityList(xs: Seq[TrialIssue], totalFound: Int, lastUpdate: Option[LocalDateTime])
+ final case class EntityList(xs: Seq[TrialIssue], totalFound: Int, lastUpdate: Option[LocalDateTime])
extends GetListByTrialIdReply
case object NotFoundError extends GetListByTrialIdReply with DomainError.NotFoundError with DefaultNotFoundError
case object AuthorizationError
@@ -52,10 +52,10 @@ object TrialIssueService {
sealed trait UpdateReply
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: TrialIssue) extends UpdateReply
+ final case class Updated(updated: TrialIssue) extends UpdateReply
case object AuthorizationError
extends UpdateReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
}
sealed trait DeleteReply
@@ -64,8 +64,8 @@ object TrialIssueService {
case object Deleted extends DeleteReply
case object AuthorizationError
extends DeleteReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case object NotFoundError extends DeleteReply with DomainError.NotFoundError with DefaultNotFoundError
- case class CommonError(userMessage: String) extends DeleteReply with DomainError
+ case object NotFoundError extends DeleteReply with DomainError.NotFoundError with DefaultNotFoundError
+ final case class CommonError(userMessage: String) extends DeleteReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/TrialService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/TrialService.scala
index 47f76f2..3148842 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/TrialService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/TrialService.scala
@@ -24,7 +24,8 @@ object TrialService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[Trial], totalFound: Int, lastUpdate: Option[LocalDateTime]) extends GetListReply
+ final case class EntityList(xs: Seq[Trial], totalFound: Int, lastUpdate: Option[LocalDateTime])
+ extends GetListReply
case object AuthorizationError
extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -32,7 +33,7 @@ object TrialService {
sealed trait GetByIdReply
object GetByIdReply {
- case class Entity(x: Trial) extends GetByIdReply
+ final case class Entity(x: Trial) extends GetByIdReply
type Error = GetByIdReply with DomainError
@@ -41,7 +42,7 @@ object TrialService {
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
+ final case class CommonError(userMessage: String)(implicit requestContext: AuthenticatedRequestContext)
extends GetByIdReply with DomainError
implicit def toPhiString(reply: GetByIdReply): PhiString = reply match {
@@ -54,7 +55,7 @@ object TrialService {
object GetPdfSourceReply {
type Error = GetPdfSourceReply with DomainError
- case class Entity(x: PdfSource) extends GetPdfSourceReply
+ final case class Entity(x: PdfSource) extends GetPdfSourceReply
case object AuthorizationError
extends GetPdfSourceReply with DomainError.AuthorizationError with DefaultAccessDeniedError
@@ -65,21 +66,21 @@ object TrialService {
case object TrialNotFoundError extends GetPdfSourceReply with DomainError.NotFoundError with DefaultNotFoundError
- case class CommonError(userMessage: String) extends GetPdfSourceReply with DomainError
+ final case class CommonError(userMessage: String) extends GetPdfSourceReply with DomainError
}
sealed trait UpdateReply
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: Trial) extends UpdateReply
+ final case class Updated(updated: Trial) extends UpdateReply
case object NotFoundError extends UpdateReply with DefaultNotFoundError with DomainError.NotFoundError
case object AuthorizationError
extends UpdateReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
implicit def toPhiString(reply: UpdateReply): PhiString = reply match {
case Updated(x) => phi"Updated($x)"
@@ -119,5 +120,4 @@ trait TrialService {
def unassign(origTrial: Trial)(implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply]
- def removeTrialDetails(trialId: StringId[Trial]): Unit
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/UserHistoryService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/UserHistoryService.scala
index e342813..a29e041 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/UserHistoryService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/UserHistoryService.scala
@@ -11,7 +11,7 @@ object UserHistoryService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[UserHistory], totalFound: Int) extends GetListReply
+ final case class EntityList(xs: Seq[UserHistory], totalFound: Int) extends GetListReply
case object AuthorizationError extends GetListReply with DomainError.AuthorizationError {
def userMessage: String = "Access denied"
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/UserService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/UserService.scala
index b54b6a9..85b93ed 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/services/UserService.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/UserService.scala
@@ -24,7 +24,7 @@ object UserService {
sealed trait ActivateExecutorReply
object ActivateExecutorReply {
type Error = ActivateExecutorReply with DomainError
- case class Entity(x: User) extends ActivateExecutorReply
+ final case class Entity(x: User) extends ActivateExecutorReply
case object NotFoundError extends ActivateExecutorReply with DomainError.NotFoundError {
val userMessage = "Info about you is not found on the server"
}
@@ -33,16 +33,16 @@ object UserService {
sealed trait GetByIdReply
object GetByIdReply {
type Error = GetByIdReply with DomainError
- case class Entity(x: User) extends GetByIdReply
+ final case class Entity(x: User) extends GetByIdReply
case object AuthorizationError
extends GetByIdReply with DomainError.AuthorizationError with DefaultAccessDeniedError
- case object NotFoundError extends GetByIdReply with DomainError.NotFoundError with DefaultNotFoundError
- case class CommonError(userMessage: String) extends GetByIdReply with DomainError
+ case object NotFoundError extends GetByIdReply with DomainError.NotFoundError with DefaultNotFoundError
+ final case class CommonError(userMessage: String) extends GetByIdReply with DomainError
}
sealed trait GetByEmailReply
object GetByEmailReply {
- case class Entity(x: User) extends GetByEmailReply
+ final case class Entity(x: User) extends GetByEmailReply
case object NotFoundError extends GetByEmailReply with DefaultNotFoundError with DomainError.NotFoundError {
override def userMessage: String = "Incorrect email. Try again."
}
@@ -50,7 +50,7 @@ object UserService {
sealed trait GetByCredentialsReply
object GetByCredentialsReply {
- case class Entity(x: User) extends GetByCredentialsReply
+ final case class Entity(x: User) extends GetByCredentialsReply
case object AuthenticationError
extends GetByCredentialsReply with DefaultCredentialsError with DomainError.AuthenticationError
case object NotFoundError extends GetByCredentialsReply with DomainError.NotFoundError with DefaultNotFoundError
@@ -58,41 +58,41 @@ object UserService {
sealed trait GetListReply
object GetListReply {
- case class EntityList(xs: Seq[User], totalFound: Int) extends GetListReply
- case object AuthorizationError extends GetListReply with DomainError.AuthorizationError with DefaultNotFoundError
+ final case class EntityList(xs: Seq[User], totalFound: Int) extends GetListReply
+ case object AuthorizationError extends GetListReply with DomainError.AuthorizationError with DefaultNotFoundError
}
sealed trait CreateReply
object CreateReply {
type Error = CreateReply with DomainError
- case class Created(x: User) extends CreateReply
- case object AuthorizationError extends CreateReply with DefaultNotFoundError with DomainError.AuthorizationError
- case class UserAlreadyExistsError(email: Email) extends CreateReply with DomainError {
+ final case class Created(x: User) extends CreateReply
+ case object AuthorizationError extends CreateReply with DefaultNotFoundError with DomainError.AuthorizationError
+ final case class UserAlreadyExistsError(email: Email) extends CreateReply with DomainError {
val userMessage = s"The user with this email already exists."
}
- case class CommonError(userMessage: String) extends CreateReply with DomainError
+ final case class CommonError(userMessage: String) extends CreateReply with DomainError
}
sealed trait UpdateReply
object UpdateReply {
type Error = UpdateReply with DomainError
- case class Updated(updated: User) extends UpdateReply
+ final case class Updated(updated: User) extends UpdateReply
case object AuthorizationError
extends UpdateReply with DefaultAccessDeniedError with DomainError.AuthorizationError
- case class CommonError(userMessage: String) extends UpdateReply with DomainError
+ final case class CommonError(userMessage: String) extends UpdateReply with DomainError
}
sealed trait DeleteReply
object DeleteReply {
type Error = DeleteReply with DomainError
case object Deleted extends DeleteReply
- case class AuthorizationError(user: User)
+ final case class AuthorizationError(user: User)
extends DeleteReply with DefaultAccessDeniedError with DomainError.AuthorizationError
case object AssignedToRecordAndDocumentError extends DeleteReply with DomainError {
val userMessage = "User is can not be deleted because he has record and document in work"
}
- case object NotFoundError extends DeleteReply with DefaultNotFoundError with DomainError.NotFoundError
- case class CommonError(userMessage: String) extends DeleteReply with DomainError
+ case object NotFoundError extends DeleteReply with DefaultNotFoundError with DomainError.NotFoundError
+ final case class CommonError(userMessage: String) extends DeleteReply with DomainError
}
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestArmService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestArmService.scala
new file mode 100644
index 0000000..299e6f8
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestArmService.scala
@@ -0,0 +1,99 @@
+package xyz.driver.pdsuidomain.services.rest
+
+import akka.http.scaladsl.marshalling.Marshal
+import scala.concurrent.{ExecutionContext, Future}
+
+import akka.http.scaladsl.model._
+import akka.stream.ActorMaterializer
+import xyz.driver.core.rest._
+import xyz.driver.pdsuicommon.auth._
+import xyz.driver.pdsuicommon.db._
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuidomain.entities._
+import xyz.driver.pdsuidomain.formats.json.ListResponse
+import xyz.driver.pdsuidomain.formats.json.arm.ApiArm
+import xyz.driver.pdsuidomain.services.ArmService
+
+class RestArmService(transport: ServiceTransport, baseUri: Uri)(implicit protected val materializer: ActorMaterializer,
+ protected val exec: ExecutionContext)
+ extends ArmService with RestHelper {
+
+ import xyz.driver.pdsuidomain.services.ArmService._
+ import xyz.driver.pdsuicommon.serialization.PlayJsonSupport._
+
+ // GET /v1/arm xyz.driver.server.controllers.ArmController.getList
+ // GET /v1/arm/:id xyz.driver.server.controllers.ArmController.getById(id: Long)
+ // POST /v1/arm xyz.driver.server.controllers.ArmController.create
+ // PATCH /v1/arm/:id xyz.driver.server.controllers.ArmController.update(id: Long)
+ // DELETE /v1/arm/:id xyz.driver.server.controllers.ArmController.delete(id: Long)
+
+ def getAll(filter: SearchFilterExpr = SearchFilterExpr.Empty,
+ sorting: Option[Sorting] = None,
+ pagination: Option[Pagination] = None)(
+ implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] = {
+
+ val request = HttpRequest(
+ HttpMethods.GET,
+ endpointUri(baseUri, "/v1/arm", filterQuery(filter) ++ sortingQuery(sorting) ++ paginationQuery(pagination)))
+
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ListResponse[ApiArm], GetListReply](response) { api =>
+ GetListReply.EntityList(api.items.map(_.toDomain), api.meta.itemsCount)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def getById(armId: LongId[Arm])(implicit requestContext: AuthenticatedRequestContext): Future[GetByIdReply] = {
+ val request = HttpRequest(HttpMethods.GET, endpointUri(baseUri, s"/v1/arm/$armId"))
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiArm, GetByIdReply](response) { api =>
+ GetByIdReply.Entity(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def create(draftArm: Arm)(implicit requestContext: AuthenticatedRequestContext): Future[CreateReply] = {
+ for {
+ entity <- Marshal(ApiArm.fromDomain(draftArm)).to[RequestEntity]
+ request = HttpRequest(HttpMethods.POST, endpointUri(baseUri, "/v1/arm")).withEntity(entity)
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiArm, CreateReply](response) { api =>
+ CreateReply.Created(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def update(origArm: Arm, draftArm: Arm)(implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] = {
+ val id = origArm.id
+ val request = HttpRequest(HttpMethods.PATCH, endpointUri(baseUri, s"/v1/arm/$id"))
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiArm, UpdateReply](response) { api =>
+ UpdateReply.Updated(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def delete(id: LongId[Arm])(implicit requestContext: AuthenticatedRequestContext): Future[DeleteReply] = {
+ val request = HttpRequest(HttpMethods.DELETE, endpointUri(baseUri, s"/v1/arm/$id"))
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiArm, DeleteReply](response) { _ =>
+ DeleteReply.Deleted
+ }()
+ } yield {
+ reply
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestCriterionService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestCriterionService.scala
new file mode 100644
index 0000000..b27ce3d
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestCriterionService.scala
@@ -0,0 +1,108 @@
+package xyz.driver.pdsuidomain.services.rest
+
+import scala.concurrent.{ExecutionContext, Future}
+
+import akka.http.scaladsl.marshalling.Marshal
+import akka.http.scaladsl.model._
+import akka.stream.ActorMaterializer
+import xyz.driver.core.rest._
+import xyz.driver.pdsuicommon.auth._
+import xyz.driver.pdsuicommon.db._
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuidomain.entities._
+import xyz.driver.pdsuidomain.formats.json.ListResponse
+import xyz.driver.pdsuidomain.services.CriterionService
+
+class RestCriterionService(transport: ServiceTransport, baseUri: Uri)(
+ implicit protected val materializer: ActorMaterializer,
+ protected val exec: ExecutionContext)
+ extends CriterionService with RestHelper {
+
+ import xyz.driver.pdsuicommon.serialization.PlayJsonSupport._
+ import xyz.driver.pdsuidomain.formats.json.criterion.ApiCriterion
+ import xyz.driver.pdsuidomain.services.CriterionService._
+
+ // GET /v1/criterion xyz.driver.server.controllers.CriterionController.getList
+ // GET /v1/criterion/:id xyz.driver.server.controllers.CriterionController.getById(id: Long)
+ // PATCH /v1/criterion/:id xyz.driver.server.controllers.CriterionController.update(id: Long)
+ // POST /v1/criterion xyz.driver.server.controllers.CriterionController.create
+ // DELETE /v1/criterion/:id xyz.driver.server.controllers.CriterionController.delete(id: Long)
+
+ def create(draftRichCriterion: RichCriterion)(
+ implicit requestContext: AuthenticatedRequestContext): Future[CreateReply] = {
+ for {
+ entity <- Marshal(ApiCriterion.fromDomain(draftRichCriterion)).to[RequestEntity]
+ request = HttpRequest(HttpMethods.POST, endpointUri(baseUri, "/v1/criterion")).withEntity(entity)
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiCriterion, CreateReply](response) { api =>
+ CreateReply.Created(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def getById(id: LongId[Criterion])(implicit requestContext: AuthenticatedRequestContext): Future[GetByIdReply] = {
+ val request = HttpRequest(HttpMethods.GET, endpointUri(baseUri, s"/v1/criterion/$id"))
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiCriterion, GetByIdReply](response) { api =>
+ GetByIdReply.Entity(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def getAll(filter: SearchFilterExpr = SearchFilterExpr.Empty,
+ sorting: Option[Sorting] = None,
+ pagination: Option[Pagination] = None)(
+ implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] = {
+
+ val request = HttpRequest(HttpMethods.GET,
+ endpointUri(baseUri,
+ s"/v1/criterion",
+ filterQuery(filter) ++ sortingQuery(sorting) ++ paginationQuery(pagination)))
+
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ListResponse[ApiCriterion], GetListReply](response) { api =>
+ GetListReply.EntityList(
+ api.items.map(_.toDomain),
+ api.meta.itemsCount,
+ api.meta.lastUpdate
+ )
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def update(origRichCriterion: RichCriterion, draftRichCriterion: RichCriterion)(
+ implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] = {
+ val id = origRichCriterion.criterion.id
+ for {
+ entity <- Marshal(ApiCriterion.fromDomain(draftRichCriterion)).to[RequestEntity]
+ request = HttpRequest(HttpMethods.PATCH, endpointUri(baseUri, s"/v1/criterion/$id")).withEntity(entity)
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiCriterion, UpdateReply](response) { api =>
+ UpdateReply.Updated(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def delete(id: LongId[Criterion])(implicit requestContext: AuthenticatedRequestContext): Future[DeleteReply] = {
+ val request = HttpRequest(HttpMethods.DELETE, endpointUri(baseUri, s"/v1/criterion/$id"))
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiCriterion, DeleteReply](response) { _ =>
+ DeleteReply.Deleted
+ }()
+ } yield {
+ reply
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestHelper.scala b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestHelper.scala
new file mode 100644
index 0000000..7d2838b
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestHelper.scala
@@ -0,0 +1,139 @@
+package xyz.driver.pdsuidomain.services.rest
+
+import java.lang.RuntimeException
+
+import scala.concurrent.{ExecutionContext, Future}
+
+import akka.http.scaladsl.model.{HttpMethods, HttpRequest, HttpResponse, ResponseEntity, StatusCode, StatusCodes, Uri}
+import akka.http.scaladsl.unmarshalling.{Unmarshal, Unmarshaller}
+import akka.stream.Materializer
+import xyz.driver.core.rest.ServiceRequestContext
+import xyz.driver.pdsuicommon.auth.{AnonymousRequestContext, AuthenticatedRequestContext}
+import xyz.driver.pdsuicommon.db.{
+ Pagination,
+ SearchFilterBinaryOperation,
+ SearchFilterExpr,
+ SearchFilterNAryOperation,
+ Sorting,
+ SortingOrder
+}
+import xyz.driver.pdsuicommon.error.DomainError
+
+trait RestHelper {
+
+ implicit protected val materializer: Materializer
+ implicit protected val exec: ExecutionContext
+
+ protected def endpointUri(baseUri: Uri, path: String) =
+ baseUri.withPath(Uri.Path(path))
+
+ protected def endpointUri(baseUri: Uri, path: String, query: Seq[(String, String)]) =
+ baseUri.withPath(Uri.Path(path)).withQuery(Uri.Query(query: _*))
+
+ def get(baseUri: Uri, path: String, query: Seq[(String, String)] = Seq.empty): HttpRequest =
+ HttpRequest(HttpMethods.GET, endpointUri(baseUri, path, query))
+
+ def sortingQuery(sorting: Option[Sorting]): Seq[(String, String)] = {
+ def dimensionQuery(dimension: Sorting.Dimension) = {
+ val ord = dimension.order match {
+ case SortingOrder.Ascending => ""
+ case SortingOrder.Descending => "-"
+ }
+ s"$ord${dimension.name}"
+ }
+
+ sorting match {
+ case None => Seq.empty
+ case Some(dimension: Sorting.Dimension) => Seq("sort" -> dimensionQuery(dimension))
+ case Some(Sorting.Sequential(dimensions)) => Seq("sort" -> dimensions.map(dimensionQuery).mkString(","))
+ }
+ }
+
+ def filterQuery(expr: SearchFilterExpr): Seq[(String, String)] = {
+ def opToString(op: SearchFilterBinaryOperation) = op match {
+ case SearchFilterBinaryOperation.Eq => "eq"
+ case SearchFilterBinaryOperation.NotEq => "ne"
+ case SearchFilterBinaryOperation.Like => "like"
+ case SearchFilterBinaryOperation.Gt => "gt"
+ case SearchFilterBinaryOperation.GtEq => "ge"
+ case SearchFilterBinaryOperation.Lt => "lt"
+ case SearchFilterBinaryOperation.LtEq => "le"
+ }
+
+ def exprToQuery(expr: SearchFilterExpr): Seq[(String, String)] = expr match {
+ case SearchFilterExpr.Empty => Seq.empty
+ case SearchFilterExpr.Atom.Binary(dimension, op, value) =>
+ Seq("filters" -> s"${dimension.name} ${opToString(op)} $value")
+ case SearchFilterExpr.Atom.NAry(dimension, SearchFilterNAryOperation.In, values) =>
+ Seq("filters" -> s"${dimension.name} in ${values.mkString(",")}")
+ case SearchFilterExpr.Intersection(ops) =>
+ ops.flatMap(op => exprToQuery(op))
+ case expr => sys.error(s"No parser available for filter expression $expr.")
+ }
+
+ exprToQuery(expr)
+ }
+
+ def paginationQuery(pagination: Option[Pagination]): Seq[(String, String)] = pagination match {
+ case None => Seq.empty
+ case Some(pp) =>
+ Seq(
+ "pageNumber" -> pp.pageNumber.toString,
+ "pageSize" -> pp.pageSize.toHexString
+ )
+ }
+
+ /** Utility method to parse responses that encode success and errors as subtypes
+ * of a common reply type.
+ *
+ * @tparam ApiReply The type of the serialized reply object, contained in the HTTP entity
+ * @tparam DomainReply The type of the domain object that will be created from a successful reply.
+ *
+ * @param response The HTTP response to parse.
+ * @param successMapper Transformation function from a deserialized api entity to a domain object.
+ * @param errorMapper Transformation function from general domain errors to
+ * specialized errors of the given DomainReply. Note that if a domain error
+ * is not explicitly handled, it will be encoded as a failure in the returned future.
+ * @param unmarshaller An unmarshaller that converts a successful response to an api reply.
+ */
+ def apiResponse[ApiReply, DomainReply](response: HttpResponse)(successMapper: ApiReply => DomainReply)(
+ errorMapper: PartialFunction[DomainError, DomainReply] = PartialFunction.empty)(
+ implicit unmarshaller: Unmarshaller[ResponseEntity, ApiReply]): Future[DomainReply] = {
+
+ val domainErrors: Map[StatusCode, DomainError] = Map(
+ StatusCodes.Unauthorized -> new DomainError.AuthenticationError {
+ override protected def userMessage: String = "unauthorized"
+ }, // 401
+ StatusCodes.Forbidden -> new DomainError.AuthorizationError {
+ override protected def userMessage: String = "forbidden"
+ }, // 403
+ StatusCodes.NotFound -> new DomainError.NotFoundError {
+ override protected def userMessage: String = "not found"
+ } // 404
+ )
+
+ if (response.status.isSuccess) {
+ val reply = Unmarshal(response.entity).to[ApiReply]
+ reply.map(successMapper)
+ } else {
+ val domainError = domainErrors.get(response.status)
+ domainError.flatMap(errorMapper.lift) match {
+ case Some(error) => Future.successful(error)
+ case None =>
+ Future.failed(
+ new RuntimeException(
+ s"Unhandled domain error for HTTP status ${response.status}. Message ${response.entity}")
+ )
+ }
+ }
+ }
+
+ implicit def toServiceRequestContext(requestContext: AnonymousRequestContext): ServiceRequestContext = {
+ val auth: Map[String, String] = requestContext match {
+ case ctx: AuthenticatedRequestContext => Map("Auth-token" -> ctx.authToken)
+ case _ => Map()
+ }
+ new ServiceRequestContext(contextHeaders = auth)
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestHypothesisService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestHypothesisService.scala
new file mode 100644
index 0000000..ff9d490
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestHypothesisService.scala
@@ -0,0 +1,39 @@
+package xyz.driver.pdsuidomain.services.rest
+
+import scala.concurrent.{ExecutionContext, Future}
+
+import akka.http.scaladsl.model._
+import akka.stream.ActorMaterializer
+import xyz.driver.core.rest._
+import xyz.driver.pdsuicommon.auth._
+import xyz.driver.pdsuicommon.db._
+import xyz.driver.pdsuidomain.formats.json.ListResponse
+import xyz.driver.pdsuidomain.formats.json.hypothesis.ApiHypothesis
+import xyz.driver.pdsuidomain.services.HypothesisService
+
+class RestHypothesisService(transport: ServiceTransport, baseUri: Uri)(
+ implicit protected val materializer: ActorMaterializer,
+ protected val exec: ExecutionContext)
+ extends HypothesisService with RestHelper {
+
+ import xyz.driver.pdsuicommon.serialization.PlayJsonSupport._
+ import xyz.driver.pdsuidomain.services.HypothesisService._
+
+ // GET /v1/hypothesis xyz.driver.server.controllers.HypothesisController.getList
+
+ def getAll(sorting: Option[Sorting] = None)(
+ implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] = {
+
+ val request = HttpRequest(HttpMethods.GET, endpointUri(baseUri, "/v1/hypothesis", sortingQuery(sorting)))
+
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ListResponse[ApiHypothesis], GetListReply](response) { api =>
+ GetListReply.EntityList(api.items.map(_.toDomain), api.meta.itemsCount)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestInterventionService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestInterventionService.scala
new file mode 100644
index 0000000..810a9d6
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestInterventionService.scala
@@ -0,0 +1,78 @@
+package xyz.driver.pdsuidomain.services.rest
+
+import akka.http.scaladsl.marshalling.Marshal
+import scala.concurrent.{ExecutionContext, Future}
+
+import akka.http.scaladsl.model._
+import akka.stream.ActorMaterializer
+import xyz.driver.core.rest._
+import xyz.driver.pdsuicommon.auth._
+import xyz.driver.pdsuicommon.db._
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuidomain.entities._
+import xyz.driver.pdsuidomain.formats.json.ListResponse
+import xyz.driver.pdsuidomain.formats.json.intervention.ApiIntervention
+import xyz.driver.pdsuidomain.services.InterventionService
+
+class RestInterventionService(transport: ServiceTransport, baseUri: Uri)(
+ implicit protected val materializer: ActorMaterializer,
+ protected val exec: ExecutionContext)
+ extends InterventionService with RestHelper {
+
+ import xyz.driver.pdsuidomain.services.InterventionService._
+ import xyz.driver.pdsuicommon.serialization.PlayJsonSupport._
+
+ // GET /v1/intervention xyz.driver.server.controllers.InterventionController.getList
+ // GET /v1/intervention/:id xyz.driver.server.controllers.InterventionController.getById(id: Long)
+ // PATCH /v1/intervention/:id xyz.driver.server.controllers.InterventionController.update(id: Long)
+
+ def getAll(filter: SearchFilterExpr = SearchFilterExpr.Empty,
+ sorting: Option[Sorting] = None,
+ pagination: Option[Pagination] = None)(
+ implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] = {
+
+ val request = HttpRequest(HttpMethods.GET,
+ endpointUri(baseUri,
+ "/v1/intervention",
+ filterQuery(filter) ++ sortingQuery(sorting) ++ paginationQuery(pagination)))
+
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ListResponse[ApiIntervention], GetListReply](response) { api =>
+ GetListReply.EntityList(api.items.map(_.toDomain), api.meta.itemsCount)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def getById(id: LongId[Intervention])(implicit requestContext: AuthenticatedRequestContext): Future[GetByIdReply] = {
+ val request = HttpRequest(HttpMethods.GET, endpointUri(baseUri, s"/v1/intervention/$id"))
+
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiIntervention, GetByIdReply](response) { api =>
+ GetByIdReply.Entity(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def update(origIntervention: InterventionWithArms, draftIntervention: InterventionWithArms)(
+ implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] = {
+ val id = origIntervention.intervention.id
+
+ for {
+ entity <- Marshal(ApiIntervention.fromDomain(draftIntervention)).to[RequestEntity]
+ request = HttpRequest(HttpMethods.PATCH, endpointUri(baseUri, s"/v1/intervention/$id")).withEntity(entity)
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiIntervention, UpdateReply](response) { api =>
+ UpdateReply.Updated(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestInterventionTypeService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestInterventionTypeService.scala
new file mode 100644
index 0000000..1243500
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestInterventionTypeService.scala
@@ -0,0 +1,40 @@
+package xyz.driver.pdsuidomain.services.rest
+
+import scala.concurrent.{ExecutionContext, Future}
+
+import akka.http.scaladsl.model._
+import akka.stream.ActorMaterializer
+import xyz.driver.core.rest._
+import xyz.driver.pdsuicommon.auth._
+import xyz.driver.pdsuicommon.db._
+import xyz.driver.pdsuicommon.error.DomainError
+import xyz.driver.pdsuidomain.formats.json.intervention.ApiInterventionType
+import xyz.driver.pdsuidomain.services.InterventionTypeService
+
+class RestInterventionTypeService(transport: ServiceTransport, baseUri: Uri)(
+ implicit protected val materializer: ActorMaterializer,
+ protected val exec: ExecutionContext)
+ extends InterventionTypeService with RestHelper {
+
+ import xyz.driver.pdsuicommon.serialization.PlayJsonSupport._
+ import xyz.driver.pdsuidomain.formats.json.ListResponse
+ import xyz.driver.pdsuidomain.services.InterventionTypeService._
+
+ def getAll(sorting: Option[Sorting] = None)(
+ implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] = {
+
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(
+ get(baseUri, "/v1/intervention-type", query = sortingQuery(sorting)))
+ reply <- apiResponse[ListResponse[ApiInterventionType], GetListReply](response) { list =>
+ val domain = list.items.map(_.toDomain)
+ GetListReply.EntityList(domain.toList, list.meta.itemsCount)
+ } {
+ case _: DomainError.AuthorizationError => GetListReply.AuthorizationError
+ }
+ } yield {
+ reply
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestMessageService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestMessageService.scala
new file mode 100644
index 0000000..61d2050
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestMessageService.scala
@@ -0,0 +1,103 @@
+package xyz.driver.pdsuidomain.services.rest
+
+import akka.http.scaladsl.marshalling.Marshal
+import scala.concurrent.{ExecutionContext, Future}
+
+import akka.http.scaladsl.model._
+import akka.stream.ActorMaterializer
+import xyz.driver.core.rest._
+import xyz.driver.pdsuicommon.auth._
+import xyz.driver.pdsuicommon.db._
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuidomain.entities._
+import xyz.driver.pdsuidomain.formats.json.ListResponse
+import xyz.driver.pdsuidomain.formats.json.message.ApiMessage
+import xyz.driver.pdsuidomain.services.MessageService
+
+class RestMessageService(transport: ServiceTransport, baseUri: Uri)(
+ implicit protected val materializer: ActorMaterializer,
+ protected val exec: ExecutionContext)
+ extends MessageService with RestHelper {
+
+ import xyz.driver.pdsuicommon.serialization.PlayJsonSupport._
+ import xyz.driver.pdsuidomain.services.MessageService._
+
+ // GET /v1/message xyz.driver.server.controllers.MessageController.getList
+ // POST /v1/message xyz.driver.server.controllers.MessageController.create
+ // PATCH /v1/message/:id xyz.driver.server.controllers.MessageController.update(id: Long)
+ // DELETE /v1/message/:id xyz.driver.server.controllers.MessageController.delete(id: Long)
+
+ def create(draftMessage: Message)(implicit requestContext: AuthenticatedRequestContext): Future[CreateReply] = {
+ for {
+ entity <- Marshal(ApiMessage.fromDomain(draftMessage)).to[RequestEntity]
+ request = HttpRequest(HttpMethods.POST, endpointUri(baseUri, "/v1/message")).withEntity(entity)
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiMessage, CreateReply](response) { api =>
+ CreateReply.Created(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def getById(messageId: LongId[Message])(implicit requestContext: AuthenticatedRequestContext): Future[GetByIdReply] = {
+ import SearchFilterExpr._
+ import SearchFilterBinaryOperation._
+ val filter = Atom.Binary("id", Eq, messageId)
+ getAll(filter).map {
+ case GetListReply.EntityList(messages, _, _) if messages.isEmpty =>
+ GetByIdReply.NotFoundError
+ case GetListReply.EntityList(messages, _, _) =>
+ GetByIdReply.Entity(messages.head)
+ case GetListReply.AuthorizationError =>
+ GetByIdReply.AuthorizationError
+ }
+ }
+ def getAll(filter: SearchFilterExpr = SearchFilterExpr.Empty,
+ sorting: Option[Sorting] = None,
+ pagination: Option[Pagination] = None)(
+ implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] = {
+
+ val request = HttpRequest(
+ HttpMethods.GET,
+ endpointUri(baseUri, "/v1/message", filterQuery(filter) ++ sortingQuery(sorting) ++ paginationQuery(pagination)))
+
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ListResponse[ApiMessage], GetListReply](response) { api =>
+ GetListReply.EntityList(api.items.map(_.toDomain), api.meta.itemsCount, api.meta.lastUpdate)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def update(origMessage: Message, draftMessage: Message)(
+ implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] = {
+ for {
+ entity <- Marshal(ApiMessage.fromDomain(draftMessage)).to[RequestEntity]
+ id = origMessage.id.id
+ request = HttpRequest(HttpMethods.PATCH, endpointUri(baseUri, s"/v1/message/$id")).withEntity(entity)
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiMessage, UpdateReply](response) { api =>
+ UpdateReply.Updated(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def delete(messageId: LongId[Message])(implicit requestContext: AuthenticatedRequestContext): Future[DeleteReply] = {
+ val request = HttpRequest(HttpMethods.GET, endpointUri(baseUri, s"/v1/message/${messageId.id}"))
+
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiMessage, DeleteReply](response) { _ =>
+ DeleteReply.Deleted
+ }()
+ } yield {
+ reply
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestStudyDesignService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestStudyDesignService.scala
new file mode 100644
index 0000000..66f7a78
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestStudyDesignService.scala
@@ -0,0 +1,37 @@
+package xyz.driver.pdsuidomain.services.rest
+
+import scala.concurrent.{ExecutionContext, Future}
+
+import akka.http.scaladsl.model._
+import akka.stream.ActorMaterializer
+import xyz.driver.core.rest._
+import xyz.driver.pdsuicommon.auth._
+import xyz.driver.pdsuicommon.db._
+import xyz.driver.pdsuidomain.formats.json.ListResponse
+import xyz.driver.pdsuidomain.formats.json.studydesign.ApiStudyDesign
+import xyz.driver.pdsuidomain.services.StudyDesignService
+
+class RestStudyDesignService(transport: ServiceTransport, baseUri: Uri)(
+ implicit protected val materializer: ActorMaterializer,
+ protected val exec: ExecutionContext)
+ extends StudyDesignService with RestHelper {
+
+ import xyz.driver.pdsuicommon.serialization.PlayJsonSupport._
+ import xyz.driver.pdsuidomain.services.StudyDesignService._
+
+ // GET /v1/study-design xyz.driver.server.controllers.StudyDesignController.getList
+
+ def getAll(sorting: Option[Sorting] = None)(
+ implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] = {
+ val request = HttpRequest(HttpMethods.GET, endpointUri(baseUri, "/v1/study-design", sortingQuery(sorting)))
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ListResponse[ApiStudyDesign], GetListReply](response) { api =>
+ GetListReply.EntityList(api.items.map(_.toDomain), api.meta.itemsCount)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestTrialService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestTrialService.scala
new file mode 100644
index 0000000..9b4b576
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/services/rest/RestTrialService.scala
@@ -0,0 +1,117 @@
+package xyz.driver.pdsuidomain.services.rest
+
+import akka.http.scaladsl.marshalling.Marshal
+import scala.NotImplementedError
+import scala.concurrent.{ExecutionContext, Future}
+
+import akka.http.scaladsl.model._
+import akka.stream.ActorMaterializer
+import xyz.driver.core.rest._
+import xyz.driver.pdsuicommon.auth._
+import xyz.driver.pdsuicommon.db._
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuidomain.entities._
+import xyz.driver.pdsuidomain.formats.json.trial.ApiTrial
+import xyz.driver.pdsuidomain.services.TrialService
+import xyz.driver.pdsuidomain.formats.json.ListResponse
+
+class RestTrialService(transport: ServiceTransport, baseUri: Uri)(
+ implicit protected val materializer: ActorMaterializer,
+ protected val exec: ExecutionContext)
+ extends TrialService with RestHelper {
+
+ import xyz.driver.pdsuicommon.serialization.PlayJsonSupport._
+ import xyz.driver.pdsuidomain.services.TrialService._
+
+ // GET /v1/trial xyz.driver.server.controllers.TrialController.getList
+ // GET /v1/trial/:id xyz.driver.server.controllers.TrialController.getById(id: String)
+ // GET /v1/trial/:id/source xyz.driver.server.controllers.TrialController.getSource(id: String)
+ // PATCH /v1/trial/:id xyz.driver.server.controllers.TrialController.update(id: String)
+ // POST /v1/trial/:id/start xyz.driver.server.controllers.TrialController.start(id: String)
+ // POST /v1/trial/:id/submit xyz.driver.server.controllers.TrialController.submit(id: String)
+ // POST /v1/trial/:id/restart xyz.driver.server.controllers.TrialController.restart(id: String)
+ // POST /v1/trial/:id/flag xyz.driver.server.controllers.TrialController.flag(id: String)
+ // POST /v1/trial/:id/resolve xyz.driver.server.controllers.TrialController.resolve(id: String)
+ // POST /v1/trial/:id/archive xyz.driver.server.controllers.TrialController.archive(id: String)
+ // POST /v1/trial/:id/unassign xyz.driver.server.controllers.TrialController.unassign(id: String)
+
+ def getById(id: StringId[Trial])(implicit requestContext: AuthenticatedRequestContext): Future[GetByIdReply] = {
+ val request = HttpRequest(HttpMethods.GET, endpointUri(baseUri, s"/v1/trial/$id"))
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiTrial, GetByIdReply](response) { api =>
+ GetByIdReply.Entity(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def getPdfSource(trialId: StringId[Trial])(
+ implicit requestContext: AuthenticatedRequestContext): Future[GetPdfSourceReply] = Future.failed(
+ new NotImplementedError("Streaming PDF over network is not supported.")
+ )
+
+ def getAll(filter: SearchFilterExpr = SearchFilterExpr.Empty,
+ sorting: Option[Sorting] = None,
+ pagination: Option[Pagination] = None)(
+ implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] = {
+
+ val request = HttpRequest(
+ HttpMethods.GET,
+ endpointUri(baseUri, "/v1/trial", filterQuery(filter) ++ sortingQuery(sorting) ++ paginationQuery(pagination)))
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ListResponse[ApiTrial], GetListReply](response) { api =>
+ GetListReply.EntityList(api.items.map(_.toDomain), api.meta.itemsCount, api.meta.lastUpdate)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def update(origTrial: Trial, draftTrial: Trial)(
+ implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] = {
+ val id = origTrial.id.id
+ for {
+ entity <- Marshal(ApiTrial.fromDomain(draftTrial)).to[RequestEntity]
+ request = HttpRequest(HttpMethods.PATCH, endpointUri(baseUri, s"/v1/trial/$id")).withEntity(entity)
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiTrial, UpdateReply](response) { api =>
+ UpdateReply.Updated(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ private def singleAction(origTrial: Trial, action: String)(
+ implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] = {
+ val id = origTrial.id.id
+ val request = HttpRequest(HttpMethods.GET, endpointUri(baseUri, s"/v1/trial/$id/$action"))
+ for {
+ response <- transport.sendRequestGetResponse(requestContext)(request)
+ reply <- apiResponse[ApiTrial, UpdateReply](response) { api =>
+ UpdateReply.Updated(api.toDomain)
+ }()
+ } yield {
+ reply
+ }
+ }
+
+ def start(origTrial: Trial)(implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] =
+ singleAction(origTrial, "start")
+ def submit(origTrial: Trial)(implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] =
+ singleAction(origTrial, "submit")
+ def restart(origTrial: Trial)(implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] =
+ singleAction(origTrial, "restart")
+ def flag(origTrial: Trial)(implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] =
+ singleAction(origTrial, "flag")
+ def resolve(origTrial: Trial)(implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] =
+ singleAction(origTrial, "resolve")
+ def archive(origTrial: Trial)(implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] =
+ singleAction(origTrial, "archive")
+ def unassign(origTrial: Trial)(implicit requestContext: AuthenticatedRequestContext): Future[UpdateReply] =
+ singleAction(origTrial, "unassign")
+
+}