From 532c37cf280fc7da75c10910d20e494aef0f2a95 Mon Sep 17 00:00:00 2001 From: hongwei Date: Thu, 27 Nov 2025 12:30:52 +0100 Subject: [PATCH] Refactor /Group management: Introduce GroupTrait and MappedGroupProvider, replacing MappedGroup. Enhance group creation, retrieval, updating, and deletion methods with improved type handling and error management. --- .../scala/code/api/v6_0_0/APIMethods600.scala | 18 +-- obp-api/src/main/scala/code/group/Group.scala | 113 ++++++++++++++---- .../main/scala/code/group/GroupTrait.scala | 45 +++++++ .../main/scala/code/group/MappedGroup.scala | 112 ----------------- 4 files changed, 144 insertions(+), 144 deletions(-) create mode 100644 obp-api/src/main/scala/code/group/GroupTrait.scala delete mode 100644 obp-api/src/main/scala/code/group/MappedGroup.scala diff --git a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala index d84b498c7..eb842588b 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala @@ -2105,7 +2105,7 @@ trait APIMethods600 { NewStyle.function.hasEntitlement("", u.userId, canCreateGroupsAtAllBanks, callContext) } group <- Future { - code.group.Group.group.vend.createGroup( + code.group.GroupTrait.group.vend.createGroup( postJson.bank_id.filter(_.nonEmpty), postJson.group_name, postJson.group_description, @@ -2169,7 +2169,7 @@ trait APIMethods600 { for { (Full(u), callContext) <- authenticatedAccess(cc) group <- Future { - code.group.Group.group.vend.getGroup(groupId) + code.group.GroupTrait.group.vend.getGroup(groupId) } map { x => unboxFullOrFail(x, callContext, s"$UnknownError Group not found", 404) } @@ -2254,15 +2254,15 @@ trait APIMethods600 { } groups <- bankIdFilter match { case Some(bankId) => - code.group.Group.group.vend.getGroupsByBankId(Some(bankId)) map { + code.group.GroupTrait.group.vend.getGroupsByBankId(Some(bankId)) map { x => unboxFullOrFail(x, callContext, s"$UnknownError Cannot get groups", 400) } case None if bankIdParam.isDefined => - code.group.Group.group.vend.getGroupsByBankId(None) map { + code.group.GroupTrait.group.vend.getGroupsByBankId(None) map { x => unboxFullOrFail(x, callContext, s"$UnknownError Cannot get groups", 400) } case None => - code.group.Group.group.vend.getAllGroups() map { + code.group.GroupTrait.group.vend.getAllGroups() map { x => unboxFullOrFail(x, callContext, s"$UnknownError Cannot get groups", 400) } } @@ -2333,7 +2333,7 @@ trait APIMethods600 { json.extract[PutGroupJsonV600] } existingGroup <- Future { - code.group.Group.group.vend.getGroup(groupId) + code.group.GroupTrait.group.vend.getGroup(groupId) } map { x => unboxFullOrFail(x, callContext, s"$UnknownError Group not found", 404) } @@ -2344,7 +2344,7 @@ trait APIMethods600 { NewStyle.function.hasEntitlement("", u.userId, canUpdateGroupsAtAllBanks, callContext) } updatedGroup <- Future { - code.group.Group.group.vend.updateGroup( + code.group.GroupTrait.group.vend.updateGroup( groupId, putJson.group_name, putJson.group_description, @@ -2401,7 +2401,7 @@ trait APIMethods600 { for { (Full(u), callContext) <- authenticatedAccess(cc) existingGroup <- Future { - code.group.Group.group.vend.getGroup(groupId) + code.group.GroupTrait.group.vend.getGroup(groupId) } map { x => unboxFullOrFail(x, callContext, s"$UnknownError Group not found", 404) } @@ -2412,7 +2412,7 @@ trait APIMethods600 { NewStyle.function.hasEntitlement("", u.userId, canDeleteGroupsAtAllBanks, callContext) } deleted <- Future { - code.group.Group.group.vend.deleteGroup(groupId) + code.group.GroupTrait.group.vend.deleteGroup(groupId) } map { x => unboxFullOrFail(x, callContext, s"$UnknownError Cannot delete group", 400) } diff --git a/obp-api/src/main/scala/code/group/Group.scala b/obp-api/src/main/scala/code/group/Group.scala index de5f16acc..a89d7423c 100644 --- a/obp-api/src/main/scala/code/group/Group.scala +++ b/obp-api/src/main/scala/code/group/Group.scala @@ -1,45 +1,112 @@ package code.group -import net.liftweb.common.Box -import net.liftweb.util.SimpleInjector +import code.util.MappedUUID +import net.liftweb.common.{Box, Empty, Full} +import net.liftweb.mapper._ +import net.liftweb.util.Helpers.tryo import scala.concurrent.Future +import com.openbankproject.commons.ExecutionContext.Implicits.global -object Group extends SimpleInjector { - val group = new Inject(buildOne _) {} +object MappedGroupProvider extends GroupProvider { - def buildOne: GroupProvider = MappedGroupProvider -} - -trait GroupProvider { - def createGroup( + override def createGroup( bankId: Option[String], groupName: String, groupDescription: String, listOfRoles: List[String], isEnabled: Boolean - ): Box[Group] + ): Box[GroupTrait] = { + tryo { + Group.create + .BankId(bankId.getOrElse("")) + .GroupName(groupName) + .GroupDescription(groupDescription) + .ListOfRoles(listOfRoles.mkString(",")) + .IsEnabled(isEnabled) + .saveMe() + } + } - def getGroup(groupId: String): Box[Group] - def getGroupsByBankId(bankId: Option[String]): Future[Box[List[Group]]] - def getAllGroups(): Future[Box[List[Group]]] + override def getGroup(groupId: String): Box[GroupTrait] = { + Group.find(By(Group.GroupId, groupId)) + } - def updateGroup( + override def getGroupsByBankId(bankId: Option[String]): Future[Box[List[GroupTrait]]] = { + Future { + tryo { + bankId match { + case Some(id) => + Group.findAll(By(Group.BankId, id)) + case None => + Group.findAll(By(Group.BankId, "")) + } + } + } + } + + override def getAllGroups(): Future[Box[List[GroupTrait]]] = { + Future { + tryo { + Group.findAll() + } + } + } + + override def updateGroup( groupId: String, groupName: Option[String], groupDescription: Option[String], listOfRoles: Option[List[String]], isEnabled: Option[Boolean] - ): Box[Group] + ): Box[GroupTrait] = { + Group.find(By(Group.GroupId, groupId)).flatMap { group => + tryo { + groupName.foreach(name => group.GroupName(name)) + groupDescription.foreach(desc => group.GroupDescription(desc)) + listOfRoles.foreach(roles => group.ListOfRoles(roles.mkString(","))) + isEnabled.foreach(enabled => group.IsEnabled(enabled)) + group.saveMe() + } + } + } - def deleteGroup(groupId: String): Box[Boolean] + override def deleteGroup(groupId: String): Box[Boolean] = { + Group.find(By(Group.GroupId, groupId)).flatMap { group => + tryo { + group.delete_! + } + } + } } -trait Group { - def groupId: String - def bankId: Option[String] - def groupName: String - def groupDescription: String - def listOfRoles: List[String] - def isEnabled: Boolean +class Group extends GroupTrait with LongKeyedMapper[Group] with IdPK with CreatedUpdated { + + def getSingleton = Group + + object GroupId extends MappedUUID(this) + object BankId extends MappedString(this, 255) // Empty string for system-level groups + object GroupName extends MappedString(this, 255) + object GroupDescription extends MappedText(this) + object ListOfRoles extends MappedText(this) // Comma-separated list of roles + object IsEnabled extends MappedBoolean(this) + + override def groupId: String = GroupId.get.toString + override def bankId: Option[String] = { + val id = BankId.get + if (id == null || id.isEmpty) None else Some(id) + } + override def groupName: String = GroupName.get + override def groupDescription: String = GroupDescription.get + override def listOfRoles: List[String] = { + val rolesStr = ListOfRoles.get + if (rolesStr == null || rolesStr.isEmpty) List.empty + else rolesStr.split(",").map(_.trim).filter(_.nonEmpty).toList + } + override def isEnabled: Boolean = IsEnabled.get +} + +object Group extends Group with LongKeyedMetaMapper[Group] { + override def dbTableName = "Group" // define the DB table name + override def dbIndexes = Index(GroupId) :: Index(BankId) :: super.dbIndexes } \ No newline at end of file diff --git a/obp-api/src/main/scala/code/group/GroupTrait.scala b/obp-api/src/main/scala/code/group/GroupTrait.scala new file mode 100644 index 000000000..939454b72 --- /dev/null +++ b/obp-api/src/main/scala/code/group/GroupTrait.scala @@ -0,0 +1,45 @@ +package code.group + +import net.liftweb.common.Box +import net.liftweb.util.SimpleInjector + +import scala.concurrent.Future + +object GroupTrait extends SimpleInjector { + val group = new Inject(buildOne _) {} + + def buildOne: GroupProvider = MappedGroupProvider +} + +trait GroupProvider { + def createGroup( + bankId: Option[String], + groupName: String, + groupDescription: String, + listOfRoles: List[String], + isEnabled: Boolean + ): Box[GroupTrait] + + def getGroup(groupId: String): Box[GroupTrait] + def getGroupsByBankId(bankId: Option[String]): Future[Box[List[GroupTrait]]] + def getAllGroups(): Future[Box[List[GroupTrait]]] + + def updateGroup( + groupId: String, + groupName: Option[String], + groupDescription: Option[String], + listOfRoles: Option[List[String]], + isEnabled: Option[Boolean] + ): Box[GroupTrait] + + def deleteGroup(groupId: String): Box[Boolean] +} + +trait GroupTrait { + def groupId: String + def bankId: Option[String] + def groupName: String + def groupDescription: String + def listOfRoles: List[String] + def isEnabled: Boolean +} \ No newline at end of file diff --git a/obp-api/src/main/scala/code/group/MappedGroup.scala b/obp-api/src/main/scala/code/group/MappedGroup.scala deleted file mode 100644 index 5579b9c34..000000000 --- a/obp-api/src/main/scala/code/group/MappedGroup.scala +++ /dev/null @@ -1,112 +0,0 @@ -package code.group - -import code.util.MappedUUID -import net.liftweb.common.{Box, Empty, Full} -import net.liftweb.mapper._ -import net.liftweb.util.Helpers.tryo - -import scala.concurrent.Future -import com.openbankproject.commons.ExecutionContext.Implicits.global - -object MappedGroupProvider extends GroupProvider { - - override def createGroup( - bankId: Option[String], - groupName: String, - groupDescription: String, - listOfRoles: List[String], - isEnabled: Boolean - ): Box[Group] = { - tryo { - MappedGroup.create - .BankId(bankId.getOrElse("")) - .GroupName(groupName) - .GroupDescription(groupDescription) - .ListOfRoles(listOfRoles.mkString(",")) - .IsEnabled(isEnabled) - .saveMe() - } - } - - override def getGroup(groupId: String): Box[Group] = { - MappedGroup.find(By(MappedGroup.GroupId, groupId)) - } - - override def getGroupsByBankId(bankId: Option[String]): Future[Box[List[Group]]] = { - Future { - tryo { - bankId match { - case Some(id) => - MappedGroup.findAll(By(MappedGroup.BankId, id)) - case None => - MappedGroup.findAll(By(MappedGroup.BankId, "")) - } - } - } - } - - override def getAllGroups(): Future[Box[List[Group]]] = { - Future { - tryo { - MappedGroup.findAll() - } - } - } - - override def updateGroup( - groupId: String, - groupName: Option[String], - groupDescription: Option[String], - listOfRoles: Option[List[String]], - isEnabled: Option[Boolean] - ): Box[Group] = { - MappedGroup.find(By(MappedGroup.GroupId, groupId)).flatMap { group => - tryo { - groupName.foreach(name => group.GroupName(name)) - groupDescription.foreach(desc => group.GroupDescription(desc)) - listOfRoles.foreach(roles => group.ListOfRoles(roles.mkString(","))) - isEnabled.foreach(enabled => group.IsEnabled(enabled)) - group.saveMe() - } - } - } - - override def deleteGroup(groupId: String): Box[Boolean] = { - MappedGroup.find(By(MappedGroup.GroupId, groupId)).flatMap { group => - tryo { - group.delete_! - } - } - } -} - -class MappedGroup extends Group with LongKeyedMapper[MappedGroup] with IdPK with CreatedUpdated { - - def getSingleton = MappedGroup - - object GroupId extends MappedUUID(this) - object BankId extends MappedString(this, 255) // Empty string for system-level groups - object GroupName extends MappedString(this, 255) - object GroupDescription extends MappedText(this) - object ListOfRoles extends MappedText(this) // Comma-separated list of roles - object IsEnabled extends MappedBoolean(this) - - override def groupId: String = GroupId.get.toString - override def bankId: Option[String] = { - val id = BankId.get - if (id == null || id.isEmpty) None else Some(id) - } - override def groupName: String = GroupName.get - override def groupDescription: String = GroupDescription.get - override def listOfRoles: List[String] = { - val rolesStr = ListOfRoles.get - if (rolesStr == null || rolesStr.isEmpty) List.empty - else rolesStr.split(",").map(_.trim).filter(_.nonEmpty).toList - } - override def isEnabled: Boolean = IsEnabled.get -} - -object MappedGroup extends MappedGroup with LongKeyedMetaMapper[MappedGroup] { - override def dbTableName = "Group" // define the DB table name - override def dbIndexes = Index(GroupId) :: Index(BankId) :: super.dbIndexes -} \ No newline at end of file