From 98cecaebc650584f66d8c28c8424e8481c4814cc Mon Sep 17 00:00:00 2001 From: Kseniya Tomskikh Date: Wed, 2 Aug 2017 15:25:17 +0600 Subject: PDSUI-2181 Created entities for patient history --- .../scala/xyz/driver/pdsuicommon/acl/ACL.scala | 36 +++++++-- .../pdsuidomain/entities/PatientHistory.scala | 92 ++++++++++++++++++++++ .../json/patienthistory/ApiPatientHistory.scala | 28 +++++++ .../services/PatientHistoryService.scala | 48 +++++++++++ 4 files changed, 196 insertions(+), 8 deletions(-) create mode 100644 src/main/scala/xyz/driver/pdsuidomain/entities/PatientHistory.scala create mode 100644 src/main/scala/xyz/driver/pdsuidomain/formats/json/patienthistory/ApiPatientHistory.scala create mode 100644 src/main/scala/xyz/driver/pdsuidomain/services/PatientHistoryService.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 07d5014..f21c165 100644 --- a/src/main/scala/xyz/driver/pdsuicommon/acl/ACL.scala +++ b/src/main/scala/xyz/driver/pdsuicommon/acl/ACL.scala @@ -85,7 +85,11 @@ object ACL extends PhiLogging { extends BaseACL( label = "extracted data", create = Set(DocumentExtractor, RecordAdmin), - read = Set(DocumentExtractor, RecordAdmin, RoutesCurator, TreatmentMatchingAdmin, ResearchOncologist), + read = Set(DocumentExtractor, + RecordAdmin, + RoutesCurator, + TreatmentMatchingAdmin, + ResearchOncologist), update = Set(DocumentExtractor, RecordAdmin), delete = Set(DocumentExtractor, RecordAdmin) ) @@ -151,7 +155,11 @@ object ACL extends PhiLogging { extends BaseACL( label = "criterion", create = Set(CriteriaCurator, TrialAdmin), - read = Set(CriteriaCurator, TrialAdmin, RoutesCurator, TreatmentMatchingAdmin, ResearchOncologist), + read = Set(CriteriaCurator, + TrialAdmin, + RoutesCurator, + TreatmentMatchingAdmin, + ResearchOncologist), update = Set(CriteriaCurator, TrialAdmin), delete = Set(CriteriaCurator, TrialAdmin) ) @@ -187,6 +195,12 @@ object ACL extends PhiLogging { update = TreatmentMatchingRoles ) + object PatientHistory + extends BaseACL( + label = "patient history", + read = Set(TreatmentMatchingAdmin) + ) + object PatientIssue extends BaseACL( label = "patient issue", @@ -238,26 +252,32 @@ object ACL extends PhiLogging { update: AclCheck = Forbid, delete: AclCheck = Forbid) { - def isCreateAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = { + def isCreateAllow()( + implicit requestContext: AuthenticatedRequestContext): Boolean = { check("create", create)(requestContext.executor.roles) } - def isReadAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = { + def isReadAllow()( + implicit requestContext: AuthenticatedRequestContext): Boolean = { check("read", read)(requestContext.executor.roles) } - def isUpdateAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = { + def isUpdateAllow()( + implicit requestContext: AuthenticatedRequestContext): Boolean = { check("update", update)(requestContext.executor.roles) } - def isDeleteAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = { + def isDeleteAllow()( + implicit requestContext: AuthenticatedRequestContext): Boolean = { check("delete", delete)(requestContext.executor.roles) } - private def check(action: String, isAllowed: AclCheck)(executorRoles: Set[Role]): Boolean = { + private def check(action: String, isAllowed: AclCheck)( + executorRoles: Set[Role]): Boolean = { loggedError( executorRoles.exists(isAllowed), - phi"${Unsafe(executorRoles.mkString(", "))} has no access to ${Unsafe(action)} a ${Unsafe(label)}" + phi"${Unsafe(executorRoles.mkString(", "))} has no access to ${Unsafe( + action)} a ${Unsafe(label)}" ) } } diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/PatientHistory.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/PatientHistory.scala new file mode 100644 index 0000000..e00a5f6 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/PatientHistory.scala @@ -0,0 +1,92 @@ +package xyz.driver.pdsuidomain.entities + +import java.time.{LocalDateTime, ZoneId} + +import xyz.driver.pdsuicommon.domain.{LongId, StringId, User, UuidId} +import xyz.driver.pdsuicommon.logging._ +import xyz.driver.pdsuicommon.utils.Utils +import xyz.driver.pdsuidomain.entities.PatientHistory.{Action, State} + +object PatientHistory { + + implicit def toPhiString(x: PatientHistory): PhiString = { + import x._ + phi"PatientHistory(id=$id, executor=$executor, patientId=$patientId, state=$state, action=$action, created=$created)" + } + + sealed trait State + object State { + case object Verify extends State + case object Curate extends State + case object Review extends State + case object Flag extends State + + val All: Set[State] = Set[State](Verify, Curate, Review, Flag) + + val fromString: PartialFunction[String, State] = { + case "Verify" => State.Verify + case "Curate" => State.Curate + case "Review" => State.Review + case "Flag" => State.Flag + } + + def stateToString(x: State): String = x match { + case State.Verify => "Verify" + case State.Curate => "Curate" + 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 PatientHistory(id: LongId[PatientHistory], + executor: StringId[User], + patientId: UuidId[Patient], + state: State, + action: Action, + created: LocalDateTime = LocalDateTime.now(ZoneId.of("Z"))) diff --git a/src/main/scala/xyz/driver/pdsuidomain/formats/json/patienthistory/ApiPatientHistory.scala b/src/main/scala/xyz/driver/pdsuidomain/formats/json/patienthistory/ApiPatientHistory.scala new file mode 100644 index 0000000..cdcd510 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/formats/json/patienthistory/ApiPatientHistory.scala @@ -0,0 +1,28 @@ +package xyz.driver.pdsuidomain.formats.json.patienthistory + +import java.time.{ZoneId, ZonedDateTime} +import java.util.UUID + +import play.api.libs.json.{Format, Json} +import xyz.driver.pdsuidomain.entities.PatientHistory + +final case class ApiPatientHistory(id: Long, + executor: String, + patientId: UUID, + state: String, + action: String, + created: ZonedDateTime) + +object ApiPatientHistory { + implicit val format: Format[ApiPatientHistory] = + Json.format[ApiPatientHistory] + + def fromDomain(x: PatientHistory) = ApiPatientHistory( + id = x.id.id, + executor = x.executor.id, + patientId = x.patientId.id, + state = PatientHistory.State.stateToString(x.state), + action = PatientHistory.Action.actionToString(x.action), + created = ZonedDateTime.of(x.created, ZoneId.of("Z")) + ) +} diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/PatientHistoryService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/PatientHistoryService.scala new file mode 100644 index 0000000..e312ca8 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuidomain/services/PatientHistoryService.scala @@ -0,0 +1,48 @@ +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.UuidId +import xyz.driver.pdsuicommon.error.DomainError +import xyz.driver.pdsuidomain.entities.{Patient, PatientHistory} + +import scala.concurrent.Future + +object PatientHistoryService { + + trait DefaultNotFoundError { + def userMessage: String = "Patient history not found" + } + + trait DefaultAccessDeniedError { + def userMessage: String = "Access denied" + } + + sealed trait GetListReply + object GetListReply { + final case class EntityList(xs: Seq[PatientHistory], + totalFound: Int, + lastUpdate: Option[LocalDateTime]) + extends GetListReply + + final case object AuthorizationError + extends GetListReply + with DomainError.AuthorizationError + with DefaultAccessDeniedError + } + +} + +trait PatientHistoryService { + + import PatientHistoryService._ + + def getListByPatientId(id: UuidId[Patient], + filter: SearchFilterExpr = SearchFilterExpr.Empty, + sorting: Option[Sorting] = None, + pagination: Option[Pagination] = None)( + implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] + +} -- cgit v1.2.3 From fc7c7063cafd7df8efe2c6c0dbc28e5ff0de06f6 Mon Sep 17 00:00:00 2001 From: Kseniya Tomskikh Date: Thu, 3 Aug 2017 16:21:14 +0600 Subject: PDSUI-2181 Apply scalafmt --- .../scala/xyz/driver/pdsuicommon/acl/ACL.scala | 30 ++++++---------------- .../pdsuidomain/entities/PatientHistory.scala | 22 ++++++++-------- .../services/PatientHistoryService.scala | 10 +++----- 3 files changed, 22 insertions(+), 40 deletions(-) (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 f21c165..f2a0ef0 100644 --- a/src/main/scala/xyz/driver/pdsuicommon/acl/ACL.scala +++ b/src/main/scala/xyz/driver/pdsuicommon/acl/ACL.scala @@ -85,11 +85,7 @@ object ACL extends PhiLogging { extends BaseACL( label = "extracted data", create = Set(DocumentExtractor, RecordAdmin), - read = Set(DocumentExtractor, - RecordAdmin, - RoutesCurator, - TreatmentMatchingAdmin, - ResearchOncologist), + read = Set(DocumentExtractor, RecordAdmin, RoutesCurator, TreatmentMatchingAdmin, ResearchOncologist), update = Set(DocumentExtractor, RecordAdmin), delete = Set(DocumentExtractor, RecordAdmin) ) @@ -155,11 +151,7 @@ object ACL extends PhiLogging { extends BaseACL( label = "criterion", create = Set(CriteriaCurator, TrialAdmin), - read = Set(CriteriaCurator, - TrialAdmin, - RoutesCurator, - TreatmentMatchingAdmin, - ResearchOncologist), + read = Set(CriteriaCurator, TrialAdmin, RoutesCurator, TreatmentMatchingAdmin, ResearchOncologist), update = Set(CriteriaCurator, TrialAdmin), delete = Set(CriteriaCurator, TrialAdmin) ) @@ -252,32 +244,26 @@ object ACL extends PhiLogging { update: AclCheck = Forbid, delete: AclCheck = Forbid) { - def isCreateAllow()( - implicit requestContext: AuthenticatedRequestContext): Boolean = { + def isCreateAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = { check("create", create)(requestContext.executor.roles) } - def isReadAllow()( - implicit requestContext: AuthenticatedRequestContext): Boolean = { + def isReadAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = { check("read", read)(requestContext.executor.roles) } - def isUpdateAllow()( - implicit requestContext: AuthenticatedRequestContext): Boolean = { + def isUpdateAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = { check("update", update)(requestContext.executor.roles) } - def isDeleteAllow()( - implicit requestContext: AuthenticatedRequestContext): Boolean = { + def isDeleteAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = { check("delete", delete)(requestContext.executor.roles) } - private def check(action: String, isAllowed: AclCheck)( - executorRoles: Set[Role]): Boolean = { + private def check(action: String, isAllowed: AclCheck)(executorRoles: Set[Role]): Boolean = { loggedError( executorRoles.exists(isAllowed), - phi"${Unsafe(executorRoles.mkString(", "))} has no access to ${Unsafe( - action)} a ${Unsafe(label)}" + phi"${Unsafe(executorRoles.mkString(", "))} has no access to ${Unsafe(action)} a ${Unsafe(label)}" ) } } diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/PatientHistory.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/PatientHistory.scala index e00a5f6..39817c4 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/entities/PatientHistory.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/entities/PatientHistory.scala @@ -16,25 +16,25 @@ object PatientHistory { sealed trait State object State { - case object Verify extends State + case object Verify extends State case object Curate extends State - case object Review extends State - case object Flag extends State + case object Review extends State + case object Flag extends State val All: Set[State] = Set[State](Verify, Curate, Review, Flag) val fromString: PartialFunction[String, State] = { - case "Verify" => State.Verify - case "Curate" => State.Curate - case "Review" => State.Review - case "Flag" => State.Flag + case "Verify" => State.Verify + case "Curate" => State.Curate + case "Review" => State.Review + case "Flag" => State.Flag } def stateToString(x: State): String = x match { - case State.Verify => "Verify" - case State.Curate => "Curate" - case State.Review => "Review" - case State.Flag => "Flag" + case State.Verify => "Verify" + case State.Curate => "Curate" + case State.Review => "Review" + case State.Flag => "Flag" } implicit def toPhiString(x: State): PhiString = diff --git a/src/main/scala/xyz/driver/pdsuidomain/services/PatientHistoryService.scala b/src/main/scala/xyz/driver/pdsuidomain/services/PatientHistoryService.scala index e312ca8..855eddc 100644 --- a/src/main/scala/xyz/driver/pdsuidomain/services/PatientHistoryService.scala +++ b/src/main/scala/xyz/driver/pdsuidomain/services/PatientHistoryService.scala @@ -22,15 +22,11 @@ object PatientHistoryService { sealed trait GetListReply object GetListReply { - final case class EntityList(xs: Seq[PatientHistory], - totalFound: Int, - lastUpdate: Option[LocalDateTime]) + final case class EntityList(xs: Seq[PatientHistory], totalFound: Int, lastUpdate: Option[LocalDateTime]) extends GetListReply final case object AuthorizationError - extends GetListReply - with DomainError.AuthorizationError - with DefaultAccessDeniedError + extends GetListReply with DomainError.AuthorizationError with DefaultAccessDeniedError } } @@ -43,6 +39,6 @@ trait PatientHistoryService { filter: SearchFilterExpr = SearchFilterExpr.Empty, sorting: Option[Sorting] = None, pagination: Option[Pagination] = None)( - implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] + implicit requestContext: AuthenticatedRequestContext): Future[GetListReply] } -- cgit v1.2.3