From 6bb9a40ea51449f9239f459bfd98b94b685a99df Mon Sep 17 00:00:00 2001 From: Vyatcheslav Suharnikov Date: Tue, 4 Jul 2017 15:21:48 +0300 Subject: PDSUI-2026 Create Trial Curation's own user history table for trials --- .../scala/xyz/driver/pdsuicommon/acl/ACL.scala | 8 +- .../driver/pdsuidomain/entities/TrialHistory.scala | 93 ++++++++++++++++++++++ .../json/trialhistory/ApiTrialHistory.scala | 26 ++++++ .../pdsuidomain/services/TrialHistoryService.scala | 49 ++++++++++++ 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/main/scala/xyz/driver/pdsuidomain/entities/TrialHistory.scala create mode 100644 src/main/scala/xyz/driver/pdsuidomain/formats/json/trialhistory/ApiTrialHistory.scala create mode 100644 src/main/scala/xyz/driver/pdsuidomain/services/TrialHistoryService.scala (limited to 'src/main') diff --git a/src/main/scala/xyz/driver/pdsuicommon/acl/ACL.scala b/src/main/scala/xyz/driver/pdsuicommon/acl/ACL.scala index 1bb5bcd..2a504fb 100644 --- a/src/main/scala/xyz/driver/pdsuicommon/acl/ACL.scala +++ b/src/main/scala/xyz/driver/pdsuicommon/acl/ACL.scala @@ -37,7 +37,7 @@ object ACL extends PhiLogging { object UserHistory extends BaseACL( label = "user history", - read = Set(RecordAdmin, TrialAdmin, TreatmentMatchingAdmin) + read = Set(RecordAdmin, TreatmentMatchingAdmin) ) object Queue @@ -111,6 +111,12 @@ object ACL extends PhiLogging { update = TcRoles ) + object TrialHistory + extends BaseACL( + label = "trial history", + read = Set(TrialAdmin) + ) + object StudyDesign extends BaseACL( label = "study design", diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/TrialHistory.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/TrialHistory.scala new file mode 100644 index 0000000..829a351 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/TrialHistory.scala @@ -0,0 +1,93 @@ +package xyz.driver.pdsuidomain.entities + +import java.time.{LocalDateTime, ZoneId} + +import xyz.driver.pdsuicommon.domain._ +import xyz.driver.pdsuicommon.logging._ +import xyz.driver.pdsuicommon.utils.Utils +import TrialHistory._ + +object TrialHistory { + + implicit def toPhiString(x: TrialHistory): PhiString = { + import x._ + phi"TrialHistory(id=$id, executor=$executor, trialId=$trialId, state=$state, action=$action, created=$created)" + } + + sealed trait State + object State { + case object Summarize extends State + case object Criteriarize extends State + case object Review extends State + case object Flag extends State + + val All: Set[State] = Set[State](Summarize, Criteriarize, Review, Flag) + + val fromString: PartialFunction[String, State] = { + case "Summarize" => State.Summarize + case "Criteriarize" => State.Criteriarize + case "Review" => State.Review + case "Flag" => State.Flag + } + + def stateToString(x: State): String = x match { + case State.Summarize => "Summarize" + case State.Criteriarize => "Criteriarize" + case State.Review => "Review" + case State.Flag => "Flag" + } + + implicit def toPhiString(x: State): PhiString = + Unsafe(Utils.getClassSimpleName(x.getClass)) + } + + sealed trait Action extends Product with Serializable { + + def oneOf(xs: Action*): Boolean = xs.contains(this) + + def oneOf(xs: Set[Action]): Boolean = xs.contains(this) + + } + + object Action { + case object Start extends Action + case object Submit extends Action + case object Unassign extends Action + case object Resolve extends Action + case object Flag extends Action + case object Archive extends Action + + val All: Set[Action] = + Set[Action](Start, Submit, Unassign, Resolve, Flag, Archive) + + val fromString: PartialFunction[String, Action] = { + case "Start" => Action.Start + case "Submit" => Action.Submit + case "Unassign" => Action.Unassign + case "Resolve" => Action.Resolve + case "Flag" => Action.Flag + case "Archive" => Action.Archive + } + + def actionToString(x: Action): String = x match { + case Action.Start => "Start" + case Action.Submit => "Submit" + case Action.Unassign => "Unassign" + case Action.Resolve => "Resolve" + case Action.Flag => "Flag" + case Action.Archive => "Archive" + } + + implicit def toPhiString(x: Action): PhiString = + Unsafe(Utils.getClassSimpleName(x.getClass)) + } + +} + +final case class TrialHistory(id: LongId[TrialHistory], + executor: LongId[User], + trialId: StringId[Trial], + state: State, + action: Action, + created: LocalDateTime = + LocalDateTime.now(ZoneId.of("Z"))) diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/trialhistory/ApiTrialHistory.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/trialhistory/ApiTrialHistory.scala new file mode 100644 index 0000000..60f72a6 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/trialhistory/ApiTrialHistory.scala @@ -0,0 +1,26 @@ +package xyz.driver.pdsuidomain.formats.json.trialhistory + +import java.time.{ZoneId, ZonedDateTime} + +import play.api.libs.json.{Format, Json} +import xyz.driver.pdsuidomain.entities.TrialHistory + +final case class ApiTrialHistory(id: Long, + executor: Long, + trialId: String, + state: String, + action: String, + created: ZonedDateTime) + +object ApiTrialHistory { + implicit val format: Format[ApiTrialHistory] = Json.format[ApiTrialHistory] + + def fromDomain(x: TrialHistory) = ApiTrialHistory( + id = x.id.id, + executor = x.executor.id, + trialId = x.trialId.id, + state = TrialHistory.State.stateToString(x.state), + action = TrialHistory.Action.actionToString(x.action), + created = ZonedDateTime.of(x.created, ZoneId.of("Z")) + ) +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/TrialHistoryService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/TrialHistoryService.scala new file mode 100644 index 0000000..17111a9 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/services/TrialHistoryService.scala @@ -0,0 +1,49 @@ +package xyz.driver.pdsuidomain.services + +import java.time.LocalDateTime + +import xyz.driver.pdsuicommon.auth.AuthenticatedRequestContext +import xyz.driver.pdsuicommon.db.{Pagination, SearchFilterExpr, Sorting} +import xyz.driver.pdsuicommon.domain.StringId +import xyz.driver.pdsuicommon.error.DomainError +import xyz.driver.pdsuidomain.entities.{Trial, TrialHistory} + +import scala.concurrent.Future + +object TrialHistoryService { + + trait DefaultNotFoundError { + def userMessage: String = "Trial not found" + } + + trait DefaultAccessDeniedError { + def userMessage: String = "Access denied" + } + + sealed trait GetListReply + object GetListReply { + case class EntityList(xs: Seq[TrialHistory], + totalFound: Int, + lastUpdate: Option[LocalDateTime]) + extends GetListReply + + case object AuthorizationError + extends GetListReply + with DomainError.AuthorizationError + with DefaultAccessDeniedError + } + +} + +trait TrialHistoryService { + + import TrialHistoryService._ + + def getListByTrialId(id: StringId[Trial], + filter: SearchFilterExpr = SearchFilterExpr.Empty, + sorting: Option[Sorting] = None, + pagination: Option[Pagination] = None)( + implicit requestContext: AuthenticatedRequestContext) + : Future[GetListReply] + +} -- cgit v1.2.3