From ceba49c0ea56fcc41e24a9e0f9a868258ff89055 Mon Sep 17 00:00:00 2001 From: simonredfern Date: Tue, 20 Jan 2026 15:14:01 +0100 Subject: [PATCH] Added /personal-dynamic-entities/available --- .../src/main/scala/code/api/util/ApiTag.scala | 1 + .../main/scala/code/api/util/Glossary.scala | 8 ++- .../scala/code/api/v6_0_0/APIMethods600.scala | 58 +++++++++++++++++++ .../code/api/v6_0_0/JSONFactory6.0.0.scala | 1 + 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/obp-api/src/main/scala/code/api/util/ApiTag.scala b/obp-api/src/main/scala/code/api/util/ApiTag.scala index da98f2548..a3554e474 100644 --- a/obp-api/src/main/scala/code/api/util/ApiTag.scala +++ b/obp-api/src/main/scala/code/api/util/ApiTag.scala @@ -106,6 +106,7 @@ object ApiTag { val apiTagDynamic = ResourceDocTag("Dynamic") val apiTagDynamicEntity = ResourceDocTag("Dynamic-Entity") val apiTagManageDynamicEntity = ResourceDocTag("Dynamic-Entity-Manage") + val apiTagPersonalDynamicEntity = ResourceDocTag("Personal-Dynamic-Entity") val apiTagDynamicEndpoint = ResourceDocTag("Dynamic-Endpoint") val apiTagManageDynamicEndpoint = ResourceDocTag("Dynamic-Endpoint-Manage") diff --git a/obp-api/src/main/scala/code/api/util/Glossary.scala b/obp-api/src/main/scala/code/api/util/Glossary.scala index 2e4512443..3c702133a 100644 --- a/obp-api/src/main/scala/code/api/util/Glossary.scala +++ b/obp-api/src/main/scala/code/api/util/Glossary.scala @@ -3283,7 +3283,13 @@ object Glossary extends MdcLoggable { |* GET /my/dynamic-entities - Get all Dynamic Entity definitions I created |* PUT /my/dynamic-entities/DYNAMIC_ENTITY_ID - Update a definition I created | -|**Response format for GET /my/dynamic-entities:** +|**Discovery endpoint (available from v6.0.0):** +| +|* GET /personal-dynamic-entities/available - Discover all Dynamic Entities that support personal data storage +| +|This endpoint allows regular users (without admin roles) to discover which dynamic entities they can interact with for storing personal data via the /my/ENTITY_NAME endpoints. No special roles required - just needs to be logged in. +| +|**Response format for GET /my/dynamic-entities and GET /personal-dynamic-entities/available:** | |**v6.0.0 format (recommended):** | 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 12d92f467..dbf835eb3 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 @@ -6458,6 +6458,64 @@ trait APIMethods600 { } } + staticResourceDocs += ResourceDoc( + getAvailablePersonalDynamicEntities, + implementedInApiVersion, + nameOf(getAvailablePersonalDynamicEntities), + "GET", + "/personal-dynamic-entities/available", + "Get Available Personal Dynamic Entities", + s"""Get all Dynamic Entities that support personal data storage (hasPersonalEntity == true). + | + |This endpoint allows regular users (without admin roles) to discover which dynamic entities + |they can interact with for storing personal data via the /my/ENTITY_NAME endpoints. + | + |Authentication: User must be logged in (no special roles required). + | + |Use case: Portals and apps can show users what personal data types are available + |without needing admin access to view all dynamic entity definitions. + | + |For more information see ${Glossary.getGlossaryItemLink("My-Dynamic-Entities")}""", + EmptyBody, + MyDynamicEntitiesJsonV600( + dynamic_entities = List( + DynamicEntityDefinitionJsonV600( + dynamic_entity_id = "abc-123-def", + entity_name = "CustomerPreferences", + user_id = "user-456", + bank_id = None, + has_personal_entity = true, + definition = net.liftweb.json.parse("""{"description": "User preferences", "required": ["theme"], "properties": {"theme": {"type": "string"}, "language": {"type": "string"}}}""").asInstanceOf[net.liftweb.json.JsonAST.JObject] + ) + ) + ), + List( + $UserNotLoggedIn, + UnknownError + ), + List(apiTagPersonalDynamicEntity, apiTagApi) + ) + + lazy val getAvailablePersonalDynamicEntities: OBPEndpoint = { + case "personal-dynamic-entities" :: "available" :: Nil JsonGet req => { cc => + implicit val ec = EndpointContext(Some(cc)) + for { + // Get all dynamic entities (system and bank level) + allDynamicEntities <- Future( + NewStyle.function.getDynamicEntities(None, false) ++ + NewStyle.function.getDynamicEntities(None, true) + ) + } yield { + // Filter to only those with hasPersonalEntity == true + val personalEntities: List[DynamicEntityCommons] = allDynamicEntities.filter(_.hasPersonalEntity) + ( + JSONFactory600.createMyDynamicEntitiesJson(personalEntities), + HttpCode.`200`(cc.callContext) + ) + } + } + } + } } diff --git a/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala b/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala index 3eba87925..3c346ca7c 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala @@ -1347,4 +1347,5 @@ object JSONFactory600 extends CustomJsonFormats with MdcLoggable { } ) } + }