diff --git a/obp-api/src/main/resources/docs/glossary/Dynamic_Resource_Doc.md b/obp-api/src/main/resources/docs/glossary/Dynamic_Resource_Doc_Introduction.md
similarity index 100%
rename from obp-api/src/main/resources/docs/glossary/Dynamic_Resource_Doc.md
rename to obp-api/src/main/resources/docs/glossary/Dynamic_Resource_Doc_Introduction.md
diff --git a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
index a9b96b4966..0f9fcf81ec 100644
--- a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
+++ b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
@@ -310,6 +310,10 @@ class Boot extends MdcLoggable {
// Toggle off via routing_schemes.seed_defaults_at_boot=false in environments that don't want defaults.
code.routingscheme.RoutingSchemeSeed.runIfEnabled()
+ // Report which static Glossary Items the database is currently displacing. A developer editing
+ // Glossary.scala has no other way to find out that their text is being overridden.
+ code.api.util.Glossary.logStaticOverrides()
+
if (APIUtil.getPropsAsBoolValue("create_system_views_at_boot", true)) {
// Create system views
val owner = Views.views.vend.getOrCreateSystemView(SYSTEM_OWNER_VIEW_ID).isDefined
@@ -1080,6 +1084,7 @@ object ToSchemify extends MdcLoggable {
Organisation,
RoutingScheme,
BankSupportedRoutingScheme,
+ code.glossaryitem.DynamicGlossaryItem,
PayeeLookup,
UtilityPaymentCallback,
BulkPayment,
diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/OpenAPI31JSONFactory.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/OpenAPI31JSONFactory.scala
index 604a466236..8425e34be4 100644
--- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/OpenAPI31JSONFactory.scala
+++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/OpenAPI31JSONFactory.scala
@@ -654,7 +654,7 @@ object OpenAPI31JSONFactory extends MdcLoggable {
val operation = OperationJson(
summary = Some(doc.summary),
- description = Some(doc.description),
+ description = Some(Glossary.expandGlossaryPlaceholders(doc.description)),
operationId = Some(doc.operation_id),
tags = tags,
parameters = if (parameters.nonEmpty) Some(parameters) else None,
diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerJSONFactory.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerJSONFactory.scala
index 918929197b..bc7e467fc9 100644
--- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerJSONFactory.scala
+++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerJSONFactory.scala
@@ -561,7 +561,7 @@ object SwaggerJSONFactory extends MdcLoggable {
OperationObjectJson(
tags = rd.tags,
summary = rd.summary,
- description = PegdownOptions.convertPegdownToHtmlTweaked(rd.description.stripMargin).replaceAll("\n", ""),
+ description = PegdownOptions.convertPegdownToHtmlTweaked(Glossary.expandGlossaryPlaceholders(rd.description.stripMargin)).replaceAll("\n", ""),
operationId = s"${rd.operation_id}",
parameters ={
val description = rd.example_request_body match {
diff --git a/obp-api/src/main/scala/code/api/util/APIUtil.scala b/obp-api/src/main/scala/code/api/util/APIUtil.scala
index 484207481b..62f51a4274 100644
--- a/obp-api/src/main/scala/code/api/util/APIUtil.scala
+++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala
@@ -1973,8 +1973,13 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|""".stripMargin
}
+ /**
+ * The Glossary as served by GET /api/glossary: the static Glossary Items compiled into
+ * Glossary.scala, unioned with the Dynamic Glossary Items held in the database. A Dynamic Item
+ * replaces a static one of the same title.
+ */
def getGlossaryItems : List[GlossaryItem] = {
- Glossary.glossaryItems.toList.sortBy(_.title)
+ Glossary.allGlossaryItems.sortBy(_.title)
}
case class MessageDoc(
@@ -5066,7 +5071,11 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
apiCollectionIdParam: Option[String],
isVersion4OrHigher: Option[Boolean]
) = s"requestedApiVersionString:$requestedApiVersionString-bankId:$bankId-tags:$tags-partialFunctions:$partialFunctions-locale:${locale.toString}" +
- s"-contentParam:$contentParam-apiCollectionIdParam:$apiCollectionIdParam-isVersion4OrHigher:$isVersion4OrHigher".intern()
+ // The Glossary version belongs in the key: endpoint descriptions embed Glossary text, so a
+ // Dynamic Glossary Item that overrides a static one must not stay masked by a cached document
+ // for the rest of the resource-doc / swagger TTL. Reading it is an in-memory lookup that
+ // re-checks the database at most once a second.
+ s"-contentParam:$contentParam-apiCollectionIdParam:$apiCollectionIdParam-isVersion4OrHigher:$isVersion4OrHigher-glossary:${Glossary.glossaryVersionForCacheKey}".intern()
def getUserLacksRevokePermissionErrorMessage(sourceViewId: ViewId, targetViewId: ViewId) =
if (isValidSystemViewId(targetViewId.value))
diff --git a/obp-api/src/main/scala/code/api/util/ApiRole.scala b/obp-api/src/main/scala/code/api/util/ApiRole.scala
index 9b840a726b..8f482e255f 100644
--- a/obp-api/src/main/scala/code/api/util/ApiRole.scala
+++ b/obp-api/src/main/scala/code/api/util/ApiRole.scala
@@ -1109,6 +1109,14 @@ object ApiRole extends MdcLoggable{
case class CanReadGlossary(requiresBankId: Boolean = false) extends ApiRole
lazy val canReadGlossary = CanReadGlossary()
+ // Dynamic Glossary Items are system level, like the static Glossary they are merged into.
+ case class CanCreateGlossaryItem(requiresBankId: Boolean = false) extends ApiRole
+ lazy val canCreateGlossaryItem = CanCreateGlossaryItem()
+ case class CanUpdateGlossaryItem(requiresBankId: Boolean = false) extends ApiRole
+ lazy val canUpdateGlossaryItem = CanUpdateGlossaryItem()
+ case class CanDeleteGlossaryItem(requiresBankId: Boolean = false) extends ApiRole
+ lazy val canDeleteGlossaryItem = CanDeleteGlossaryItem()
+
case class CanCreateCustomerAttributeDefinitionAtOneBank(requiresBankId: Boolean = true) extends ApiRole
lazy val canCreateCustomerAttributeDefinitionAtOneBank = CanCreateCustomerAttributeDefinitionAtOneBank()
diff --git a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala
index 650f57f670..7d14fc84f7 100644
--- a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala
+++ b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala
@@ -510,6 +510,15 @@ object ErrorMessages {
val CreateApiProductSubscriptionAttributeError = "OBP-30569: Could not create ApiProductSubscriptionAttribute."
val DeleteApiProductSubscriptionAttributeError = "OBP-30570: Could not delete ApiProductSubscriptionAttribute."
+ // Dynamic Glossary Item (OBP-30571 .. OBP-30577)
+ val GlossaryItemNotFound = "OBP-30571: Glossary Item not found. Please specify a valid value for TITLE."
+ val GlossaryItemAlreadyExists = "OBP-30572: Glossary Item already exists. Please specify a different value for title, or update the existing one."
+ val InvalidGlossaryItemTitle = "OBP-30573: Invalid Glossary Item title. It must be non empty and at most 255 characters."
+ val CreateGlossaryItemError = "OBP-30574: Could not create Glossary Item."
+ val UpdateGlossaryItemError = "OBP-30575: Could not update Glossary Item."
+ val DeleteGlossaryItemError = "OBP-30576: Could not delete Glossary Item."
+ val GlossaryItemShadowsStaticItem = "OBP-30577: A static Glossary Item with this title already exists. Creating this item would override it in the Glossary. Set overrides_static_item to true if that is intended, or choose a different title."
+
val OrganisationNotFound = "OBP-30506: Organisation not found. Please specify a valid value for ORGANISATION_ID."
val OrganisationAlreadyExists = "OBP-30507: Organisation already exists. Please specify a different value for ORGANISATION_ID."
val InvalidOrganisationIdFormat = "OBP-30508: Invalid Organisation Id. The ORGANISATION_ID should only contain 0-9/a-z/A-Z/'-'/'.'/'_', and be between 2 and 64 characters in length."
diff --git a/obp-api/src/main/scala/code/api/util/ExampleValue.scala b/obp-api/src/main/scala/code/api/util/ExampleValue.scala
index 64c304e94e..c934bba928 100644
--- a/obp-api/src/main/scala/code/api/util/ExampleValue.scala
+++ b/obp-api/src/main/scala/code/api/util/ExampleValue.scala
@@ -35,7 +35,8 @@ object ExampleValue {
lazy val bankIdExample = ConnectorField("gh.29.uk", s"A string that MUST uniquely identify the bank on this OBP instance. " +
s"It COULD be a UUID but is generally a short string that easily identifies the bank / brand it represents.")
lazy val bank_idExample = bankIdExample
- glossaryItems += makeGlossaryItem("Bank.bank_id", bankIdExample)
+ // No glossary item for Bank.bank_id here: Glossary.scala defines a fuller one (format, version
+ // history), and two items with the same title made the Glossary return it twice.
lazy val accountIdExample = ConnectorField("8ca8a7e4-6d02-40e3-a129-0b2bf89de9f0", s"A string that, in combination with the bankId MUST uniquely identify the account on this OBP instance. SHOULD be a UUID. " +
s"MUST NOT be able to guess accountNumber from accountId. OBP-API or Adapter keeps a mapping between accountId and accountNumber. AccountId is a non reversible hash of the human readable account number.")
@@ -149,7 +150,7 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("Customer.attributeId", customerAttributeIdExample)
lazy val userAttributeIdExample = ConnectorField("7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", s"User attribute id")
- glossaryItems += makeGlossaryItem("Customer.attributeId", userAttributeIdExample)
+ glossaryItems += makeGlossaryItem("User.attributeId", userAttributeIdExample)
lazy val customerAttributeNameExample = ConnectorField("SPECIAL_TAX_NUMBER", s"Customer attribute name")
glossaryItems += makeGlossaryItem("Customer.attributeName", customerAttributeNameExample)
@@ -568,13 +569,14 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("DynamicResourceDoc.dynamicResourceDocId", dynamicResourceDocIdExample)
lazy val partialFunctionExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("DynamicResourceDoc.partialFunction", partialFunctionExample)
+ // glossaryItems += makeGlossaryItem("DynamicResourceDoc.partialFunction", partialFunctionExample)
lazy val implementedInApiVersionExample = ConnectorField(NoExampleProvided, NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("DynamicResourceDoc.implementedInApiVersion", implementedInApiVersionExample)
+ // glossaryItems += makeGlossaryItem("DynamicResourceDoc.implementedInApiVersion", implementedInApiVersionExample)
+ // No glossary item here: dynamicResourceDocPartialFunctionNameExample below registers this same
+ // title, and its value is the one SwaggerDefinitionsJSON uses.
lazy val partialFunctionNameExample = ConnectorField("getBanks", "partial function name")
- glossaryItems += makeGlossaryItem("DynamicResourceDoc.partialFunctionName", partialFunctionNameExample)
lazy val dynamicResourceDocPartialFunctionNameExample = ConnectorField("createUser", "partial function name")
glossaryItems += makeGlossaryItem("DynamicResourceDoc.partialFunctionName", dynamicResourceDocPartialFunctionNameExample)
@@ -600,28 +602,28 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("DynamicResourceDoc.isFeatured", isFeaturedExample)
lazy val specialInstructionsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("DynamicResourceDoc.specialInstructions", specialInstructionsExample)
+ // glossaryItems += makeGlossaryItem("DynamicResourceDoc.specialInstructions", specialInstructionsExample)
lazy val specifiedUrlExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("DynamicResourceDoc.specifiedUrl", specifiedUrlExample)
+ // glossaryItems += makeGlossaryItem("DynamicResourceDoc.specifiedUrl", specifiedUrlExample)
lazy val dynamicMessageDocIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("DynamicMessageDoc.dynamicMessageDocId", dynamicMessageDocIdExample)
+ // glossaryItems += makeGlossaryItem("DynamicMessageDoc.dynamicMessageDocId", dynamicMessageDocIdExample)
lazy val outboundAvroSchemaExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("DynamicMessageDoc.outboundAvroSchema", outboundAvroSchemaExample)
+ // glossaryItems += makeGlossaryItem("DynamicMessageDoc.outboundAvroSchema", outboundAvroSchemaExample)
lazy val inboundAvroSchemaExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("DynamicMessageDoc.inboundAvroSchema", inboundAvroSchemaExample)
+ // glossaryItems += makeGlossaryItem("DynamicMessageDoc.inboundAvroSchema", inboundAvroSchemaExample)
- lazy val canSeeImagesExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeImagesExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the images attached to a Transaction.")
glossaryItems += makeGlossaryItem("can_see_images", canSeeImagesExample)
lazy val topConsumersExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("top_consumers", topConsumersExample)
+ // glossaryItems += makeGlossaryItem("top_consumers", topConsumersExample)
lazy val smsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("sms", smsExample)
+ // glossaryItems += makeGlossaryItem("sms", smsExample)
lazy val maximumResponseTimeExample = ConnectorField("60",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("maximum_response_time", maximumResponseTimeExample)
@@ -630,16 +632,16 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("cancelled", cancelledExample)
lazy val entitlementRequestsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("entitlement_requests", entitlementRequestsExample)
+ // glossaryItems += makeGlossaryItem("entitlement_requests", entitlementRequestsExample)
lazy val newBalanceExample = ConnectorField("20",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("new_balance", newBalanceExample)
lazy val nExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("n", nExample)
+ // glossaryItems += makeGlossaryItem("n", nExample)
lazy val scopesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("scopes", scopesExample)
+ // glossaryItems += makeGlossaryItem("scopes", scopesExample)
lazy val effectiveDateExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("effective_date", effectiveDateExample)
@@ -648,61 +650,61 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("date_of_application", dateOfApplicationExample)
lazy val useTypeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("use_type", useTypeExample)
+ // glossaryItems += makeGlossaryItem("use_type", useTypeExample)
lazy val cardsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("cards", cardsExample)
+ // glossaryItems += makeGlossaryItem("cards", cardsExample)
lazy val orderDateExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("order_date", orderDateExample)
lazy val canAddCommentExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("can_add_comment", canAddCommentExample)
+ // glossaryItems += makeGlossaryItem("can_add_comment", canAddCommentExample)
lazy val frequencyExample = ConnectorField("DAILY",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("frequency", frequencyExample)
lazy val ordersExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("orders", ordersExample)
+ // glossaryItems += makeGlossaryItem("orders", ordersExample)
lazy val typeExample = ConnectorField("",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("type", typeExample)
lazy val imageIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("image_id", imageIdExample)
+ // glossaryItems += makeGlossaryItem("image_id", imageIdExample)
lazy val canSeeOtherAccountRoutingSchemeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("can_see_other_account_routing_scheme", canSeeOtherAccountRoutingSchemeExample)
+ // glossaryItems += makeGlossaryItem("can_see_other_account_routing_scheme", canSeeOtherAccountRoutingSchemeExample)
- lazy val canDeleteCorporateLocationExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canDeleteCorporateLocationExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can delete the corporate location on a Transaction.")
glossaryItems += makeGlossaryItem("can_delete_corporate_location", canDeleteCorporateLocationExample)
lazy val fromExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("from", fromExample)
+ // glossaryItems += makeGlossaryItem("from", fromExample)
lazy val httpMethodExample = ConnectorField("GET",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("http_method", httpMethodExample)
lazy val developerEmailExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("developer_email", developerEmailExample)
+ // glossaryItems += makeGlossaryItem("developer_email", developerEmailExample)
lazy val logLevelExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("log_level", logLevelExample)
+ // glossaryItems += makeGlossaryItem("log_level", logLevelExample)
lazy val otherAccountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("other_account", otherAccountExample)
+ // glossaryItems += makeGlossaryItem("other_account", otherAccountExample)
lazy val balanceExample = ConnectorField("10",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("balance", balanceExample)
lazy val portsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("ports", portsExample)
+ // glossaryItems += makeGlossaryItem("ports", portsExample)
lazy val perSecondExample = ConnectorField("1000",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("per_second", perSecondExample)
lazy val challengeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("challenge", challengeExample)
+ // glossaryItems += makeGlossaryItem("challenge", challengeExample)
lazy val appNameExample = ConnectorField("appNameBank",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("app_name", appNameExample)
@@ -714,34 +716,34 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("technology", technologyExample)
lazy val connectorNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("connector_name", connectorNameExample)
+ // glossaryItems += makeGlossaryItem("connector_name", connectorNameExample)
lazy val ownersExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("owners", ownersExample)
+ // glossaryItems += makeGlossaryItem("owners", ownersExample)
lazy val exampleInboundMessageExample = ConnectorField("{}", "This is the json object.")
glossaryItems += makeGlossaryItem("example_inbound_message", exampleInboundMessageExample)
lazy val nationalIdentifierExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("national_identifier", nationalIdentifierExample)
+ // glossaryItems += makeGlossaryItem("national_identifier", nationalIdentifierExample)
lazy val temporaryRequestedCurrentAmountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("temporary_requested_current_amount", temporaryRequestedCurrentAmountExample)
+ // glossaryItems += makeGlossaryItem("temporary_requested_current_amount", temporaryRequestedCurrentAmountExample)
lazy val countExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("count", countExample)
+ // glossaryItems += makeGlossaryItem("count", countExample)
lazy val canSeeOtherAccountBankNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_BANK_NAME, canSeeOtherAccountBankNameExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_BANK_NAME, canSeeOtherAccountBankNameExample)
lazy val handleExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("handle", handleExample)
+ // glossaryItems += makeGlossaryItem("handle", handleExample)
lazy val customerTokenExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("customer_token", customerTokenExample)
+ // glossaryItems += makeGlossaryItem("customer_token", customerTokenExample)
lazy val sandboxTanExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("sandbox_tan", sandboxTanExample)
+ // glossaryItems += makeGlossaryItem("sandbox_tan", sandboxTanExample)
lazy val corporateLocationExample = ConnectorField("10",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("corporate_location", corporateLocationExample)
@@ -753,19 +755,19 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("duration", durationExample)
lazy val canSeeBankAccountTypeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_TYPE, canSeeBankAccountTypeExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_TYPE, canSeeBankAccountTypeExample)
lazy val toSepaExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("to_sepa", toSepaExample)
+ // glossaryItems += makeGlossaryItem("to_sepa", toSepaExample)
lazy val whichAliasToUseExample = ConnectorField("public",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("which_alias_to_use", whichAliasToUseExample)
lazy val canAddImageExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_ADD_IMAGE, canAddImageExample)
+ // glossaryItems += makeGlossaryItem(CAN_ADD_IMAGE, canAddImageExample)
lazy val accountAttributeIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("account_attribute_id", accountAttributeIdExample)
+ // glossaryItems += makeGlossaryItem("account_attribute_id", accountAttributeIdExample)
lazy val closingTimeExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("closing_time", closingTimeExample)
@@ -774,145 +776,149 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("last_failure_date", lastFailureDateExample)
lazy val whereExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("where", whereExample)
+ // glossaryItems += makeGlossaryItem("where", whereExample)
lazy val nominalInterest2Example = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("nominal_interest2", nominalInterest2Example)
+ // glossaryItems += makeGlossaryItem("nominal_interest2", nominalInterest2Example)
lazy val statusExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("status", statusExample)
+ // glossaryItems += makeGlossaryItem("status", statusExample)
lazy val transactionStatusExample = ConnectorField(s" ${TransactionRequestStatus.COMPLETED.toString}",s"Status of the transaction, e.g. ${TransactionRequestStatus.COMPLETED.toString}, ${TransactionRequestStatus.PENDING.toString} ..")
- glossaryItems += makeGlossaryItem("status", transactionStatusExample)
+ glossaryItems += makeGlossaryItem("TransactionRequest.status", transactionStatusExample)
lazy val errorCodeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("errorCode", errorCodeExample)
+ // glossaryItems += makeGlossaryItem("errorCode", errorCodeExample)
lazy val textExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("text", textExample)
+ // glossaryItems += makeGlossaryItem("text", textExample)
lazy val canSeeTransactionBalanceExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_BALANCE, canSeeTransactionBalanceExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_BALANCE, canSeeTransactionBalanceExample)
lazy val atmsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("atms", atmsExample)
+ // glossaryItems += makeGlossaryItem("atms", atmsExample)
lazy val overallBalanceDateExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("overall_balance_date", overallBalanceDateExample)
lazy val canDeletePhysicalLocationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_DELETE_PHYSICAL_LOCATION, canDeletePhysicalLocationExample)
+ // glossaryItems += makeGlossaryItem(CAN_DELETE_PHYSICAL_LOCATION, canDeletePhysicalLocationExample)
lazy val canAddWhereTagExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_ADD_WHERE_TAG, canAddWhereTagExample)
+ // glossaryItems += makeGlossaryItem(CAN_ADD_WHERE_TAG, canAddWhereTagExample)
lazy val pinResetExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("pin_reset", pinResetExample)
+ // glossaryItems += makeGlossaryItem("pin_reset", pinResetExample)
lazy val sepaExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("sepa", sepaExample)
+ // glossaryItems += makeGlossaryItem("sepa", sepaExample)
lazy val shortNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("short_name", shortNameExample)
+ // glossaryItems += makeGlossaryItem("short_name", shortNameExample)
lazy val attributeDefinitionIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("attribute_definition_id", attributeDefinitionIdExample)
+ // glossaryItems += makeGlossaryItem("attribute_definition_id", attributeDefinitionIdExample)
lazy val accountRulesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("account_rules", accountRulesExample)
+ // glossaryItems += makeGlossaryItem("account_rules", accountRulesExample)
lazy val transactionsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("transactions", transactionsExample)
+ // glossaryItems += makeGlossaryItem("transactions", transactionsExample)
lazy val channelExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("channel", channelExample)
+ // glossaryItems += makeGlossaryItem("channel", channelExample)
lazy val creatorExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("creator", creatorExample)
+ // glossaryItems += makeGlossaryItem("creator", creatorExample)
lazy val activeExample = ConnectorField(booleanFalse,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("active", activeExample)
lazy val canSeeOtherAccountMetadataExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_METADATA, canSeeOtherAccountMetadataExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_METADATA, canSeeOtherAccountMetadataExample)
lazy val canSeeBankAccountIbanExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_IBAN, canSeeBankAccountIbanExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_IBAN, canSeeBankAccountIbanExample)
lazy val lobbyExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("lobby", lobbyExample)
+ // glossaryItems += makeGlossaryItem("lobby", lobbyExample)
lazy val conversionValueExample = ConnectorField("100",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("conversion_value", conversionValueExample)
lazy val transactionRequestsWithChargesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("transaction_requests_with_charges", transactionRequestsWithChargesExample)
+ // glossaryItems += makeGlossaryItem("transaction_requests_with_charges", transactionRequestsWithChargesExample)
lazy val customerUserIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("customer_user_id", customerUserIdExample)
+ // glossaryItems += makeGlossaryItem("customer_user_id", customerUserIdExample)
lazy val bankCodeExample = ConnectorField("CGHZ",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("bank_code", bankCodeExample)
lazy val averageResponseTimeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("average_response_time", averageResponseTimeExample)
+ // glossaryItems += makeGlossaryItem("average_response_time", averageResponseTimeExample)
lazy val phoneNumberExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("phone_number", phoneNumberExample)
+ // glossaryItems += makeGlossaryItem("phone_number", phoneNumberExample)
lazy val viewsBasicExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("views_basic", viewsBasicExample)
+ // glossaryItems += makeGlossaryItem("views_basic", viewsBasicExample)
lazy val functionNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("function_name", functionNameExample)
+ // glossaryItems += makeGlossaryItem("function_name", functionNameExample)
lazy val canSeeBankRoutingSchemeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ROUTING_SCHEME, canSeeBankRoutingSchemeExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ROUTING_SCHEME, canSeeBankRoutingSchemeExample)
lazy val line1Example = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("line1", line1Example)
+ // glossaryItems += makeGlossaryItem("line1", line1Example)
lazy val fromDateExample = ConnectorField(DateWithMsExampleString,s"The TimeStamp in the format: $DateWithMs")
glossaryItems += makeGlossaryItem("from_date", fromDateExample)
lazy val creditLimitExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("credit_limit", creditLimitExample)
+ // glossaryItems += makeGlossaryItem("credit_limit", creditLimitExample)
lazy val otherBankRoutingAddressExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("other_bank_routing_address", otherBankRoutingAddressExample)
+ // glossaryItems += makeGlossaryItem("other_bank_routing_address", otherBankRoutingAddressExample)
lazy val bankExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("bank", bankExample)
+ // No glossary item: Glossary.scala defines "Bank", and glossary lookups are case insensitive,
+ // so a "bank" field resolves to that rather than to an entry with no description.
+ // glossaryItems += makeGlossaryItem("bank", bankExample)
lazy val counterpartiesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("counterparties", counterpartiesExample)
+ // No glossary item: Glossary.scala defines "Counterparties", and glossary lookups are case insensitive,
+ // so a "counterparties" field resolves to that rather than to an entry with no description.
+ // glossaryItems += makeGlossaryItem("counterparties", counterpartiesExample)
lazy val canSeeMoreInfoExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_MORE_INFO, canSeeMoreInfoExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_MORE_INFO, canSeeMoreInfoExample)
lazy val transactionAttributesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("transaction_attributes", transactionAttributesExample)
+ // glossaryItems += makeGlossaryItem("transaction_attributes", transactionAttributesExample)
lazy val viewsAvailableExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("views_available", viewsAvailableExample)
+ // glossaryItems += makeGlossaryItem("views_available", viewsAvailableExample)
lazy val useExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("use", useExample)
+ // glossaryItems += makeGlossaryItem("use", useExample)
lazy val requestedTemporaryValidEndDateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("requested_temporary_valid_end_date", requestedTemporaryValidEndDateExample)
+ // glossaryItems += makeGlossaryItem("requested_temporary_valid_end_date", requestedTemporaryValidEndDateExample)
lazy val imagesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("images", imagesExample)
+ // glossaryItems += makeGlossaryItem("images", imagesExample)
lazy val canSeeBankAccountBalanceExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_BALANCE, canSeeBankAccountBalanceExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_BALANCE, canSeeBankAccountBalanceExample)
lazy val parametersExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("parameters", parametersExample)
+ // glossaryItems += makeGlossaryItem("parameters", parametersExample)
lazy val canAddTransactionRequestToAnyAccountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_ADD_TRANSACTION_REQUEST_TO_ANY_ACCOUNT, canAddTransactionRequestToAnyAccountExample)
+ // glossaryItems += makeGlossaryItem(CAN_ADD_TRANSACTION_REQUEST_TO_ANY_ACCOUNT, canAddTransactionRequestToAnyAccountExample)
lazy val websiteExample = ConnectorField("www.openbankproject.com",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("website", websiteExample)
@@ -1004,43 +1010,43 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("ATM.minimum_withdrawal", atmMinimumWithdrawalExample)
lazy val atmBranchIdentificationExample = ConnectorField(NoExampleProvided, NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("ATM.branch_identification", atmBranchIdentificationExample)
+ // glossaryItems += makeGlossaryItem("ATM.branch_identification", atmBranchIdentificationExample)
lazy val siteIdentification = ConnectorField(NoExampleProvided, NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("ATM.site_identification", siteIdentification)
+ // glossaryItems += makeGlossaryItem("ATM.site_identification", siteIdentification)
lazy val atmSiteNameExample = ConnectorField(NoExampleProvided, NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("ATM.site_name", atmSiteNameExample)
+ // glossaryItems += makeGlossaryItem("ATM.site_name", atmSiteNameExample)
lazy val cashWithdrawalNationalFeeExample = ConnectorField(NoExampleProvided, NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("ATM.cash_withdrawal_national_fee", cashWithdrawalNationalFeeExample)
+ // glossaryItems += makeGlossaryItem("ATM.cash_withdrawal_national_fee", cashWithdrawalNationalFeeExample)
lazy val cashWithdrawalInternationalFeeExample: ConnectorField = ConnectorField(NoExampleProvided, NoDescriptionProvided)
glossaryItems += makeGlossaryItem("ATM.cash_withdrawal_international_fee", cashWithdrawalInternationalFeeExample)
lazy val balanceInquiryFeeExample = ConnectorField(NoExampleProvided, NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("ATM.balance_inquiry_fee", balanceInquiryFeeExample)
+ // glossaryItems += makeGlossaryItem("ATM.balance_inquiry_fee", balanceInquiryFeeExample)
lazy val atmTypeExample = ConnectorField(NoExampleProvided, NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("ATM.atm_type", atmTypeExample)
+ // glossaryItems += makeGlossaryItem("ATM.atm_type", atmTypeExample)
lazy val accessibilityFeaturesExample = ConnectorField("""["ATAC","ATAD"]""", NoDescriptionProvided)
glossaryItems += makeGlossaryItem("accessibility_features", accessibilityFeaturesExample)
lazy val canSeeOtherBankRoutingSchemeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_BANK_ROUTING_SCHEME, canSeeOtherBankRoutingSchemeExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_BANK_ROUTING_SCHEME, canSeeOtherBankRoutingSchemeExample)
lazy val physicalLocationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("physical_location", physicalLocationExample)
+ // glossaryItems += makeGlossaryItem("physical_location", physicalLocationExample)
lazy val canSeeBankAccountRoutingSchemeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_ROUTING_SCHEME, canSeeBankAccountRoutingSchemeExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_ROUTING_SCHEME, canSeeBankAccountRoutingSchemeExample)
lazy val rankAmount2Example = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("rank_amount2", rankAmount2Example)
+ // glossaryItems += makeGlossaryItem("rank_amount2", rankAmount2Example)
lazy val relatesToKycCheckIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("relates_to_kyc_check_id", relatesToKycCheckIdExample)
+ // glossaryItems += makeGlossaryItem("relates_to_kyc_check_id", relatesToKycCheckIdExample)
lazy val productIdExample = ConnectorField("product-id-example-uuid", "The UUID of the product")
glossaryItems += makeGlossaryItem("product_id", productIdExample)
@@ -1049,76 +1055,78 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("product_code", productCodeExample)
lazy val imageUrlExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("image_url", imageUrlExample)
+ // glossaryItems += makeGlossaryItem("image_url", imageUrlExample)
lazy val canSeeTransactionMetadataExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_METADATA, canSeeTransactionMetadataExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_METADATA, canSeeTransactionMetadataExample)
lazy val documentsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("documents", documentsExample)
+ // glossaryItems += makeGlossaryItem("documents", documentsExample)
lazy val relatesToKycDocumentIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("relates_to_kyc_document_id", relatesToKycDocumentIdExample)
+ // glossaryItems += makeGlossaryItem("relates_to_kyc_document_id", relatesToKycDocumentIdExample)
lazy val hostedAtExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("hosted_at", hostedAtExample)
+ // glossaryItems += makeGlossaryItem("hosted_at", hostedAtExample)
lazy val holderExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("holder", holderExample)
+ // glossaryItems += makeGlossaryItem("holder", holderExample)
lazy val kindExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("kind", kindExample)
+ // glossaryItems += makeGlossaryItem("kind", kindExample)
lazy val shortCodeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("short_code", shortCodeExample)
+ // glossaryItems += makeGlossaryItem("short_code", shortCodeExample)
lazy val driveupExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("driveup", driveupExample)
+ // glossaryItems += makeGlossaryItem("driveup", driveupExample)
lazy val keysExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("keys", keysExample)
+ // glossaryItems += makeGlossaryItem("keys", keysExample)
lazy val otherAccountsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("other_accounts", otherAccountsExample)
+ // glossaryItems += makeGlossaryItem("other_accounts", otherAccountsExample)
lazy val canSeeTransactionFinishDateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_FINISH_DATE, canSeeTransactionFinishDateExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_FINISH_DATE, canSeeTransactionFinishDateExample)
lazy val satisfiedExample = ConnectorField(booleanFalse,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("satisfied", satisfiedExample)
lazy val canSeeOtherAccountIbanExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_IBAN, canSeeOtherAccountIbanExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_IBAN, canSeeOtherAccountIbanExample)
lazy val attributeIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("attribute_id", attributeIdExample)
+ // glossaryItems += makeGlossaryItem("attribute_id", attributeIdExample)
lazy val accountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("account", accountExample)
+ // No glossary item: Glossary.scala defines "Account", and glossary lookups are case insensitive,
+ // so a "account" field resolves to that rather than to an entry with no description.
+ // glossaryItems += makeGlossaryItem("account", accountExample)
lazy val idExample = ConnectorField("d8839721-ad8f-45dd-9f78-2080414b93f9",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("id", idExample)
lazy val canAddCorporateLocationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_ADD_CORPORATE_LOCATION, canAddCorporateLocationExample)
+ // glossaryItems += makeGlossaryItem(CAN_ADD_CORPORATE_LOCATION, canAddCorporateLocationExample)
lazy val crmEventsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("crm_events", crmEventsExample)
+ // glossaryItems += makeGlossaryItem("crm_events", crmEventsExample)
lazy val shortReferenceExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("short_reference", shortReferenceExample)
+ // glossaryItems += makeGlossaryItem("short_reference", shortReferenceExample)
lazy val requiresBankIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("requires_bank_id", requiresBankIdExample)
+ // glossaryItems += makeGlossaryItem("requires_bank_id", requiresBankIdExample)
lazy val numberExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("number", numberExample)
+ // glossaryItems += makeGlossaryItem("number", numberExample)
lazy val cityExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("city", cityExample)
+ // glossaryItems += makeGlossaryItem("city", cityExample)
lazy val toTransferToAtmExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("to_transfer_to_atm", toTransferToAtmExample)
+ // glossaryItems += makeGlossaryItem("to_transfer_to_atm", toTransferToAtmExample)
lazy val jwtExample = ConnectorField("eyJhbGciOiJIUzI1NiJ9.eyJlbnRpdGxlbWVudHMiOltdLCJjcmVhdGVkQnlVc2VySWQiOiJhYjY1Mz" +
"lhOS1iMTA1LTQ0ODktYTg4My0wYWQ4ZDZjNjE2NTciLCJzdWIiOiIyMWUxYzhjYy1mOTE4LTRlYWMtYjhlMy01ZTVlZWM2YjNiNGIiLCJhdWQiOiJ" +
@@ -1130,19 +1138,19 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("jwt", jwtExample)
lazy val requestedCurrentValidEndDateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("requested_current_valid_end_date", requestedCurrentValidEndDateExample)
+ // glossaryItems += makeGlossaryItem("requested_current_valid_end_date", requestedCurrentValidEndDateExample)
lazy val canSeeOtherBankRoutingAddressExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_BANK_ROUTING_ADDRESS, canSeeOtherBankRoutingAddressExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_BANK_ROUTING_ADDRESS, canSeeOtherBankRoutingAddressExample)
lazy val thursdayExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("thursday", thursdayExample)
+ // glossaryItems += makeGlossaryItem("thursday", thursdayExample)
lazy val userAuthContextsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("user_auth_contexts", userAuthContextsExample)
+ // glossaryItems += makeGlossaryItem("user_auth_contexts", userAuthContextsExample)
lazy val phoneExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("phone", phoneExample)
+ // glossaryItems += makeGlossaryItem("phone", phoneExample)
lazy val sepaCreditTransferExample = ConnectorField("yes","no-description-provided")
glossaryItems += makeGlossaryItem("sepaCreditTransfer", sepaCreditTransferExample)
@@ -1163,10 +1171,10 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("sepaDirectDebit", sepaDirectDebitExample)
lazy val canSeeTransactionOtherBankAccountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_OTHER_BANK_ACCOUNT, canSeeTransactionOtherBankAccountExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_OTHER_BANK_ACCOUNT, canSeeTransactionOtherBankAccountExample)
lazy val itemsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("items", itemsExample)
+ // glossaryItems += makeGlossaryItem("items", itemsExample)
lazy val toDateExample = ConnectorField(DateWithMsExampleString,s"The TimeStamp in the format: $DateWithMs")
glossaryItems += makeGlossaryItem("to_date", toDateExample)
@@ -1175,167 +1183,169 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("bank_routings", bankRoutingsExample)
lazy val canSeeOpenCorporatesUrlExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_OPEN_CORPORATES_URL, canSeeOpenCorporatesUrlExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_OPEN_CORPORATES_URL, canSeeOpenCorporatesUrlExample)
lazy val branchesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("branches", branchesExample)
+ // glossaryItems += makeGlossaryItem("branches", branchesExample)
lazy val overallBalanceExample = ConnectorField("10",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("overall_balance", overallBalanceExample)
lazy val ttlInSecondsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("ttl_in_seconds", ttlInSecondsExample)
+ // glossaryItems += makeGlossaryItem("ttl_in_seconds", ttlInSecondsExample)
lazy val authContextUpdateIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("auth_context_update_id", authContextUpdateIdExample)
+ // glossaryItems += makeGlossaryItem("auth_context_update_id", authContextUpdateIdExample)
lazy val scopeIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("scope_id", scopeIdExample)
+ // glossaryItems += makeGlossaryItem("scope_id", scopeIdExample)
lazy val organisationWebsiteExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("organisation_website", organisationWebsiteExample)
+ // glossaryItems += makeGlossaryItem("organisation_website", organisationWebsiteExample)
lazy val howExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("how", howExample)
+ // glossaryItems += makeGlossaryItem("how", howExample)
lazy val holdersExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("holders", holdersExample)
+ // glossaryItems += makeGlossaryItem("holders", holdersExample)
lazy val consumersExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("consumers", consumersExample)
+ // glossaryItems += makeGlossaryItem("consumers", consumersExample)
lazy val nicknameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("nickname", nicknameExample)
+ // glossaryItems += makeGlossaryItem("nickname", nicknameExample)
lazy val mediasExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("medias", mediasExample)
+ // glossaryItems += makeGlossaryItem("medias", mediasExample)
lazy val perMonthCallLimitExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("per_month_call_limit", perMonthCallLimitExample)
+ // glossaryItems += makeGlossaryItem("per_month_call_limit", perMonthCallLimitExample)
lazy val rolesExample = ConnectorField("CanCreateMyUser","Entitlements are used to grant System or Bank level roles to Users ")
glossaryItems += makeGlossaryItem("roles", rolesExample)
lazy val categoryExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("category", categoryExample)
+ // glossaryItems += makeGlossaryItem("category", categoryExample)
lazy val onHotListExample = ConnectorField("false",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("on_hot_list", onHotListExample)
lazy val temporaryCreditDocumentationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("temporary_credit_documentation", temporaryCreditDocumentationExample)
+ // glossaryItems += makeGlossaryItem("temporary_credit_documentation", temporaryCreditDocumentationExample)
lazy val locationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("location", locationExample)
+ // glossaryItems += makeGlossaryItem("location", locationExample)
lazy val otherBankRoutingSchemeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("other_bank_routing_scheme", otherBankRoutingSchemeExample)
+ // glossaryItems += makeGlossaryItem("other_bank_routing_scheme", otherBankRoutingSchemeExample)
lazy val groupExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("group", groupExample)
+ // glossaryItems += makeGlossaryItem("group", groupExample)
lazy val taxResidenceIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("tax_residence_id", taxResidenceIdExample)
+ // glossaryItems += makeGlossaryItem("tax_residence_id", taxResidenceIdExample)
lazy val accountAttributesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("account_attributes", accountAttributesExample)
+ // glossaryItems += makeGlossaryItem("account_attributes", accountAttributesExample)
lazy val listExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("list", listExample)
+ // glossaryItems += makeGlossaryItem("list", listExample)
lazy val branchNumberExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("branch_number", branchNumberExample)
+ // glossaryItems += makeGlossaryItem("branch_number", branchNumberExample)
lazy val accountsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("accounts", accountsExample)
+ // glossaryItems += makeGlossaryItem("accounts", accountsExample)
lazy val consentsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("consents", consentsExample)
+ // glossaryItems += makeGlossaryItem("consents", consentsExample)
lazy val entitlementsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("entitlements", entitlementsExample)
+ // glossaryItems += makeGlossaryItem("entitlements", entitlementsExample)
lazy val commentIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("comment_id", commentIdExample)
+ // glossaryItems += makeGlossaryItem("comment_id", commentIdExample)
lazy val canSeeBankAccountNationalIdentifierExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_NATIONAL_IDENTIFIER, canSeeBankAccountNationalIdentifierExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_NATIONAL_IDENTIFIER, canSeeBankAccountNationalIdentifierExample)
lazy val perMinuteExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("per_minute", perMinuteExample)
+ // glossaryItems += makeGlossaryItem("per_minute", perMinuteExample)
lazy val resultExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("result", resultExample)
+ // glossaryItems += makeGlossaryItem("result", resultExample)
lazy val entitlementRequestIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("entitlement_request_id", entitlementRequestIdExample)
+ // glossaryItems += makeGlossaryItem("entitlement_request_id", entitlementRequestIdExample)
lazy val minimumResponseTimeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("minimum_response_time", minimumResponseTimeExample)
+ // glossaryItems += makeGlossaryItem("minimum_response_time", minimumResponseTimeExample)
lazy val locatedAtExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("ATM.located_at", locatedAtExample)
+ // glossaryItems += makeGlossaryItem("ATM.located_at", locatedAtExample)
lazy val requireScopesForAllRolesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("require_scopes_for_all_roles", requireScopesForAllRolesExample)
+ // glossaryItems += makeGlossaryItem("require_scopes_for_all_roles", requireScopesForAllRolesExample)
lazy val creditRatingExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("credit_rating", creditRatingExample)
+ // glossaryItems += makeGlossaryItem("credit_rating", creditRatingExample)
lazy val firstCheckNumberExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("first_check_number", firstCheckNumberExample)
+ // glossaryItems += makeGlossaryItem("first_check_number", firstCheckNumberExample)
lazy val addressesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("addresses", addressesExample)
+ // glossaryItems += makeGlossaryItem("addresses", addressesExample)
lazy val thisViewIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("this_view_id", thisViewIdExample)
+ // glossaryItems += makeGlossaryItem("this_view_id", thisViewIdExample)
lazy val canSeeTransactionCurrencyExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_CURRENCY, canSeeTransactionCurrencyExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_CURRENCY, canSeeTransactionCurrencyExample)
lazy val accountOtpExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("account_otp", accountOtpExample)
+ // glossaryItems += makeGlossaryItem("account_otp", accountOtpExample)
lazy val hideMetadataIfAliasUsedExample = ConnectorField(booleanFalse, NoDescriptionProvided)
glossaryItems += makeGlossaryItem("hide_metadata_if_alias_used", hideMetadataIfAliasUsedExample)
lazy val canSeeBankAccountCurrencyExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_CURRENCY, canSeeBankAccountCurrencyExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_CURRENCY, canSeeBankAccountCurrencyExample)
lazy val generateAuditorsViewExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("generate_auditors_view", generateAuditorsViewExample)
+ // glossaryItems += makeGlossaryItem("generate_auditors_view", generateAuditorsViewExample)
lazy val longitudeExample = ConnectorField("-77.0364",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("longitude", longitudeExample)
lazy val familyExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("family", familyExample)
+ // glossaryItems += makeGlossaryItem("family", familyExample)
lazy val reasonsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("reasons", reasonsExample)
+ // glossaryItems += makeGlossaryItem("reasons", reasonsExample)
lazy val replacementExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("replacement", replacementExample)
+ // glossaryItems += makeGlossaryItem("replacement", replacementExample)
lazy val customerExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("customer", customerExample)
+ // No glossary item: Glossary.scala defines "Customer", and glossary lookups are case insensitive,
+ // so a "customer" field resolves to that rather than to an entry with no description.
+ // glossaryItems += makeGlossaryItem("customer", customerExample)
lazy val nominalInterest1Example = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("nominal_interest1", nominalInterest1Example)
+ // glossaryItems += makeGlossaryItem("nominal_interest1", nominalInterest1Example)
lazy val memberProductCodeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("member_product_code", memberProductCodeExample)
+ // glossaryItems += makeGlossaryItem("member_product_code", memberProductCodeExample)
lazy val scaMethodExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("sca_method", scaMethodExample)
+ // glossaryItems += makeGlossaryItem("sca_method", scaMethodExample)
lazy val accountWebhookIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("account_webhook_id", accountWebhookIdExample)
+ // glossaryItems += makeGlossaryItem("account_webhook_id", accountWebhookIdExample)
lazy val customerMessageId = ConnectorField("5995d6a2-01b3-423c-a173-5481df49bdaf",
"A string that, in combination with the bankId MUST uniquely identify the customer message on this OBP instance")
- glossaryItems += makeGlossaryItem("id", customerMessageId)
+ glossaryItems += makeGlossaryItem("CustomerMessage.id", customerMessageId)
lazy val messageExample = ConnectorField("123456","The messsage content to send to customer.")
glossaryItems += makeGlossaryItem("message", messageExample)
@@ -1350,175 +1360,175 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("from_person", fromPersonExample)
lazy val canSeePrivateAliasExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_PRIVATE_ALIAS, canSeePrivateAliasExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_PRIVATE_ALIAS, canSeePrivateAliasExample)
lazy val typeOfLockExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("type_of_lock", typeOfLockExample)
+ // glossaryItems += makeGlossaryItem("type_of_lock", typeOfLockExample)
lazy val canSeeOtherAccountKindExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_KIND, canSeeOtherAccountKindExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_KIND, canSeeOtherAccountKindExample)
lazy val canAddOpenCorporatesUrlExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_ADD_OPEN_CORPORATES_URL, canAddOpenCorporatesUrlExample)
+ // glossaryItems += makeGlossaryItem(CAN_ADD_OPEN_CORPORATES_URL, canAddOpenCorporatesUrlExample)
lazy val metadataViewExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("metadata_view", metadataViewExample)
+ // glossaryItems += makeGlossaryItem("metadata_view", metadataViewExample)
lazy val aliasExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("alias", aliasExample)
+ // glossaryItems += makeGlossaryItem("alias", aliasExample)
lazy val canSeeTransactionThisBankAccountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_THIS_BANK_ACCOUNT, canSeeTransactionThisBankAccountExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_THIS_BANK_ACCOUNT, canSeeTransactionThisBankAccountExample)
lazy val triggerNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("trigger_name", triggerNameExample)
+ // glossaryItems += makeGlossaryItem("trigger_name", triggerNameExample)
lazy val otherAccountIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("other_account_id", otherAccountIdExample)
+ // glossaryItems += makeGlossaryItem("other_account_id", otherAccountIdExample)
lazy val resetInSecondsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("reset_in_seconds", resetInSecondsExample)
+ // glossaryItems += makeGlossaryItem("reset_in_seconds", resetInSecondsExample)
lazy val answerExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("answer", answerExample)
+ // glossaryItems += makeGlossaryItem("answer", answerExample)
lazy val executionTimeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("execution_time", executionTimeExample)
+ // glossaryItems += makeGlossaryItem("execution_time", executionTimeExample)
lazy val timeToLiveExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("time_to_live", timeToLiveExample)
+ // glossaryItems += makeGlossaryItem("time_to_live", timeToLiveExample)
lazy val akkaExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("akka", akkaExample)
+ // glossaryItems += makeGlossaryItem("akka", akkaExample)
lazy val meetingIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("meeting_id", meetingIdExample)
+ // glossaryItems += makeGlossaryItem("meeting_id", meetingIdExample)
lazy val tagIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("tag_id", tagIdExample)
+ // glossaryItems += makeGlossaryItem("tag_id", tagIdExample)
lazy val addressExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("address", addressExample)
+ // glossaryItems += makeGlossaryItem("address", addressExample)
lazy val canAddPrivateAliasExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_ADD_PRIVATE_ALIAS, canAddPrivateAliasExample)
+ // glossaryItems += makeGlossaryItem(CAN_ADD_PRIVATE_ALIAS, canAddPrivateAliasExample)
lazy val postcodeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("postcode", postcodeExample)
+ // glossaryItems += makeGlossaryItem("postcode", postcodeExample)
lazy val fromCurrencyCodeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("from_currency_code", fromCurrencyCodeExample)
+ // glossaryItems += makeGlossaryItem("from_currency_code", fromCurrencyCodeExample)
lazy val wednesdayExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("wednesday", wednesdayExample)
+ // glossaryItems += makeGlossaryItem("wednesday", wednesdayExample)
lazy val lastOkDateExample = ConnectorField(formatDate(oneYearAgoDate),NoDescriptionProvided)
glossaryItems += makeGlossaryItem("last_ok_date", lastOkDateExample)
lazy val transactionTypesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("transaction_types", transactionTypesExample)
+ // glossaryItems += makeGlossaryItem("transaction_types", transactionTypesExample)
lazy val resetPasswordUrlExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("reset_password_url", resetPasswordUrlExample)
+ // glossaryItems += makeGlossaryItem("reset_password_url", resetPasswordUrlExample)
lazy val canSeeBankAccountSwiftBicExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_SWIFT_BIC, canSeeBankAccountSwiftBicExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_SWIFT_BIC, canSeeBankAccountSwiftBicExample)
lazy val jsonstringExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("jsonstring", jsonstringExample)
+ // glossaryItems += makeGlossaryItem("jsonstring", jsonstringExample)
lazy val inviteesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("invitees", inviteesExample)
+ // glossaryItems += makeGlossaryItem("invitees", inviteesExample)
lazy val appTypeExample = ConnectorField("Web",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("app_type", appTypeExample)
lazy val productAttributeIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("product_attribute_id", productAttributeIdExample)
+ // glossaryItems += makeGlossaryItem("product_attribute_id", productAttributeIdExample)
lazy val isSystemExample = ConnectorField("true", "If the view is the system level, then it is true")
glossaryItems += makeGlossaryItem("view.is_system", isSystemExample)
lazy val detailsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("details", detailsExample)
+ // glossaryItems += makeGlossaryItem("details", detailsExample)
lazy val canSeeOwnerCommentExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_OWNER_COMMENT, canSeeOwnerCommentExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_OWNER_COMMENT, canSeeOwnerCommentExample)
lazy val canSeeTagsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_TAGS, canSeeTagsExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_TAGS, canSeeTagsExample)
lazy val moreInfoUrlExample = ConnectorField("www.example.com/abc",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("more_info_url", moreInfoUrlExample)
lazy val kycMediaIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("kyc_media_id", kycMediaIdExample)
+ // glossaryItems += makeGlossaryItem("kyc_media_id", kycMediaIdExample)
lazy val outboundavroschemaExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("outboundavroschema", outboundavroschemaExample)
+ // glossaryItems += makeGlossaryItem("outboundavroschema", outboundavroschemaExample)
lazy val isAliasExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("is_alias", isAliasExample)
+ // glossaryItems += makeGlossaryItem("is_alias", isAliasExample)
lazy val roleNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("role_name", roleNameExample)
+ // glossaryItems += makeGlossaryItem("role_name", roleNameExample)
lazy val termsAndConditionsUrlExample = ConnectorField("www.example.com/xyz",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("terms_and_conditions_url_example", termsAndConditionsUrlExample)
lazy val canAddUrlExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_ADD_URL, canAddUrlExample)
+ // glossaryItems += makeGlossaryItem(CAN_ADD_URL, canAddUrlExample)
lazy val viewExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("view", viewExample)
+ // glossaryItems += makeGlossaryItem("view", viewExample)
lazy val displayNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("display_name", displayNameExample)
+ // glossaryItems += makeGlossaryItem("display_name", displayNameExample)
lazy val canDeleteTagExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_DELETE_TAG, canDeleteTagExample)
+ // glossaryItems += makeGlossaryItem(CAN_DELETE_TAG, canDeleteTagExample)
lazy val hoursExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("hours", hoursExample)
+ // glossaryItems += makeGlossaryItem("hours", hoursExample)
lazy val customerAttributesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("customer_attributes", customerAttributesExample)
+ // glossaryItems += makeGlossaryItem("customer_attributes", customerAttributesExample)
lazy val perHourCallLimitExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("per_hour_call_limit", perHourCallLimitExample)
+ // glossaryItems += makeGlossaryItem("per_hour_call_limit", perHourCallLimitExample)
lazy val distributionChannelExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("distribution_channel", distributionChannelExample)
+ // glossaryItems += makeGlossaryItem("distribution_channel", distributionChannelExample)
lazy val otherAccountRoutingSchemeExample = ConnectorField("IBAN","otherAccountRoutingScheme string, eg: IBAN")
glossaryItems += makeGlossaryItem("other_account_routing_scheme", otherAccountRoutingSchemeExample)
lazy val generateAccountantsViewExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("generate_accountants_view", generateAccountantsViewExample)
+ // glossaryItems += makeGlossaryItem("generate_accountants_view", generateAccountantsViewExample)
lazy val counterpartyExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("counterparty", counterpartyExample)
+ // glossaryItems += makeGlossaryItem("counterparty", counterpartyExample)
lazy val tagsExample = ConnectorField("Create-My-User","OBP uses the tags to group the endpoints, the relevant endpoints can share the same tag. ")
glossaryItems += makeGlossaryItem("tags", tagsExample)
lazy val perHourExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("per_hour", perHourExample)
+ // glossaryItems += makeGlossaryItem("per_hour", perHourExample)
lazy val cardDescriptionExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("card_description", cardDescriptionExample)
+ // glossaryItems += makeGlossaryItem("card_description", cardDescriptionExample)
lazy val moreInfoExample = ConnectorField("More information about this fee",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("more_info", moreInfoExample)
lazy val fieldExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("field", fieldExample)
+ // glossaryItems += makeGlossaryItem("field", fieldExample)
lazy val creditornameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("creditorname", creditornameExample)
+ // glossaryItems += makeGlossaryItem("creditorname", creditornameExample)
lazy val dateActivatedExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("date_activated", dateActivatedExample)
+ // glossaryItems += makeGlossaryItem("date_activated", dateActivatedExample)
lazy val webuiPropsExample = ConnectorField(
"webui_api_explorer_url",
@@ -1545,85 +1555,85 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("webui_props", webuiPropsExample)
lazy val userCustomerLinksExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("user_customer_links", userCustomerLinksExample)
+ // glossaryItems += makeGlossaryItem("user_customer_links", userCustomerLinksExample)
lazy val inboundavroschemaExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("inboundavroschema", inboundavroschemaExample)
+ // glossaryItems += makeGlossaryItem("inboundavroschema", inboundavroschemaExample)
lazy val matchAllExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("match_all", matchAllExample)
+ // glossaryItems += makeGlossaryItem("match_all", matchAllExample)
lazy val chargeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("charge", chargeExample)
+ // glossaryItems += makeGlossaryItem("charge", chargeExample)
lazy val kycDocumentIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("kyc_document_id", kycDocumentIdExample)
+ // glossaryItems += makeGlossaryItem("kyc_document_id", kycDocumentIdExample)
lazy val canSeePublicAliasExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_PUBLIC_ALIAS, canSeePublicAliasExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_PUBLIC_ALIAS, canSeePublicAliasExample)
lazy val webUiPropsIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("web_ui_props_id", webUiPropsIdExample)
+ // glossaryItems += makeGlossaryItem("web_ui_props_id", webUiPropsIdExample)
lazy val providerExample = ConnectorField("ETHEREUM","the provider name ")
glossaryItems += makeGlossaryItem("provider", providerExample)
lazy val canSeePhysicalLocationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_PHYSICAL_LOCATION, canSeePhysicalLocationExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_PHYSICAL_LOCATION, canSeePhysicalLocationExample)
lazy val accountRoutingsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("account_routings", accountRoutingsExample)
+ // glossaryItems += makeGlossaryItem("account_routings", accountRoutingsExample)
lazy val purposeIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("purpose_id", purposeIdExample)
+ // glossaryItems += makeGlossaryItem("purpose_id", purposeIdExample)
lazy val perDayCallLimitExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("per_day_call_limit", perDayCallLimitExample)
+ // glossaryItems += makeGlossaryItem("per_day_call_limit", perDayCallLimitExample)
lazy val kycCheckIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("kyc_check_id", kycCheckIdExample)
+ // glossaryItems += makeGlossaryItem("kyc_check_id", kycCheckIdExample)
lazy val perWeekCallLimitExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("per_week_call_limit", perWeekCallLimitExample)
+ // glossaryItems += makeGlossaryItem("per_week_call_limit", perWeekCallLimitExample)
lazy val bankIdPatternExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("bank_id_pattern", bankIdPatternExample)
+ // glossaryItems += makeGlossaryItem("bank_id_pattern", bankIdPatternExample)
lazy val cardAttributesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("card_attributes", cardAttributesExample)
+ // glossaryItems += makeGlossaryItem("card_attributes", cardAttributesExample)
lazy val verbExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("verb", verbExample)
+ // glossaryItems += makeGlossaryItem("verb", verbExample)
lazy val freeFormExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("free_form", freeFormExample)
+ // glossaryItems += makeGlossaryItem("free_form", freeFormExample)
lazy val transferTypeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("transfer_type", transferTypeExample)
+ // glossaryItems += makeGlossaryItem("transfer_type", transferTypeExample)
lazy val challengeTypeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("challenge_type", challengeTypeExample)
+ // glossaryItems += makeGlossaryItem("challenge_type", challengeTypeExample)
lazy val messageDocsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("message_docs", messageDocsExample)
+ // glossaryItems += makeGlossaryItem("message_docs", messageDocsExample)
lazy val licenseExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("license", licenseExample)
+ // glossaryItems += makeGlossaryItem("license", licenseExample)
lazy val requestIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("request_id", requestIdExample)
+ // glossaryItems += makeGlossaryItem("request_id", requestIdExample)
lazy val userAuthContextIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("user_auth_context_id", userAuthContextIdExample)
+ // glossaryItems += makeGlossaryItem("user_auth_context_id", userAuthContextIdExample)
lazy val perMinuteCallLimitExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("per_minute_call_limit", perMinuteCallLimitExample)
+ // glossaryItems += makeGlossaryItem("per_minute_call_limit", perMinuteCallLimitExample)
lazy val countyExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("county", countyExample)
+ // glossaryItems += makeGlossaryItem("county", countyExample)
lazy val publicAliasExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("public_alias", publicAliasExample)
+ // glossaryItems += makeGlossaryItem("public_alias", publicAliasExample)
lazy val parentProductCodeExample = ConnectorField("787LOW",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("parent_product_code", parentProductCodeExample)
@@ -1632,10 +1642,10 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("product_name", productNameExample)
lazy val numberOfCheckbooksExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("number_of_checkbooks", numberOfCheckbooksExample)
+ // glossaryItems += makeGlossaryItem("number_of_checkbooks", numberOfCheckbooksExample)
lazy val directDebitIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("direct_debit_id", directDebitIdExample)
+ // glossaryItems += makeGlossaryItem("direct_debit_id", directDebitIdExample)
lazy val consentReferenceIdExample = ConnectorField("fd13b9af-4f74-4d52-a7f1-7c2c12f3aa11" ,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("consent_reference_id", consentReferenceIdExample)
@@ -1644,7 +1654,7 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("consent_id", consentIdExample)
lazy val basketIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("basket_id", basketIdExample)
+ // glossaryItems += makeGlossaryItem("basket_id", basketIdExample)
lazy val consentRequestPayloadExample = ConnectorField(
s"""{
@@ -1721,13 +1731,13 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("consent_request_id", consentRequestIdExample)
lazy val line2Example = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("line2", line2Example)
+ // glossaryItems += makeGlossaryItem("line2", line2Example)
lazy val everythingExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("everything", everythingExample)
+ // glossaryItems += makeGlossaryItem("everything", everythingExample)
lazy val networksExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("networks", networksExample)
+ // glossaryItems += makeGlossaryItem("networks", networksExample)
lazy val allowsExample = ConnectorField(List(CardAction.CREDIT.toString.toLowerCase,CardAction.DEBIT.toString.toLowerCase,CardAction.CASH_WITHDRAWAL.toString.toLowerCase).mkString("[",",","]"), "The actions of the card.")
glossaryItems += makeGlossaryItem("allows", allowsExample)
@@ -1736,139 +1746,139 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("data.bankid", `data.bankIdExample` )
lazy val customerNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("customer_name", customerNameExample)
+ // glossaryItems += makeGlossaryItem("customer_name", customerNameExample)
lazy val fridayExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("friday", fridayExample)
+ // glossaryItems += makeGlossaryItem("friday", fridayExample)
lazy val productCollectionExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("product_collection", productCollectionExample)
+ // glossaryItems += makeGlossaryItem("product_collection", productCollectionExample)
lazy val methodNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("method_name", methodNameExample)
+ // glossaryItems += makeGlossaryItem("method_name", methodNameExample)
lazy val staffTokenExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("staff_token", staffTokenExample)
+ // glossaryItems += makeGlossaryItem("staff_token", staffTokenExample)
lazy val dateAddedExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("date_added", dateAddedExample)
+ // glossaryItems += makeGlossaryItem("date_added", dateAddedExample)
lazy val connectorVersionExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("connector_version", connectorVersionExample)
+ // glossaryItems += makeGlossaryItem("connector_version", connectorVersionExample)
lazy val accountApplicationsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("account_applications", accountApplicationsExample)
+ // glossaryItems += makeGlossaryItem("account_applications", accountApplicationsExample)
lazy val endDateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("end_date", endDateExample)
+ // glossaryItems += makeGlossaryItem("end_date", endDateExample)
- lazy val canAddTransactionRequestToOwnAccountExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canAddTransactionRequestToOwnAccountExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can create a Transaction Request from the Account to another account held by the same User.")
glossaryItems += makeGlossaryItem("can_add_transaction_request_to_own_account", canAddTransactionRequestToOwnAccountExample)
lazy val otherAccountRoutingAddressExample = ConnectorField("DE89370400440532013000","OtherBankRoutingAddress string, eg IBAN value")
glossaryItems += makeGlossaryItem("other_account_routing_address", otherAccountRoutingAddressExample)
lazy val isFirehoseExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("is_firehose", isFirehoseExample)
+ // glossaryItems += makeGlossaryItem("is_firehose", isFirehoseExample)
lazy val okExample = ConnectorField(booleanFalse,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("ok", okExample)
lazy val bankRoutingExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("bank_routing", bankRoutingExample)
+ // glossaryItems += makeGlossaryItem("bank_routing", bankRoutingExample)
lazy val shippingCodeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("shipping_code", shippingCodeExample)
+ // glossaryItems += makeGlossaryItem("shipping_code", shippingCodeExample)
lazy val line3Example = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("line3", line3Example)
+ // glossaryItems += makeGlossaryItem("line3", line3Example)
lazy val swiftBicExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("swift_bic", swiftBicExample)
+ // glossaryItems += makeGlossaryItem("swift_bic", swiftBicExample)
lazy val debtoraccountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("debtoraccount", debtoraccountExample)
+ // glossaryItems += makeGlossaryItem("debtoraccount", debtoraccountExample)
lazy val latitudeExample = ConnectorField("38.8951",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("latitude", latitudeExample)
lazy val dependentEndpointsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("dependent_endpoints", dependentEndpointsExample)
+ // glossaryItems += makeGlossaryItem("dependent_endpoints", dependentEndpointsExample)
lazy val hasDepositCapabilityExample = ConnectorField(booleanFalse,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("ATM.has_deposit_capability", hasDepositCapabilityExample)
lazy val toCounterpartyExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("to_counterparty", toCounterpartyExample)
+ // glossaryItems += makeGlossaryItem("to_counterparty", toCounterpartyExample)
lazy val dateInsertedExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("date_inserted", dateInsertedExample)
+ // glossaryItems += makeGlossaryItem("date_inserted", dateInsertedExample)
lazy val schemeExample = ConnectorField("OBP",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("scheme", schemeExample)
lazy val customerAddressIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("customer_address_id", customerAddressIdExample)
+ // glossaryItems += makeGlossaryItem("customer_address_id", customerAddressIdExample)
lazy val generatePublicViewExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("generate_public_view", generatePublicViewExample)
+ // glossaryItems += makeGlossaryItem("generate_public_view", generatePublicViewExample)
lazy val canSeeBankAccountRoutingAddressExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("can_see_bank_account_routing_address", canSeeBankAccountRoutingAddressExample)
+ // glossaryItems += makeGlossaryItem("can_see_bank_account_routing_address", canSeeBankAccountRoutingAddressExample)
lazy val canSeeCommentsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("can_see_comments", canSeeCommentsExample)
+ // glossaryItems += makeGlossaryItem("can_see_comments", canSeeCommentsExample)
- lazy val canEditOwnerCommentExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canEditOwnerCommentExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can edit the owner comment on a Transaction.")
glossaryItems += makeGlossaryItem("can_edit_owner_comment", canEditOwnerCommentExample)
- lazy val canAddCounterpartyExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canAddCounterpartyExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can create a Counterparty for the Account.")
glossaryItems += makeGlossaryItem("can_add_counterparty", canAddCounterpartyExample)
lazy val markdownExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("markdown", markdownExample)
+ // glossaryItems += makeGlossaryItem("markdown", markdownExample)
lazy val standingOrderIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("standing_order_id", standingOrderIdExample)
+ // glossaryItems += makeGlossaryItem("standing_order_id", standingOrderIdExample)
lazy val parentProductExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("parent_product", parentProductExample)
+ // glossaryItems += makeGlossaryItem("parent_product", parentProductExample)
lazy val mobilePhoneExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("mobile_phone", mobilePhoneExample)
+ // glossaryItems += makeGlossaryItem("mobile_phone", mobilePhoneExample)
lazy val sundayExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("sunday", sundayExample)
+ // glossaryItems += makeGlossaryItem("sunday", sundayExample)
lazy val propertyExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("property", propertyExample)
+ // glossaryItems += makeGlossaryItem("property", propertyExample)
lazy val tokenExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("token", tokenExample)
+ // glossaryItems += makeGlossaryItem("token", tokenExample)
lazy val accountRoutingExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("account_routing", accountRoutingExample)
+ // glossaryItems += makeGlossaryItem("account_routing", accountRoutingExample)
lazy val requestedCurrentRateAmount2Example = ConnectorField("20",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("requested_current_rate_amount2", requestedCurrentRateAmount2Example)
lazy val narrativeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("narrative", narrativeExample)
+ // glossaryItems += makeGlossaryItem("narrative", narrativeExample)
- lazy val canSeeOtherAccountRoutingAddressExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeOtherAccountRoutingAddressExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the routing address of the Other Account, the counterparty side of a Transaction.")
glossaryItems += makeGlossaryItem("can_see_other_account_routing_address", canSeeOtherAccountRoutingAddressExample)
lazy val statusesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("statuses", statusesExample)
+ // glossaryItems += makeGlossaryItem("statuses", statusesExample)
lazy val callsMadeExample = ConnectorField("50",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("calls_made", callsMadeExample)
lazy val currentStateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("current_state", currentStateExample)
+ // glossaryItems += makeGlossaryItem("current_state", currentStateExample)
lazy val customersExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("customers", customersExample)
+ // glossaryItems += makeGlossaryItem("customers", customersExample)
lazy val scheduledDateExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("scheduled_date", scheduledDateExample)
@@ -1877,55 +1887,55 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("allowed_attempts", allowedAttemptsExample)
lazy val hostedByExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("hosted_by", hostedByExample)
+ // glossaryItems += makeGlossaryItem("hosted_by", hostedByExample)
lazy val whenExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("when", whenExample)
lazy val userAuthContextUpdateIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("user_auth_context_update_id", userAuthContextUpdateIdExample)
+ // glossaryItems += makeGlossaryItem("user_auth_context_update_id", userAuthContextUpdateIdExample)
lazy val accessiblefeaturesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("accessiblefeatures", accessiblefeaturesExample)
+ // glossaryItems += makeGlossaryItem("accessiblefeatures", accessiblefeaturesExample)
lazy val tuesdayExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("tuesday", tuesdayExample)
+ // glossaryItems += makeGlossaryItem("tuesday", tuesdayExample)
- lazy val canQueryAvailableFundsExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canQueryAvailableFundsExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can check whether funds are available on the Account.")
glossaryItems += makeGlossaryItem("can_query_available_funds", canQueryAvailableFundsExample)
lazy val otherAccountSecondaryRoutingSchemeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("other_account_secondary_routing_scheme", otherAccountSecondaryRoutingSchemeExample)
+ // glossaryItems += makeGlossaryItem("other_account_secondary_routing_scheme", otherAccountSecondaryRoutingSchemeExample)
lazy val processExample = ConnectorField("obp.getBank","The format must be obp.xxxx, 'obp.' is the prefix, xxx will be the connector method name")
glossaryItems += makeGlossaryItem("process", processExample)
lazy val otherBranchRoutingSchemeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("other_branch_routing_scheme", otherBranchRoutingSchemeExample)
+ // glossaryItems += makeGlossaryItem("other_branch_routing_scheme", otherBranchRoutingSchemeExample)
lazy val openingTimeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("opening_time", openingTimeExample)
+ // glossaryItems += makeGlossaryItem("opening_time", openingTimeExample)
lazy val httpProtocolExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("http_protocol", httpProtocolExample)
+ // glossaryItems += makeGlossaryItem("http_protocol", httpProtocolExample)
lazy val thisAccountIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("this_account_id", thisAccountIdExample)
+ // glossaryItems += makeGlossaryItem("this_account_id", thisAccountIdExample)
lazy val queryExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("query", queryExample)
+ // glossaryItems += makeGlossaryItem("query", queryExample)
lazy val badAttemptsSinceLastSuccessOrResetExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("bad_attempts_since_last_success_or_reset", badAttemptsSinceLastSuccessOrResetExample)
+ // glossaryItems += makeGlossaryItem("bad_attempts_since_last_success_or_reset", badAttemptsSinceLastSuccessOrResetExample)
lazy val webHooksExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("web_hooks", webHooksExample)
+ // glossaryItems += makeGlossaryItem("web_hooks", webHooksExample)
lazy val providerIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("provider_id", providerIdExample)
+ // glossaryItems += makeGlossaryItem("provider_id", providerIdExample)
lazy val meetingsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("meetings", meetingsExample)
+ // glossaryItems += makeGlossaryItem("meetings", meetingsExample)
lazy val cardNumberExample = bankCardNumberExample
@@ -1933,31 +1943,32 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("instructedamount", instructedamountExample)
lazy val userCustomerLinkIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("user_customer_link_id", userCustomerLinkIdExample)
+ // glossaryItems += makeGlossaryItem("user_customer_link_id", userCustomerLinkIdExample)
lazy val outboundTopicExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("outbound_topic", outboundTopicExample)
+ // glossaryItems += makeGlossaryItem("outbound_topic", outboundTopicExample)
lazy val postCodeExample = ConnectorField("789",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("post_code", postCodeExample)
lazy val superFamilyExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("super_family", superFamilyExample)
+ // glossaryItems += makeGlossaryItem("super_family", superFamilyExample)
lazy val nameExample = ConnectorField("ACCOUNT_MANAGEMENT_FEE",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("name", nameExample)
lazy val ageExample = ConnectorField("18", "The user age.")
- glossaryItems += makeGlossaryItem("age", ageExample)
+ // No glossary item: Glossary.scala defines "Age", and glossary lookups are case insensitive,
+ // so a "age" field resolves to that rather than to an entry with no description.
lazy val productFeeIdExample = ConnectorField("696hlAHLFKUHE37469287634",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("product_fee_id", productFeeIdExample)
lazy val emailAddressExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("email_address", emailAddressExample)
+ // glossaryItems += makeGlossaryItem("email_address", emailAddressExample)
lazy val availableFundsRequestIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("available_funds_request_id", availableFundsRequestIdExample)
+ // glossaryItems += makeGlossaryItem("available_funds_request_id", availableFundsRequestIdExample)
lazy val lastNameExample = ConnectorField("Smith","The Last name")
glossaryItems += makeGlossaryItem("last_name", lastNameExample)
@@ -1979,94 +1990,94 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("logo_url", logoURLExample)
lazy val roleExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("role", roleExample)
+ // glossaryItems += makeGlossaryItem("role", roleExample)
lazy val requireScopesForListedRolesExample = ConnectorField(booleanFalse,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("require_scopes_for_listed_roles", requireScopesForListedRolesExample)
lazy val branchTypeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("branch_type", branchTypeExample)
+ // glossaryItems += makeGlossaryItem("branch_type", branchTypeExample)
lazy val fullNameExample = ConnectorField("full name string",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("full_name", fullNameExample)
- lazy val canCreateDirectDebitExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canCreateDirectDebitExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can create a Direct Debit on the Account.")
glossaryItems += makeGlossaryItem(CAN_CREATE_DIRECT_DEBIT, canCreateDirectDebitExample)
lazy val futureDateExample = ConnectorField("20200127",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("future_date", futureDateExample)
lazy val toTransferToAccountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("to_transfer_to_account", toTransferToAccountExample)
+ // glossaryItems += makeGlossaryItem("to_transfer_to_account", toTransferToAccountExample)
lazy val thisAccountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("this_account", thisAccountExample)
+ // glossaryItems += makeGlossaryItem("this_account", thisAccountExample)
lazy val accountApplicationIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("account_application_id", accountApplicationIdExample)
+ // glossaryItems += makeGlossaryItem("account_application_id", accountApplicationIdExample)
lazy val documentNumberExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("document_number", documentNumberExample)
+ // glossaryItems += makeGlossaryItem("document_number", documentNumberExample)
- lazy val canSeeOtherAccountNationalIdentifierExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeOtherAccountNationalIdentifierExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the national identifier of the Other Account, the counterparty side of a Transaction.")
glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_NATIONAL_IDENTIFIER, canSeeOtherAccountNationalIdentifierExample)
lazy val canSeeTransactionStartDateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_START_DATE, canSeeTransactionStartDateExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_START_DATE, canSeeTransactionStartDateExample)
lazy val canAddPhysicalLocationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_ADD_PHYSICAL_LOCATION, canAddPhysicalLocationExample)
+ // glossaryItems += makeGlossaryItem(CAN_ADD_PHYSICAL_LOCATION, canAddPhysicalLocationExample)
lazy val cacheExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("cache", cacheExample)
+ // glossaryItems += makeGlossaryItem("cache", cacheExample)
- lazy val canSeeBankRoutingAddressExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeBankRoutingAddressExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the routing address of the Bank that holds the Account.")
glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ROUTING_ADDRESS, canSeeBankRoutingAddressExample)
lazy val usersExample = ConnectorField("user list", "Please refer to the user object.")
glossaryItems += makeGlossaryItem("users", usersExample)
lazy val staffNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("staff_name", staffNameExample)
+ // glossaryItems += makeGlossaryItem("staff_name", staffNameExample)
lazy val ktyExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("kty", ktyExample)
+ // glossaryItems += makeGlossaryItem("kty", ktyExample)
- lazy val canBeSeenOnViewsExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canBeSeenOnViewsExample = ConnectorField(booleanFalse, "The Views on which the attributes of an Attribute Definition can be seen, as a list of view ids. Set on the Attribute Definition itself, so despite the name this is not a View permission.")
glossaryItems += makeGlossaryItem("can_be_seen_on_views", canBeSeenOnViewsExample)
lazy val kidExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("kid", kidExample)
+ // glossaryItems += makeGlossaryItem("kid", kidExample)
lazy val createdByUserExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("created_by_user", createdByUserExample)
+ // glossaryItems += makeGlossaryItem("created_by_user", createdByUserExample)
lazy val taxNumberExample = ConnectorField("456",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("tax_number", taxNumberExample)
lazy val presentExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("present", presentExample)
+ // glossaryItems += makeGlossaryItem("present", presentExample)
lazy val metadataExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("metadata", metadataExample)
+ // glossaryItems += makeGlossaryItem("metadata", metadataExample)
- lazy val canSeeTransactionAmountExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeTransactionAmountExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the amount of a Transaction on the Account.")
glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_AMOUNT, canSeeTransactionAmountExample)
lazy val methodRoutingIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("method_routing_id", methodRoutingIdExample)
+ // glossaryItems += makeGlossaryItem("method_routing_id", methodRoutingIdExample)
lazy val thisBankIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("this_bank_id", thisBankIdExample)
+ // glossaryItems += makeGlossaryItem("this_bank_id", thisBankIdExample)
lazy val permissionsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("permissions", permissionsExample)
+ // glossaryItems += makeGlossaryItem("permissions", permissionsExample)
lazy val otherBranchRoutingAddressExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("other_branch_routing_address", otherBranchRoutingAddressExample)
+ // glossaryItems += makeGlossaryItem("other_branch_routing_address", otherBranchRoutingAddressExample)
lazy val bespokeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("bespoke", bespokeExample)
+ // glossaryItems += makeGlossaryItem("bespoke", bespokeExample)
lazy val codeExample = ConnectorField("125",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("code", codeExample)
@@ -2074,14 +2085,14 @@ object ExampleValue {
lazy val countryCodeExample = ConnectorField("1254",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("country_code", countryCodeExample)
- lazy val canSeeBankAccountCreditLimitExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeBankAccountCreditLimitExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the credit limit of the Account.")
glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_CREDIT_LIMIT, canSeeBankAccountCreditLimitExample)
- lazy val canSeeOtherAccountNumberExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeOtherAccountNumberExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the account number of the Other Account, the counterparty side of a Transaction.")
glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_NUMBER, canSeeOtherAccountNumberExample)
lazy val orderExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("order", orderExample)
+ // glossaryItems += makeGlossaryItem("order", orderExample)
lazy val postedExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("posted", postedExample)
@@ -2090,30 +2101,30 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("logo", logoExample)
lazy val topApisExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("top_apis", topApisExample)
+ // glossaryItems += makeGlossaryItem("top_apis", topApisExample)
lazy val taxResidenceExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("tax_residence", taxResidenceExample)
+ // glossaryItems += makeGlossaryItem("tax_residence", taxResidenceExample)
lazy val isActiveExample = ConnectorField(booleanFalse,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("is_active", isActiveExample)
- lazy val canSeeBankAccountBankNameExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeBankAccountBankNameExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the name of the Bank that holds the Account.")
glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_BANK_NAME, canSeeBankAccountBankNameExample)
lazy val firstNameExample = ConnectorField("Tom","The first name")
glossaryItems += makeGlossaryItem("first_name", firstNameExample)
lazy val contactDetailsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("contact_details", contactDetailsExample)
+ // glossaryItems += makeGlossaryItem("contact_details", contactDetailsExample)
lazy val jwksUriExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("jwks_uri", jwksUriExample)
+ // glossaryItems += makeGlossaryItem("jwks_uri", jwksUriExample)
lazy val transactionIdsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("transaction_ids", transactionIdsExample)
+ // glossaryItems += makeGlossaryItem("transaction_ids", transactionIdsExample)
- lazy val canSeeBankAccountOwnersExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeBankAccountOwnersExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the owners of the Account.")
glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_OWNERS, canSeeBankAccountOwnersExample)
lazy val actualDateExample = ConnectorField("2020-01-27",NoDescriptionProvided)
@@ -2122,23 +2133,23 @@ object ExampleValue {
lazy val exampleOutboundMessageExample = ConnectorField("{}","this will the json object")
glossaryItems += makeGlossaryItem("example_outbound_message", exampleOutboundMessageExample)
- lazy val canDeleteWhereTagExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canDeleteWhereTagExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can delete the where tag on a Transaction.")
glossaryItems += makeGlossaryItem(CAN_DELETE_WHERE_TAG, canDeleteWhereTagExample)
- lazy val canSeeUrlExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeUrlExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the URL held in the metadata of a Transaction.")
glossaryItems += makeGlossaryItem(CAN_SEE_URL, canSeeUrlExample)
lazy val versionExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("version", versionExample)
+ // glossaryItems += makeGlossaryItem("version", versionExample)
lazy val collectedExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("collected", collectedExample)
lazy val canAddPublicAliasExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_ADD_PUBLIC_ALIAS, canAddPublicAliasExample)
+ // glossaryItems += makeGlossaryItem(CAN_ADD_PUBLIC_ALIAS, canAddPublicAliasExample)
lazy val allowedActionsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("allowed_actions", allowedActionsExample)
+ // glossaryItems += makeGlossaryItem("allowed_actions", allowedActionsExample)
lazy val rankAmount1Example = ConnectorField("100",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("rank_amount1", rankAmount1Example)
@@ -2147,67 +2158,69 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("duration_time", durationTimeExample)
lazy val noneExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("none", noneExample)
+ // glossaryItems += makeGlossaryItem("none", noneExample)
lazy val implementedInVersionExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("implemented_in_version", implementedInVersionExample)
+ // glossaryItems += makeGlossaryItem("implemented_in_version", implementedInVersionExample)
- lazy val canSeeImageUrlExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeImageUrlExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the URL of an image attached to a Transaction.")
glossaryItems += makeGlossaryItem(CAN_SEE_IMAGE_URL, canSeeImageUrlExample)
lazy val toTransferToPhoneExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("to_transfer_to_phone", toTransferToPhoneExample)
+ // glossaryItems += makeGlossaryItem("to_transfer_to_phone", toTransferToPhoneExample)
lazy val perDayExample = ConnectorField("4000",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("per_day", perDayExample)
lazy val elasticSearchExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("elastic_search", elasticSearchExample)
+ // glossaryItems += makeGlossaryItem("elastic_search", elasticSearchExample)
lazy val reasonRequestedExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("reason_requested", reasonRequestedExample)
+ // glossaryItems += makeGlossaryItem("reason_requested", reasonRequestedExample)
lazy val perWeekExample = ConnectorField("50000",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("per_week", perWeekExample)
lazy val productsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("products", productsExample)
+ // glossaryItems += makeGlossaryItem("products", productsExample)
lazy val organisationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("organisation", organisationExample)
+ // glossaryItems += makeGlossaryItem("organisation", organisationExample)
lazy val branchRoutingExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("branch_routing", branchRoutingExample)
+ // glossaryItems += makeGlossaryItem("branch_routing", branchRoutingExample)
lazy val versionStatusExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("version_status", versionStatusExample)
+ // glossaryItems += makeGlossaryItem("version_status", versionStatusExample)
lazy val apiVersionExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("api_version", apiVersionExample)
+ // glossaryItems += makeGlossaryItem("api_version", apiVersionExample)
lazy val perSecondCallLimitExample = ConnectorField("10",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("per_second_call_limit", perSecondCallLimitExample)
lazy val messagesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("messages", messagesExample)
+ // glossaryItems += makeGlossaryItem("messages", messagesExample)
lazy val metaExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("meta", metaExample)
+ // glossaryItems += makeGlossaryItem("meta", metaExample)
lazy val eExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("e", eExample)
+ // glossaryItems += makeGlossaryItem("e", eExample)
- lazy val canSeeCorporateLocationExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeCorporateLocationExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the corporate location recorded on a Transaction.")
glossaryItems += makeGlossaryItem(CAN_SEE_CORPORATE_LOCATION, canSeeCorporateLocationExample)
lazy val userExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("user", userExample)
+ // No glossary item: Glossary.scala defines "User", and glossary lookups are case insensitive,
+ // so a "user" field resolves to that rather than to an entry with no description.
+ // glossaryItems += makeGlossaryItem("user", userExample)
lazy val lastLockDateExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("last_lock_date", lastLockDateExample)
lazy val requestedCurrentRateAmount1Example = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("requested_current_rate_amount1", requestedCurrentRateAmount1Example)
+ // glossaryItems += makeGlossaryItem("requested_current_rate_amount1", requestedCurrentRateAmount1Example)
lazy val toCurrencyCodeExample = ConnectorField("EUR",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("to_currency_code", toCurrencyCodeExample)
@@ -2216,136 +2229,136 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("dob_of_dependants", dobOfDependantsExample)
lazy val settlementAccountsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("settlement_accounts", settlementAccountsExample)
+ // glossaryItems += makeGlossaryItem("settlement_accounts", settlementAccountsExample)
lazy val collectionCodeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("collection_code", collectionCodeExample)
+ // glossaryItems += makeGlossaryItem("collection_code", collectionCodeExample)
lazy val energySourceExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("energy_source", energySourceExample)
+ // glossaryItems += makeGlossaryItem("energy_source", energySourceExample)
lazy val openCorporatesUrlExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("open_corporates_url", openCorporatesUrlExample)
+ // glossaryItems += makeGlossaryItem("open_corporates_url", openCorporatesUrlExample)
lazy val inverseConversionValueExample = ConnectorField("50",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("inverse_conversion_value", inverseConversionValueExample)
lazy val methodRoutingsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("method_routings", methodRoutingsExample)
+ // glossaryItems += makeGlossaryItem("method_routings", methodRoutingsExample)
lazy val orderIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("order_id", orderIdExample)
+ // glossaryItems += makeGlossaryItem("order_id", orderIdExample)
lazy val checksExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("checks", checksExample)
+ // glossaryItems += makeGlossaryItem("checks", checksExample)
lazy val mondayExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("monday", mondayExample)
+ // glossaryItems += makeGlossaryItem("monday", mondayExample)
lazy val requiredfieldinfoExample = ConnectorField("false",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("requiredfieldinfo", requiredfieldinfoExample)
- lazy val canSeeWhereTagExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeWhereTagExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the where tag, the geolocation recorded by a User, on a Transaction.")
glossaryItems += makeGlossaryItem(CAN_SEE_WHERE_TAG, canSeeWhereTagExample)
lazy val bankidExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("bankid", bankidExample)
+ // glossaryItems += makeGlossaryItem("bankid", bankidExample)
lazy val otherAccountSecondaryRoutingAddressExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("other_account_secondary_routing_address", otherAccountSecondaryRoutingAddressExample)
+ // glossaryItems += makeGlossaryItem("other_account_secondary_routing_address", otherAccountSecondaryRoutingAddressExample)
lazy val perMonthExample = ConnectorField("500",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("per_month", perMonthExample)
lazy val inboundTopicExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("inbound_topic", inboundTopicExample)
+ // glossaryItems += makeGlossaryItem("inbound_topic", inboundTopicExample)
lazy val creditoraccountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("creditoraccount", creditoraccountExample)
+ // glossaryItems += makeGlossaryItem("creditoraccount", creditoraccountExample)
lazy val warehouseExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("warehouse", warehouseExample)
+ // glossaryItems += makeGlossaryItem("warehouse", warehouseExample)
lazy val metricsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("metrics", metricsExample)
+ // glossaryItems += makeGlossaryItem("metrics", metricsExample)
lazy val kycDocumentExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("kyc_document", kycDocumentExample)
+ // glossaryItems += makeGlossaryItem("kyc_document", kycDocumentExample)
lazy val privateAliasExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("private_alias", privateAliasExample)
+ // glossaryItems += makeGlossaryItem("private_alias", privateAliasExample)
lazy val toSepaCreditTransfersExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("to_sepa_credit_transfers", toSepaCreditTransfersExample)
+ // glossaryItems += makeGlossaryItem("to_sepa_credit_transfers", toSepaCreditTransfersExample)
lazy val stateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("state", stateExample)
+ // glossaryItems += makeGlossaryItem("state", stateExample)
lazy val createdByUserIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("created_by_user_id", createdByUserIdExample)
+ // glossaryItems += makeGlossaryItem("created_by_user_id", createdByUserIdExample)
lazy val attributesExample = ConnectorField("attribute value in form of (name, value)",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("attributes", attributesExample)
lazy val revokedExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("revoked", revokedExample)
+ // glossaryItems += makeGlossaryItem("revoked", revokedExample)
lazy val currentCreditDocumentationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("current_credit_documentation", currentCreditDocumentationExample)
+ // glossaryItems += makeGlossaryItem("current_credit_documentation", currentCreditDocumentationExample)
lazy val mobilePhoneNumberExample = ConnectorField("+49 30 901820",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("mobile_phone_number", mobilePhoneNumberExample)
lazy val saturdayExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("saturday", saturdayExample)
+ // glossaryItems += makeGlossaryItem("saturday", saturdayExample)
lazy val completedExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("completed", completedExample)
lazy val domainExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("domain", domainExample)
+ // glossaryItems += makeGlossaryItem("domain", domainExample)
lazy val toSandboxTanExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("to_sandbox_tan", toSandboxTanExample)
+ // glossaryItems += makeGlossaryItem("to_sandbox_tan", toSandboxTanExample)
- lazy val canAddTagExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canAddTagExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can add a tag to a Transaction.")
glossaryItems += makeGlossaryItem(CAN_ADD_TAG, canAddTagExample)
- lazy val canSeeBankAccountLabelExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeBankAccountLabelExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the label of the Account.")
glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_LABEL, canSeeBankAccountLabelExample)
lazy val serviceAvailableExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("service_available", serviceAvailableExample)
+ // glossaryItems += makeGlossaryItem("service_available", serviceAvailableExample)
lazy val suggestedOrderExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("suggested_order", suggestedOrderExample)
+ // glossaryItems += makeGlossaryItem("suggested_order", suggestedOrderExample)
lazy val shortcodeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("shortcode", shortcodeExample)
+ // glossaryItems += makeGlossaryItem("shortcode", shortcodeExample)
lazy val linkExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("link", linkExample)
+ // glossaryItems += makeGlossaryItem("link", linkExample)
lazy val canSeeTransactionTypeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_TYPE, canSeeTransactionTypeExample)
+ // glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_TYPE, canSeeTransactionTypeExample)
lazy val implementedByPartialFunctionExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("implemented_by_partial_function", implementedByPartialFunctionExample)
+ // glossaryItems += makeGlossaryItem("implemented_by_partial_function", implementedByPartialFunctionExample)
lazy val driveUpExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("drive_up", driveUpExample)
+ // glossaryItems += makeGlossaryItem("drive_up", driveUpExample)
- lazy val canAddMoreInfoExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canAddMoreInfoExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can add the more-info note to a Transaction.")
glossaryItems += makeGlossaryItem(CAN_ADD_MORE_INFO, canAddMoreInfoExample)
lazy val detailExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("detail", detailExample)
+ // glossaryItems += makeGlossaryItem("detail", detailExample)
lazy val viewsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("views", viewsExample)
+ // glossaryItems += makeGlossaryItem("views", viewsExample)
lazy val transactionRequestTypesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("transaction_request_types", transactionRequestTypesExample)
+ // glossaryItems += makeGlossaryItem("transaction_request_types", transactionRequestTypesExample)
lazy val counterpartyLimitIdExample = ConnectorField("abc9a7e4-6d02-40e3-a129-0b2bf89de9b1","A string that MUST uniquely identify the Counterparty Limit on this OBP instance.")
glossaryItems += makeGlossaryItem("counterparty_limit_id", counterpartyLimitIdExample)
@@ -2371,47 +2384,47 @@ object ExampleValue {
lazy val maxTotalAmountExample = ConnectorField("10000.12",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("max_total_amount", maxTotalAmountExample)
- lazy val canAddImageUrlExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canAddImageUrlExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can add an image URL to a Transaction.")
glossaryItems += makeGlossaryItem(CAN_ADD_IMAGE_URL, canAddImageUrlExample)
lazy val jwksUrisExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("jwks_uris", jwksUrisExample)
+ // glossaryItems += makeGlossaryItem("jwks_uris", jwksUrisExample)
- lazy val canSeeOtherAccountSwiftBicExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeOtherAccountSwiftBicExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the SWIFT / BIC of the Other Account, the counterparty side of a Transaction.")
glossaryItems += makeGlossaryItem(CAN_SEE_OTHER_ACCOUNT_SWIFT_BIC, canSeeOtherAccountSwiftBicExample)
lazy val staffUserIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("staff_user_id", staffUserIdExample)
+ // glossaryItems += makeGlossaryItem("staff_user_id", staffUserIdExample)
lazy val branchRoutingsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("branch_routings", branchRoutingsExample)
+ // glossaryItems += makeGlossaryItem("branch_routings", branchRoutingsExample)
lazy val validFromExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("valid_from", validFromExample)
- lazy val canDeleteImageExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canDeleteImageExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can delete an image attached to a Transaction.")
glossaryItems += makeGlossaryItem(CAN_DELETE_IMAGE, canDeleteImageExample)
lazy val toExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("to", toExample)
+ // glossaryItems += makeGlossaryItem("to", toExample)
lazy val messageFormatExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("message_format", messageFormatExample)
+ // glossaryItems += makeGlossaryItem("message_format", messageFormatExample)
lazy val productAttributesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("product_attributes", productAttributesExample)
+ // glossaryItems += makeGlossaryItem("product_attributes", productAttributesExample)
- lazy val canSeeTransactionDescriptionExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeTransactionDescriptionExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the description of a Transaction on the Account.")
glossaryItems += makeGlossaryItem(CAN_SEE_TRANSACTION_DESCRIPTION, canSeeTransactionDescriptionExample)
lazy val faceImageExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("face_image", faceImageExample)
+ // glossaryItems += makeGlossaryItem("face_image", faceImageExample)
- lazy val canSeeBankAccountNumberExample = ConnectorField(booleanFalse,NoDescriptionProvided)
+ lazy val canSeeBankAccountNumberExample = ConnectorField(booleanFalse, "A View permission. If true, a User with this View can see the account number of the Account.")
glossaryItems += makeGlossaryItem(CAN_SEE_BANK_ACCOUNT_NUMBER, canSeeBankAccountNumberExample)
lazy val glossaryItemsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("glossary_items", glossaryItemsExample)
+ // glossaryItems += makeGlossaryItem("glossary_items", glossaryItemsExample)
lazy val isBankIdExactMatchExample = ConnectorField(booleanFalse,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("is_bank_id_exact_match", isBankIdExactMatchExample)
@@ -2423,10 +2436,10 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("ATM.is_accessible", isAccessibleExample)
lazy val entitlementIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("entitlement_id", entitlementIdExample)
+ // glossaryItems += makeGlossaryItem("entitlement_id", entitlementIdExample)
lazy val indexExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("index", indexExample)
+ // glossaryItems += makeGlossaryItem("index", indexExample)
lazy val descriptionExample = ConnectorField(s"Description of the object. Maximum length is ${ApiCollection.Description.maxLen}. It can be any characters here.","The human readable description here.")
glossaryItems += makeGlossaryItem("description", descriptionExample)
@@ -2438,31 +2451,31 @@ object ExampleValue {
glossaryItems += makeGlossaryItem("DynamicResourceDoc.description", dynamicResourceDocDescriptionExample)
lazy val canDeleteCommentExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_DELETE_COMMENT, canDeleteCommentExample)
+ // glossaryItems += makeGlossaryItem(CAN_DELETE_COMMENT, canDeleteCommentExample)
lazy val commentsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("comments", commentsExample)
+ // glossaryItems += makeGlossaryItem("comments", commentsExample)
lazy val banksExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("banks", banksExample)
+ // glossaryItems += makeGlossaryItem("banks", banksExample)
lazy val canCreateStandingOrderExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem(CAN_CREATE_STANDING_ORDER, canCreateStandingOrderExample)
+ // glossaryItems += makeGlossaryItem(CAN_CREATE_STANDING_ORDER, canCreateStandingOrderExample)
lazy val adapterImplementationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("adapter_implementation", adapterImplementationExample)
+ // glossaryItems += makeGlossaryItem("adapter_implementation", adapterImplementationExample)
lazy val successExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("success", successExample)
+ // glossaryItems += makeGlossaryItem("success", successExample)
lazy val createdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("created", createdExample)
+ // glossaryItems += makeGlossaryItem("created", createdExample)
lazy val issuePlaceExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("issue_place", issuePlaceExample)
+ // glossaryItems += makeGlossaryItem("issue_place", issuePlaceExample)
lazy val summaryExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("summary", summaryExample)
+ // glossaryItems += makeGlossaryItem("summary", summaryExample)
lazy val dynamicResourceDocSummaryExample = ConnectorField("Create My User","The summary of this endpoint")
glossaryItems += makeGlossaryItem("DynamicResourceDoc.summary", dynamicResourceDocSummaryExample)
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 1c8b4bfaf5..2387e2b146 100644
--- a/obp-api/src/main/scala/code/api/util/Glossary.scala
+++ b/obp-api/src/main/scala/code/api/util/Glossary.scala
@@ -4,8 +4,9 @@ import code.api.Constant
import code.api.Constant._
import code.api.ResourceDocs1_4_0.OpenAPI31JSONFactory
import code.api.util.APIUtil.{getObpApiRoot, getServerUrl}
-import code.api.util.ExampleValue.{accountIdExample, bankIdExample, customerIdExample, userIdExample}
+import code.api.util.ExampleValue.{accountIdExample, bankIdExample, customerIdExample, transactionIdExample, userIdExample, viewIdExample}
import code.util.Helper.MdcLoggable
+import net.liftweb.common.Full
import code.webuiprops.MappedWebUiPropsProvider.getWebUiPropsValue
import java.io.File
@@ -14,62 +15,161 @@ import scala.collection.mutable.ArrayBuffer
object Glossary extends MdcLoggable {
- def getGlossaryItem(title: String): String = {
-
- //logger.debug(s"getGlossaryItem says Hello. title to find is: $title")
-
- val something = glossaryItems.find(_.title.toLowerCase == title.toLowerCase) match {
- case Some(foundItem) =>
- /**
- * Two important rules:
- * 1. Make sure you have an **empty line** after the closing `` tag, otherwise the markdown/code blocks won't show correctly.
- * 2. Make sure you have an **empty line** after the closing `` tag if you have multiple collapsible sections.
- */
- s"""
- |${foundItem.title}
- |
- | ${foundItem.htmlDescription}
- |
- |""".stripMargin
- case None => "glossary-item-not-found"
+ // ── Embedding Glossary text in Resource Doc descriptions ──────────────────
+ // These three helpers are called while the Resource Docs are being built, which happens at
+ // class initialisation, long before the database is available. So rather than resolving the
+ // Glossary Item there and then, they emit a placeholder that is expanded when the docs are
+ // served — against the union of static and Dynamic Glossary Items, so a Dynamic Item overrides
+ // the shipped text in endpoint descriptions just as it does in GET /api/glossary.
+ //
+ // Expansion happens on the markdown, before it is converted to html. See
+ // expandGlossaryPlaceholders and its three call sites: JSONFactory1_4_0 (the Resource Docs
+ // API), SwaggerJSONFactory and OpenAPI31JSONFactory.
+
+ // An html comment, deliberately. The placeholder is normally expanded long before anyone sees
+ // it, but if one ever does leak into a response it must be inert: `{{...}}` would have been
+ // read as an interpolation expression by a Vue or Angular client and thrown at render time.
+ // A comment renders as nothing instead.
+ private val GlossaryPlaceholderPrefix = """".r
+
+ // A FULL or SIMPLE expansion embeds another Item's html, which may itself hold placeholders,
+ // and replaceAllIn does not rescan what it substitutes. So expansion repeats — bounded, so a
+ // cycle of Items referencing each other terminates and leaves an inert comment at worst.
+ private val GlossaryPlaceholderMaxPasses = 3
+
+ private def glossaryPlaceholder(mode: String, title: String): String = s"$GlossaryPlaceholderPrefix$mode:$title-->"
+
+ /** Embeds the Glossary Item as a collapsible block. */
+ def getGlossaryItem(title: String): String = glossaryPlaceholder("FULL", title)
+
+ /**
+ * Embeds just the text of the Glossary Item, with no title and no collapsible element.
+ * Use this if getGlossaryItem is problematic with a certain glossary item (e.g. JSON Schema
+ * Validation Glossary Item) or you just want a simple inclusion of text.
+ */
+ def getGlossaryItemSimple(title: String): String = glossaryPlaceholder("SIMPLE", title)
+
+ /**
+ * Embeds a link to the Glossary Item rather than its text.
+ * Can reduce bandwidth and maybe make things semantically clearer.
+ */
+ def getGlossaryItemLink(title: String): String = glossaryPlaceholder("LINK", title)
+
+ /**
+ * Two important rules for the FULL rendering:
+ * 1. Make sure you have an **empty line** after the closing `` tag, otherwise the markdown/code blocks won't show correctly.
+ * 2. Make sure you have an **empty line** after the closing `` tag if you have multiple collapsible sections.
+ */
+ private def renderGlossaryItemFull(item: GlossaryItem): String =
+ s"""
+ |${item.title}
+ |
+ | ${item.htmlDescription}
+ |
+ |""".stripMargin
+
+ private def renderGlossaryItemSimple(item: GlossaryItem): String =
+ s"""
+ | ${item.htmlDescription}
+ |""".stripMargin
+
+ // We use the requested title rather than the found item's, because anchors are case sensitive.
+ private def renderGlossaryItemLink(title: String): String = s"""[here](/glossary#${title})"""
+
+ /**
+ * Expands any Glossary placeholders in the given markdown. Text with no placeholder is returned
+ * untouched, so this is cheap to call on every description.
+ */
+ def expandGlossaryPlaceholders(text: String): String =
+ expandGlossaryPlaceholders(text, GlossaryPlaceholderMaxPasses)
+
+ private def expandGlossaryPlaceholders(text: String, passesLeft: Int): String = {
+ if (text == null || passesLeft <= 0 || !text.contains(GlossaryPlaceholderPrefix)) text
+ else {
+ val expanded = expandOnce(text)
+ if (expanded == text) text else expandGlossaryPlaceholders(expanded, passesLeft - 1)
}
- //logger.debug(s"getGlossaryItem says the text to return is $something")
- something
}
- def getGlossaryItemSimple(title: String): String = {
- // This function just returns a string without Title and collapsable element.
- // Can use this if getGlossaryItem is problematic with a certain glossary item (e.g. JSON Schema Validation Glossary Item) or just want a simple inclusion of text.
-
- //logger.debug(s"getGlossaryItemSimple says Hello. title to find is: $title")
-
- val something = glossaryItems.find(_.title.toLowerCase == title.toLowerCase) match {
- case Some(foundItem) =>
- s"""
- | ${foundItem.htmlDescription}
- |""".stripMargin
- case None => "glossary-item-simple-not-found"
+ private def expandOnce(text: String): String = {
+ {
+ val byTitle = glossaryItemsByTitle
+ GlossaryPlaceholder.replaceAllIn(text, matched => {
+ val mode = matched.group(1)
+ val title = matched.group(2)
+ val rendered = byTitle.get(title.toLowerCase) match {
+ case Some(item) => mode match {
+ case "FULL" => renderGlossaryItemFull(item)
+ case "SIMPLE" => renderGlossaryItemSimple(item)
+ case _ => renderGlossaryItemLink(title)
+ }
+ case None =>
+ logger.debug(s"expandGlossaryPlaceholders could not find Glossary Item: $title")
+ mode match {
+ case "FULL" => "glossary-item-not-found"
+ case "SIMPLE" => "glossary-item-simple-not-found"
+ case _ => "glossary-item-link-not-found"
+ }
+ }
+ // The rendered text is arbitrary markdown, so $ and \ in it must not be read as
+ // replacement group references.
+ java.util.regex.Matcher.quoteReplacement(rendered)
+ })
}
- //logger.debug(s"getGlossaryItemSimple says the text to return is $something")
- something
}
- def getGlossaryItemLink(title: String): String = {
- // This function just returns a link to the Glossary Item in question.
- // Can reduce bandwith and maybe make things semantically clearer if we use links instead of includes.
-
- val something = glossaryItems.find(_.title.toLowerCase == title.toLowerCase) match {
- case Some(foundItem) =>
- // We use the title because anchors are case sensitive, but we find it so we can log / display not found.
- s"""[here](/glossary#${title})"""
- case None => "glossary-item-link-not-found"
+ // Expansion runs once per Resource Doc per Resource Doc cache TTL, and a cold cache expands
+ // hundreds of docs in one burst, so they share a lookup map rather than each reading the
+ // database. The map is keyed on the Dynamic Glossary Item watermark, and the watermark itself
+ // is re-read at most once a second.
+ private val GlossaryCacheRecheckMillis = 1000L
+ private val cachedItemsByTitle =
+ new java.util.concurrent.atomic.AtomicReference[(Long, String, Map[String, GlossaryItem])]((0L, "", Map.empty))
+
+ /**
+ * Drops the placeholder lookup cache so a write made on this node is reflected at once, rather
+ * than on the next watermark re-read. Other nodes still pick the write up via the watermark.
+ */
+ def invalidateGlossaryItemCache(): Unit = cachedItemsByTitle.set((0L, "", Map.empty))
+
+ private def glossaryState: (String, Map[String, GlossaryItem]) = {
+ val now = System.currentTimeMillis
+ val (checkedAt, version, byTitle) = cachedItemsByTitle.get()
+ if (checkedAt != 0L && now - checkedAt < GlossaryCacheRecheckMillis) (version, byTitle)
+ else {
+ val currentVersion = dynamicGlossaryItemsVersion
+ if (checkedAt != 0L && currentVersion == version) {
+ cachedItemsByTitle.set((now, version, byTitle))
+ (version, byTitle)
+ } else {
+ // allGlossaryItems yields one Item per exact title, but titles differing only in case
+ // survive and collapse together in this case-insensitive map. Reversing makes the first
+ // of those spellings win, as find() used to.
+ val items = allGlossaryItems
+ val rebuilt = items.reverse.map(item => item.title.toLowerCase -> item).toMap
+ cachedItemsByTitle.set((now, currentVersion, rebuilt))
+ // Only on a real change, so this reports each edit once rather than on every read.
+ logStaticOverrides(items.filter(_.shadowsStaticItem))
+ (currentVersion, rebuilt)
+ }
}
- something
}
+ private def glossaryItemsByTitle: Map[String, GlossaryItem] = glossaryState._2
+
+ /**
+ * A token for Resource Doc cache keys. It changes whenever a Dynamic Glossary Item is added,
+ * changed or removed, so a cached endpoint description that embeds Glossary text is rebuilt
+ * instead of being served stale for the rest of the Resource Doc cache TTL (an hour by
+ * default). Glossary writes are rare, so paying for a Resource Doc re-render on each one is
+ * the right way round.
+ */
+ def glossaryVersionForCacheKey: String = glossaryState._1
+
// reason of description is function: because we want make description is dynamic, so description can read
// webui_ props dynamic instead of a constant string.
@@ -77,7 +177,13 @@ object Glossary extends MdcLoggable {
title: String,
description: () => String,
htmlDescription: String,
- textDescription: String
+ textDescription: String,
+ // Provenance. Static items are compiled in; dynamic ones come from the
+ // DynamicGlossaryItem table. shadowsStaticItem is computed when the two
+ // sets are merged: true when this dynamic item displaced a static one.
+ isDynamic: Boolean = false,
+ overridesStaticItem: Boolean = false,
+ shadowsStaticItem: Boolean = false
)
def makeGlossaryItem (title: String, connectorField: ConnectorField) : GlossaryItem = {
@@ -117,6 +223,10 @@ object Glossary extends MdcLoggable {
)
}
+ /** A Glossary Item backed by a row in the DynamicGlossaryItem table. */
+ def dynamic(title: String, description: => String, overridesStaticItem: Boolean): GlossaryItem =
+ apply(title, description).copy(isDynamic = true, overridesStaticItem = overridesStaticItem)
+
}
@@ -127,6 +237,121 @@ object Glossary extends MdcLoggable {
// NOTE! Some glossary items are defined in ExampleValue.scala
+ // ── Dynamic Glossary Items ────────────────────────────────────────────────
+ // Glossary Items above are static: they are compiled in and only change when the API is
+ // redeployed. Dynamic Glossary Items live in the DynamicGlossaryItem table and are maintained
+ // at runtime over the /glossary-items endpoints. GET /api/glossary returns the union of the
+ // two, a Dynamic Item replacing a static one of the same title (compared case insensitively).
+ //
+ // Note the getGlossaryItem / getGlossaryItemSimple / getGlossaryItemLink helpers above stay
+ // static only on purpose. They are called while the Resource Docs are being built, which
+ // happens at class initialisation before the database is necessarily available, and their
+ // output is baked into the docs. Only the Glossary listing itself is dynamic.
+
+ /** Every Dynamic Glossary Item, rendered into the same GlossaryItem shape as the static ones. */
+ def dynamicGlossaryItems: List[GlossaryItem] = {
+ code.glossaryitem.DynamicGlossaryItems.dynamicGlossaryItem.vend.getAllDynamicGlossaryItems match {
+ case Full(rows) => rows.map(row => GlossaryItem.dynamic(row.title, row.description, row.overridesStaticItem))
+ case failure =>
+ // The Glossary must still be served if the table is unreachable, so fall back to static only.
+ logger.warn(s"Glossary.dynamicGlossaryItems could not read Dynamic Glossary Items: $failure")
+ Nil
+ }
+ }
+
+ /** True when the static Glossary defines an item with this title. Case insensitive. */
+ def staticGlossaryItemExists(title: String): Boolean =
+ glossaryItems.exists(_.title.toLowerCase == title.toLowerCase)
+
+ /**
+ * Static Glossary Items plus Dynamic ones, a Dynamic Item winning on a title clash.
+ *
+ * Creating a Dynamic Item whose title collides with a static one is refused unless the operator
+ * declared the override, so a clash here is normally deliberate. It can still arise without
+ * that declaration if a static item is added later with a title a Dynamic Item already uses —
+ * the Dynamic Item still wins, to keep one entry per title, and logStaticOverrides reports it.
+ */
+ def allGlossaryItems: List[GlossaryItem] = {
+ val dynamic = dynamicGlossaryItems
+ val staticTitles = glossaryItems.map(_.title.toLowerCase).toSet
+ val dynamicWithShadowFlag =
+ dynamic.map(item => item.copy(shadowsStaticItem = staticTitles.contains(item.title.toLowerCase)))
+ val shadowedTitles = dynamic.map(_.title.toLowerCase).toSet
+ dedupeByTitle(
+ glossaryItems.toList.filterNot(item => shadowedTitles.contains(item.title.toLowerCase)) ::: dynamicWithShadowFlag)
+ }
+
+ /**
+ * Keeps the first Item of each exact title.
+ *
+ * Two Items with the identical title is a mistake in the Glossary source: only one can own the
+ * /glossary#Title anchor, and every lookup already resolves to the first, so the second was
+ * unreachable anyway. Emitting both also breaks any client that keys a list by title. The
+ * listing drops it and says so, since the source is what wants fixing.
+ *
+ * Titles that differ only in case are left alone. Anchors are case sensitive, so those are
+ * distinct entries to a client and dropping one would lose documentation that reads fine today
+ * — but they are ambiguous to the case-insensitive lookups, so they are still worth reporting.
+ */
+ private def dedupeByTitle(items: List[GlossaryItem]): List[GlossaryItem] = {
+ val duplicated = items.groupBy(_.title).collect { case (title, sharing) if sharing.size > 1 => title }
+ if (duplicated.nonEmpty) {
+ logger.warn(
+ s"Glossary: ${duplicated.size} title(s) are defined more than once and only the first of each is served: " +
+ duplicated.toList.sorted.mkString(", ") +
+ ". Two Glossary Items cannot share a title — one of them needs renaming in Glossary.scala, ExampleValue.scala or docs/glossary.")
+ }
+ val caseOnlyCollisions = items.map(_.title).distinct
+ .groupBy(_.toLowerCase).collect { case (_, spellings) if spellings.size > 1 => spellings.sorted.mkString(" / ") }
+ if (caseOnlyCollisions.nonEmpty) {
+ logger.info(
+ s"Glossary: ${caseOnlyCollisions.size} title(s) differ only in case: " +
+ caseOnlyCollisions.toList.sorted.mkString(", ") +
+ ". All are served, but Glossary lookups are case insensitive and resolve to the first of each.")
+ }
+ items.distinctBy(_.title)
+ }
+
+ /** Dynamic Glossary Items that are currently displacing a static Item of the same title. */
+ def shadowingGlossaryItems: List[GlossaryItem] = allGlossaryItems.filter(_.shadowsStaticItem)
+
+ /**
+ * Reports, in the log, which static Glossary Items are currently being overridden. This is the
+ * one place the shadowing reaches a developer editing Glossary.scala, who otherwise has no way
+ * of knowing the database is displacing the text they just wrote. Called at boot and again
+ * whenever the Dynamic Glossary Item set changes.
+ */
+ def logStaticOverrides(shadowing: List[GlossaryItem]): Unit = {
+ val (declared, undeclared) = shadowing.partition(_.overridesStaticItem)
+ if (declared.nonEmpty) {
+ logger.info(
+ s"Glossary: ${declared.size} static Glossary Item(s) are deliberately overridden by Dynamic Glossary Items: " +
+ declared.map(_.title).sorted.mkString(", ") +
+ ". Editing their text in Glossary.scala will have no visible effect until the Dynamic Item is removed.")
+ }
+ if (undeclared.nonEmpty) {
+ // No override was declared, so the static item was almost certainly added after the
+ // Dynamic one. Worth a warning: neither the author of the static text nor the operator
+ // asked for this.
+ logger.warn(
+ s"Glossary: ${undeclared.size} static Glossary Item(s) are shadowed by Dynamic Glossary Items that did NOT declare an override: " +
+ undeclared.map(_.title).sorted.mkString(", ") +
+ ". A static Item was probably added later with a title already in use. Rename one, delete the Dynamic Item, " +
+ "or set overrides_static_item on it to confirm the override is intended.")
+ }
+ }
+
+ /** Boot-time entry point for the report above. */
+ def logStaticOverrides(): Unit = logStaticOverrides(shadowingGlossaryItems)
+
+ /**
+ * A watermark that changes whenever any Dynamic Glossary Item is added, changed or removed,
+ * so callers can cache the rendered Glossary and rebuild it only when it has actually moved.
+ */
+ def dynamicGlossaryItemsVersion: String =
+ code.glossaryitem.DynamicGlossaryItems.dynamicGlossaryItem.vend.getDynamicGlossaryItemsVersion.getOrElse("unavailable")
+
+
val latestConnector : String = "rest_vMar2019"
def messageDocLink(process: String) : String = {
@@ -1010,6 +1235,28 @@ object Glossary extends MdcLoggable {
"""The user Age"""
)
+ glossaryItems += GlossaryItem(
+ title = "View.view_id",
+ description =
+ s"""
+ |Identifies a View on a bank account.
+ |
+ |A View controls which fields of the account and its transactions a User can see, and which actions they can take on that account. Granting a User access to an account means granting them access through a particular View.
+ |
+ |Examples: `owner`, `accountant`, `auditor`.
+ |
+ |Example value: ${viewIdExample.value}
+ """)
+
+ glossaryItems += GlossaryItem(
+ title = "Transaction.transaction_id",
+ description =
+ s"""
+ |Uniquely identifies a Transaction on an account at a bank.
+ |
+ |Example value: ${transactionIdExample.value}
+ """)
+
glossaryItems += GlossaryItem(
title = "Account.account_id",
description =
@@ -1441,7 +1688,7 @@ object Glossary extends MdcLoggable {
|
|
|
- |See ${getGlossaryItemLink("Consent_OBP_Flow_Example")} for an example flow.
+ |See ${getGlossaryItemLink("Authentication: Consent OBP Flow Example")} for an example flow.
|See ${getGlossaryItemLink("Consent_Account_Onboarding")} for more information about onboarding.
|
|
diff --git a/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala b/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
index b850b84581..e20dbe3b0f 100644
--- a/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
+++ b/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
@@ -9,7 +9,7 @@ import java.util.Date
import code.api.util.APIUtil.{EmptyBody, PrimaryDataBody, ResourceDoc}
import code.api.util.ApiTag.ResourceDocTag
import code.api.util.Glossary.glossaryItems
-import code.api.util.{APIUtil, ApiRole, ConnectorField, CustomJsonFormats, ExampleValue, I18NUtil, PegdownOptions}
+import code.api.util.{APIUtil, ApiRole, ConnectorField, CustomJsonFormats, ExampleValue, Glossary, I18NUtil, PegdownOptions}
import code.bankconnectors.LocalMappedConnector.getAllEndpointTagsBox
import com.openbankproject.commons.model.ListResult
import code.crm.CrmEvent.CrmEvent
@@ -392,8 +392,13 @@ object JSONFactory1_4_0 extends MdcLoggable{
}
parameter match {
case _ if isUrlParameter() =>
+ // Same precedence as the body-field branch below, then a substring match as a last resort.
+ // A bare `contains` alone is order dependent: "bank_id" is a substring of "requires_bank_id"
+ // as well as "Bank.bank_id", so whichever was appended to glossaryItems first used to win.
glossaryItems
- .find(_.title.toLowerCase.contains(s"${parameter.toLowerCase}"))
+ .find(_.title.toLowerCase.equals(s"${parameter.toLowerCase}"))
+ .orElse(glossaryItems.find(_.title.toLowerCase.endsWith(s".${parameter.toLowerCase}")))
+ .orElse(glossaryItems.find(_.title.toLowerCase.contains(s"${parameter.toLowerCase}")))
.map(_.title).getOrElse("").replaceAll(" ","-")
case _ =>
// First try exact match (e.g. body field "address" → glossary item "address").
@@ -474,11 +479,17 @@ object JSONFactory1_4_0 extends MdcLoggable{
if(glossaryItemTitle.contains("jsonstring")){
""
} else {
- s"""
- |
- |[${boldIfMandatory()}](/glossary#$glossaryItemTitle): $exampleFieldValue
- |
- |""".stripMargin
+ // With no Glossary Item for this field, "[field](/glossary#)" would send the reader to the top
+ // of the Glossary rather than to a definition. Render the field plainly instead — a field with
+ // nothing to say about it is better than a link to nothing.
+ val field =
+ if (glossaryItemTitle.isEmpty) boldIfMandatory()
+ else s"[${boldIfMandatory()}](/glossary#$glossaryItemTitle)"
+ s"""
+ |
+ |$field: $exampleFieldValue
+ |
+ |""".stripMargin
}
}
@@ -566,7 +577,10 @@ object JSONFactory1_4_0 extends MdcLoggable{
// Without them, a request for /obp/v7.0.0/resource-docs hits cache entries warmed by an
// earlier /obp/dynamic-endpoint/resource-docs call and returns the wrong specified_url.
// (Superset of upstream's specifiedUrl-only fix in 17faa09ac.)
- val cacheKey = LOCALISED_RESOURCE_DOC_PREFIX + s"operationId:${operationId}-locale:$locale- isVersion4OrHigher:$isVersion4OrHigher- includeTechnology:$includeTechnology-requestUrl:${resourceDocUpdatedTags.requestUrl}-specifiedUrl:${resourceDocUpdatedTags.specifiedUrl.getOrElse("")}".intern()
+ // The Glossary version belongs in the key too: descriptions embed Glossary text, so a Dynamic
+ // Glossary Item that overrides a static one must not be masked by an hour-old cache entry.
+ // The value is read from an in-memory cache that re-checks the database at most once a second.
+ val cacheKey = LOCALISED_RESOURCE_DOC_PREFIX + s"operationId:${operationId}-locale:$locale- isVersion4OrHigher:$isVersion4OrHigher- includeTechnology:$includeTechnology-requestUrl:${resourceDocUpdatedTags.requestUrl}-specifiedUrl:${resourceDocUpdatedTags.specifiedUrl.getOrElse("")}-glossary:${Glossary.glossaryVersionForCacheKey}".intern()
Caching.memoizeSyncWithImMemory(Some(cacheKey))(CREATE_LOCALISED_RESOURCE_DOC_JSON_TTL.seconds) {
val fieldsDescription =
if (resourceDocUpdatedTags.tags.toString.contains("Dynamic-Entity")
@@ -597,7 +611,11 @@ object JSONFactory1_4_0 extends MdcLoggable{
locale,
resourceDocUpdatedTags.description.stripMargin.trim
)
- val description = resourceDocDescription ++ fieldsDescription
+ // Expand any Glossary placeholders now, against the union of static and Dynamic Glossary
+ // Items. Doing it here rather than when the Resource Doc was built is what lets a Dynamic
+ // Glossary Item override the shipped text in an endpoint description. Translations may
+ // carry placeholders too, hence after translate.
+ val description = Glossary.expandGlossaryPlaceholders(resourceDocDescription ++ fieldsDescription)
val summary = resourceDocUpdatedTags.summary.replaceFirst("""\.(\s*)$""", "$1") // remove the ending dot in summary
val translatedSummary = I18NUtil.ResourceDocTranslation.translate(I18NResourceDocField.SUMMARY, resourceDocUpdatedTags.operationId, locale, summary)
diff --git a/obp-api/src/main/scala/code/api/v2_2_0/JSONFactory2.2.0.scala b/obp-api/src/main/scala/code/api/v2_2_0/JSONFactory2.2.0.scala
index 14e1f90cc0..43b2a82171 100644
--- a/obp-api/src/main/scala/code/api/v2_2_0/JSONFactory2.2.0.scala
+++ b/obp-api/src/main/scala/code/api/v2_2_0/JSONFactory2.2.0.scala
@@ -30,7 +30,7 @@ import org.json4s._
import code.actorsystem.ObpActorConfig
import code.api.Constant._
import code.api.util.APIUtil.{EndpointInfo, MessageDoc, getPropsValue}
-import code.api.util.{APIUtil, ApiPropsWithAlias, CustomJsonFormats, OptionalFieldSerializer}
+import code.api.util.{APIUtil, ApiPropsWithAlias, CustomJsonFormats, Glossary, OptionalFieldSerializer}
import code.api.v1_2_1.BankRoutingJsonV121
import code.api.v1_4_0.JSONFactory1_4_0._
import code.api.v2_1_0.{JSONFactory210, LocationJsonV210, PostCounterpartyBespokeJson, ResourceUserJSON}
@@ -852,7 +852,10 @@ object JSONFactory220 {
MessageDocJson(
process = md.process,
message_format = md.messageFormat,
- description = md.description,
+ // Expanded for the same reason Resource Doc and Glossary descriptions are: no Message Doc
+ // embeds a Glossary Item today, but this is the render path that would leak the raw
+ // placeholder if one ever did.
+ description = Glossary.expandGlossaryPlaceholders(md.description),
outbound_topic = md.outboundTopic,
inbound_topic = md.inboundTopic,
example_outbound_message = decompose(md.exampleOutboundMessage),
diff --git a/obp-api/src/main/scala/code/api/v3_0_0/Http4s300.scala b/obp-api/src/main/scala/code/api/v3_0_0/Http4s300.scala
index 71e1d7d3c0..c87c9ca19d 100644
--- a/obp-api/src/main/scala/code/api/v3_0_0/Http4s300.scala
+++ b/obp-api/src/main/scala/code/api/v3_0_0/Http4s300.scala
@@ -9,7 +9,7 @@ import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
import code.api.v2_0_0.AccountsHelper._
import code.api.util.APIUtil.{EmptyBody, ResourceDoc, _}
-import code.api.util.{ApiRole, FutureUtil}
+import code.api.util.{ApiRole, FutureUtil, Glossary}
import code.api.util.ApiRole._
import code.api.util.ApiTag._
import code.api.util.ErrorMessages._
@@ -1868,7 +1868,24 @@ object Http4s300 {
// ─── getApiGlossary ───────────────────────────────────────────────────────
private val glossaryDocsRequireRole = APIUtil.getPropsAsBoolValue("apiOptions.glossaryDocsRequireRole", false)
- private lazy val cachedGlossaryJson = JSONFactory300.createGlossaryItemsJsonV300(getGlossaryItems)
+
+ // Rendering the Glossary means running every item's markdown through Pegdown, so the result is
+ // cached. The static half never moves, but Dynamic Glossary Items can be created, updated or
+ // deleted at any time (and on any node), so the cache is keyed on a watermark of that table
+ // instead of being a lazy val held for the life of the JVM.
+ private val cachedGlossaryJson =
+ new java.util.concurrent.atomic.AtomicReference[Option[(String, GlossaryItemsJsonV300)]](None)
+
+ private def glossaryJson: GlossaryItemsJsonV300 = {
+ val version = Glossary.dynamicGlossaryItemsVersion
+ cachedGlossaryJson.get() match {
+ case Some((cachedVersion, json)) if cachedVersion == version => json
+ case _ =>
+ val json = JSONFactory300.createGlossaryItemsJsonV300(getGlossaryItems)
+ cachedGlossaryJson.set(Some((version, json)))
+ json
+ }
+ }
val getApiGlossary: HttpRoutes[IO] = HttpRoutes.of[IO] {
case req @ GET -> `prefixPath` / "api" / "glossary" =>
@@ -1879,7 +1896,7 @@ object Http4s300 {
NewStyle.function.hasEntitlement("", cc.user.openOrThrowException("user required").userId, ApiRole.canReadGlossary, Some(cc))
}
} else Future.unit
- } yield cachedGlossaryJson
+ } yield glossaryJson
}
}
@@ -1891,15 +1908,16 @@ object Http4s300 {
"Get Glossary of the API",
"""Get API Glossary
|
- |Returns the glossary of the API.
+ |Returns the glossary of the API: the union of
+ |
+ |* **Static Glossary Items**, compiled into the API and only changing when the API is redeployed, and
+ |* **Dynamic Glossary Items**, held in the database and maintained at runtime over the Glossary Item endpoints (POST / PUT / DELETE /obp/v7.0.0/glossary-items).
|
- |The glossary content is static and only changes when the API is redeployed.
- |This endpoint supports HTTP caching:
+ |A Dynamic Glossary Item whose title matches a static one (compared case insensitively) replaces it, so an operator can correct or localise shipped text without a redeploy.
|
- |* The response includes a **Cache-Control** header (max-age=3600) indicating clients should cache for 1 hour.
- |* The response includes an **ETag** header. Clients can send **If-None-Match** with the ETag value on subsequent requests to receive a **304 Not Modified** if the content has not changed.
+ |The response includes an **ETag** header. Clients can send **If-None-Match** with the ETag value on subsequent requests to receive a **304 Not Modified** if the content has not changed.
|
- |Clients and agents are encouraged to cache the glossary response locally.
+ |Clients and agents are encouraged to cache the glossary response locally and revalidate with the ETag, since Dynamic Glossary Items can change between calls.
|
|""",
EmptyBody,
diff --git a/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala b/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala
index 8385842296..4aaccd6054 100644
--- a/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala
+++ b/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala
@@ -29,7 +29,7 @@ package code.api.v3_0_0
import code.api.Constant._
import code.api.util.APIUtil._
import code.api.util.Glossary.GlossaryItem
-import code.api.util.{APIUtil, PegdownOptions}
+import code.api.util.{APIUtil, Glossary, PegdownOptions}
import code.api.v1_2_1.JSONFactory._
import code.api.v1_2_1._
import code.api.v1_4_0.JSONFactory1_4_0._
@@ -597,11 +597,15 @@ object JSONFactory300{
}
def createGlossaryItemJsonV300(glossaryItem : GlossaryItem) : GlossaryItemJsonV300 = {
+ // Glossary Items cross-reference each other, so their descriptions carry Glossary placeholders
+ // just as endpoint descriptions do, and have to be expanded here too. Without this the raw
+ // placeholder reaches the client instead of the link it stands for.
+ val description = Glossary.expandGlossaryPlaceholders(glossaryItem.description())
GlossaryItemJsonV300(
title = glossaryItem.title,
description = GlossaryDescriptionJsonV300 (
- markdown = glossaryItem.description().stripMargin, //.replaceAll("\n", ""),
- html = PegdownOptions.convertPegdownToHtmlTweaked(glossaryItem.description()) // .replaceAll("\n", "")
+ markdown = description.stripMargin, //.replaceAll("\n", ""),
+ html = PegdownOptions.convertPegdownToHtmlTweaked(description) // .replaceAll("\n", "")
)
)
}
diff --git a/obp-api/src/main/scala/code/api/v4_0_0/Http4s400.scala b/obp-api/src/main/scala/code/api/v4_0_0/Http4s400.scala
index 4e8bfd1921..946d2e91e5 100644
--- a/obp-api/src/main/scala/code/api/v4_0_0/Http4s400.scala
+++ b/obp-api/src/main/scala/code/api/v4_0_0/Http4s400.scala
@@ -5375,7 +5375,7 @@ object Http4s400 {
"Create My Api Collection Endpoint",
s"""Create Api Collection Endpoint.
|
- |${Glossary.getGlossaryItem("API Collections")}
+ |${Glossary.getGlossaryItem("API Collection")}
|
|
|${userAuthenticationMessage(true)}
@@ -5397,7 +5397,7 @@ object Http4s400 {
"Create My Api Collection Endpoint By Id",
s"""Create Api Collection Endpoint By Id.
|
- |${Glossary.getGlossaryItem("API Collections")}
+ |${Glossary.getGlossaryItem("API Collection")}
|
|${userAuthenticationMessage(true)}
|
@@ -7234,7 +7234,7 @@ object Http4s400 {
"Delete My Api Collection",
s"""Delete Api Collection By API_COLLECTION_ID
|
- |${Glossary.getGlossaryItem("API Collections")}
+ |${Glossary.getGlossaryItem("API Collection")}
|
|${userAuthenticationMessage(true)}
|
@@ -7255,7 +7255,7 @@ object Http4s400 {
"DELETE",
"/my/api-collections/API_COLLECTION_NAME/api-collection-endpoints/OPERATION_ID",
"Delete My Api Collection Endpoint",
- s"""${Glossary.getGlossaryItem("API Collections")}
+ s"""${Glossary.getGlossaryItem("API Collection")}
|
|
|Delete Api Collection Endpoint By OPERATION_ID
@@ -7277,7 +7277,7 @@ object Http4s400 {
"DELETE",
"/my/api-collection-ids/API_COLLECTION_ID/api-collection-endpoints/OPERATION_ID",
"Delete My Api Collection Endpoint By Id",
- s"""${Glossary.getGlossaryItem("API Collections")}
+ s"""${Glossary.getGlossaryItem("API Collection")}
|
|Delete Api Collection Endpoint By OPERATION_ID
|
@@ -7298,7 +7298,7 @@ object Http4s400 {
"DELETE",
"/my/api-collection-ids/API_COLLECTION_ID/api-collection-endpoint-ids/API_COLLECTION_ENDPOINT_ID",
"Delete My Api Collection Endpoint By Id",
- s"""${Glossary.getGlossaryItem("API Collections")}
+ s"""${Glossary.getGlossaryItem("API Collection")}
|Delete Api Collection Endpoint
|Delete Api Collection Endpoint By Id
|
diff --git a/obp-api/src/main/scala/code/api/v7_0_0/Http4s700.scala b/obp-api/src/main/scala/code/api/v7_0_0/Http4s700.scala
index 2e7c5dbf94..c7c56ab224 100644
--- a/obp-api/src/main/scala/code/api/v7_0_0/Http4s700.scala
+++ b/obp-api/src/main/scala/code/api/v7_0_0/Http4s700.scala
@@ -8,7 +8,7 @@ import code.api.Constant._
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
import code.api.util.APIUtil.{EmptyBody, _}
import code.api.util.{APIUtil, ApiRole, CallContext, CustomJsonFormats, Glossary, NewStyle}
-import code.api.util.ApiRole.{canAttachOpenCorridorPromise, canConfigureAmqpBankBroker, canGetMessageOutbox, canRetryMessageOutbox, canSettleOpenCorridor, canCreateAccount, canCreateEntitlementAtAnyBank, canCreateEntitlementAtOneBank, canCreateMetricsArchiveRun, canCreateOrganisation, canCreateRoutingScheme, canCreateTestEmail, canCreateUtilityVendResult, canDeleteEntitlementAtAnyBank, canDeleteOrganisation, canDeleteRoutingScheme, canDeleteSchedulerJobLock, canGetAccountAccessTrace, canGetAnyOrganisation, canGetAnyUser, canGetCacheConfig, canGetCacheInfo, canGetCacheNamespaces, canGetConfig, canGetConnectorHealth, canGetCustomersAtOneBank, canGetDatabasePoolInfo, canGetMetricsDiagnostics, canGetMigrations, canGetSchedulerJobLocks, canReadMetrics, canUpdateBankSupportedRoutingScheme, canUpdateOrganisation, canUpdateRoutingScheme, canUpdateSystemView}
+import code.api.util.ApiRole.{canAttachOpenCorridorPromise, canConfigureAmqpBankBroker, canGetMessageOutbox, canRetryMessageOutbox, canSettleOpenCorridor, canCreateAccount, canCreateEntitlementAtAnyBank, canCreateEntitlementAtOneBank, canCreateMetricsArchiveRun, canCreateGlossaryItem, canCreateOrganisation, canCreateRoutingScheme, canCreateTestEmail, canCreateUtilityVendResult, canDeleteEntitlementAtAnyBank, canDeleteGlossaryItem, canDeleteOrganisation, canDeleteRoutingScheme, canDeleteSchedulerJobLock, canGetAccountAccessTrace, canGetAnyOrganisation, canGetAnyUser, canGetCacheConfig, canGetCacheInfo, canGetCacheNamespaces, canGetConfig, canGetConnectorHealth, canGetCustomersAtOneBank, canGetDatabasePoolInfo, canGetMetricsDiagnostics, canGetMigrations, canGetSchedulerJobLocks, canReadMetrics, canUpdateBankSupportedRoutingScheme, canUpdateGlossaryItem, canUpdateOrganisation, canUpdateRoutingScheme, canUpdateSystemView}
import code.api.util.CommonsEmailWrapper
import code.model.dataAccess.{AuthUser, BankAccountCreation, MappedBank, ResourceUser}
import code.consent.Consents
@@ -31,6 +31,7 @@ import code.migration.MigrationScriptLogProvider
import code.bankconnectors.{Connector => BankConnector}
import code.entitlement.Entitlement
import code.organisation.Organisations
+import code.glossaryitem.DynamicGlossaryItems
import code.routingscheme.{RoutingSchemes, RoutingSchemeValidation}
import code.payeelookup.PayeeLookups
import code.utilitypayment.{UtilityCallbackDispatcher, UtilityPaymentCallbacks}
@@ -3464,6 +3465,351 @@ object Http4s700 {
// ── End Routing Schemes ───────────────────────────────────────────────────
+ // ── Dynamic Glossary Items ────────────────────────────────────────────────
+ // The Glossary served by GET /obp/v3.0.0/api/glossary is the union of the static Glossary
+ // Items compiled into Glossary.scala and the Dynamic Glossary Items maintained here. A
+ // Dynamic Item replaces a static one of the same title (compared case insensitively), so an
+ // operator can correct, extend or localise shipped text without redeploying the API.
+ //
+ // Title is the resource key. TITLE segments may contain '.' and spaces — http4s matches path
+ // segments by '/' and url-decodes them, so "Bank.bank_id" is a single segment.
+
+ private val GlossaryItemMaxTitleLength = 255
+
+ private def isValidGlossaryItemTitle(title: String): Boolean =
+ title.nonEmpty && title.length <= GlossaryItemMaxTitleLength
+
+ val createDynamicGlossaryItem: HttpRoutes[IO] = HttpRoutes.of[IO] {
+ case req @ POST -> `prefixPath` / "glossary-items" =>
+ EndpointHelpers.withUserAndBodyCreated[JSONFactory700.PostGlossaryItemJsonV700, JSONFactory700.GlossaryItemJsonV700](req) { (user, body, cc) =>
+ // A json null extracts to a null String rather than failing, so guard before trimming.
+ val title = Option(body.title).map(_.trim).getOrElse("")
+ for {
+ _ <- Helper.booleanToFuture(InvalidGlossaryItemTitle, 400, Some(cc))(isValidGlossaryItemTitle(title))
+ existing <- Future(DynamicGlossaryItems.dynamicGlossaryItem.vend.getDynamicGlossaryItemByTitle(title))
+ _ <- Helper.booleanToFuture(GlossaryItemAlreadyExists, 409, Some(cc))(existing.isEmpty)
+ overridesStaticItem = body.overrides_static_item.getOrElse(false)
+ // Shadowing a static Item is refused unless it was asked for, so it is never a side
+ // effect of picking a title that happens to be taken.
+ _ <- Helper.booleanToFuture(GlossaryItemShadowsStaticItem, 409, Some(cc)) {
+ overridesStaticItem || !Glossary.staticGlossaryItemExists(title)
+ }
+ created <- Future {
+ DynamicGlossaryItems.dynamicGlossaryItem.vend.createDynamicGlossaryItem(
+ title = title,
+ description = body.description,
+ overridesStaticItem = overridesStaticItem,
+ createdByUserId = user.userId
+ )
+ }.map(unboxFullOrFail(_, Some(cc), CreateGlossaryItemError, 400))
+ // Reflect the write on this node at once; other nodes pick it up via the watermark.
+ _ = Glossary.invalidateGlossaryItemCache()
+ } yield JSONFactory700.createGlossaryItemJsonV700(created)
+ }
+ }
+
+ resourceDocs += ResourceDoc(
+ implementedInApiVersion,
+ nameOf(createDynamicGlossaryItem),
+ "POST",
+ "/glossary-items",
+ "Create Dynamic Glossary Item",
+ """Create a Dynamic Glossary Item.
+ |
+ |`description` is markdown, the same flavour the static Glossary uses. It is returned as both markdown and rendered html.
+ |
+ |Titles are unique case insensitively across Dynamic Glossary Items — creating one that already exists returns 409; update it with `PUT /glossary-items/TITLE` instead.
+ |
+ |**Overriding a static Glossary Item.** If the title matches one of the API's own (static) Glossary Items, the request is refused with `OBP-30577` unless you set `overrides_static_item: true`. That way an item never displaces shipped documentation just because its title happened to be taken. When you do declare it, this item replaces the static one everywhere the Glossary is served — `GET /obp/v3.0.0/api/glossary` and the Glossary text embedded in endpoint descriptions — and deleting it restores the static text.
+ |
+ |The response reports both `overrides_static_item` (what you declared) and `shadows_static_glossary_item` (whether a static Item of this title exists right now). They differ if a static Item is added later with a title this one already used; that case is reported in the API logs at startup.
+ |
+ |Authentication is Required.""".stripMargin,
+ JSONFactory700.PostGlossaryItemJsonV700(
+ title = "Bank.bank_id",
+ description = "The unique identifier of the Bank on this OBP instance.\n\nExample value: gh.29.uk",
+ overrides_static_item = Some(true)
+ ),
+ JSONFactory700.GlossaryItemJsonV700(
+ glossary_item_id = "8f2b1c44-1f2a-4c3d-9a7e-5b6c7d8e9f01",
+ title = "Bank.bank_id",
+ description = JSONFactory700.GlossaryItemDescriptionJsonV700(
+ markdown = "The unique identifier of the Bank on this OBP instance.",
+ html = "
The unique identifier of the Bank on this OBP instance.
" + ), + overrides_static_item = true, + shadows_static_glossary_item = true, + created_by_user_id = "9ca9a7e4-6d02-40e3-a129-0b2bf89de9b1", + created_at = new java.util.Date(), + updated_at = new java.util.Date() + ), + List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, + InvalidGlossaryItemTitle, GlossaryItemAlreadyExists, CreateGlossaryItemError, UnknownError), + apiTagDocumentation :: Nil, + Some(List(canCreateGlossaryItem)), + http4sPartialFunction = Some(createDynamicGlossaryItem) + ) + + val getDynamicGlossaryItems: HttpRoutes[IO] = HttpRoutes.of[IO] { + case req @ GET -> `prefixPath` / "glossary-items" => + EndpointHelpers.withUser(req) { (_, cc) => + val q = req.uri.query.params + val title = q.get("title").filter(_.nonEmpty) + val limit = q.get("limit").flatMap(s => scala.util.Try(s.toInt).toOption).getOrElse(100).max(1).min(500) + val offset = q.get("offset").flatMap(s => scala.util.Try(s.toInt).toOption).getOrElse(0).max(0) + for { + page <- DynamicGlossaryItems.dynamicGlossaryItem.vend.getDynamicGlossaryItems(title, limit, offset) + .map(unboxFullOrFail(_, Some(cc), UnknownError, 500)) + (rows, total) = page + } yield JSONFactory700.createGlossaryItemsJsonV700(rows, total, limit, offset) + } + } + + resourceDocs += ResourceDoc( + implementedInApiVersion, + nameOf(getDynamicGlossaryItems), + "GET", + "/glossary-items", + "Get Dynamic Glossary Items", + """Returns the Dynamic Glossary Items only — the ones held in the database and maintained over these endpoints. + | + |For the Glossary as consumers see it (static Glossary Items unioned with these), call `GET /obp/v3.0.0/api/glossary`. + | + |Optional query parameters: + | + |* `title` — return only items whose title contains this value (case insensitive). + |* `limit` — page size, default 100, maximum 500. + |* `offset` — number of items to skip, default 0. + | + |Authentication is Required.""".stripMargin, + EmptyBody, + JSONFactory700.GlossaryItemsJsonV700( + glossary_items = List( + JSONFactory700.GlossaryItemJsonV700( + glossary_item_id = "8f2b1c44-1f2a-4c3d-9a7e-5b6c7d8e9f01", + title = "Bank.bank_id", + description = JSONFactory700.GlossaryItemDescriptionJsonV700( + markdown = "The unique identifier of the Bank on this OBP instance.", + html = "The unique identifier of the Bank on this OBP instance.
" + ), + overrides_static_item = true, + shadows_static_glossary_item = true, + created_by_user_id = "9ca9a7e4-6d02-40e3-a129-0b2bf89de9b1", + created_at = new java.util.Date(), + updated_at = new java.util.Date() + ) + ), + pagination = JSONFactory700.GlossaryItemPaginationJsonV700(total = 1, limit = 100, offset = 0) + ), + List($AuthenticatedUserIsRequired, UnknownError), + apiTagDocumentation :: Nil, + None, + http4sPartialFunction = Some(getDynamicGlossaryItems) + ) + + val getDynamicGlossaryItem: HttpRoutes[IO] = HttpRoutes.of[IO] { + case req @ GET -> `prefixPath` / "glossary-items" / titleSegment => + EndpointHelpers.withUser(req) { (_, cc) => + for { + row <- Future(DynamicGlossaryItems.dynamicGlossaryItem.vend.getDynamicGlossaryItemByTitle(titleSegment)) + .map(unboxFullOrFail(_, Some(cc), GlossaryItemNotFound, 404)) + } yield JSONFactory700.createGlossaryItemJsonV700(row) + } + } + + resourceDocs += ResourceDoc( + implementedInApiVersion, + nameOf(getDynamicGlossaryItem), + "GET", + "/glossary-items/TITLE", + "Get Dynamic Glossary Item", + """Returns one Dynamic Glossary Item by title. The title is matched case insensitively. + | + |Returns 404 if no Dynamic Glossary Item has this title, even when a static Glossary Item does — this endpoint only sees Dynamic Items. + | + |Authentication is Required.""".stripMargin, + EmptyBody, + JSONFactory700.GlossaryItemJsonV700( + glossary_item_id = "8f2b1c44-1f2a-4c3d-9a7e-5b6c7d8e9f01", + title = "Bank.bank_id", + description = JSONFactory700.GlossaryItemDescriptionJsonV700( + markdown = "The unique identifier of the Bank on this OBP instance.", + html = "The unique identifier of the Bank on this OBP instance.
" + ), + overrides_static_item = true, + shadows_static_glossary_item = true, + created_by_user_id = "9ca9a7e4-6d02-40e3-a129-0b2bf89de9b1", + created_at = new java.util.Date(), + updated_at = new java.util.Date() + ), + List($AuthenticatedUserIsRequired, GlossaryItemNotFound, UnknownError), + apiTagDocumentation :: Nil, + None, + http4sPartialFunction = Some(getDynamicGlossaryItem) + ) + + val updateDynamicGlossaryItem: HttpRoutes[IO] = HttpRoutes.of[IO] { + case req @ PUT -> `prefixPath` / "glossary-items" / titleSegment => + EndpointHelpers.withUserAndBody[JSONFactory700.PutGlossaryItemJsonV700, JSONFactory700.GlossaryItemJsonV700](req) { (_, body, cc) => + for { + _ <- Future(DynamicGlossaryItems.dynamicGlossaryItem.vend.getDynamicGlossaryItemByTitle(titleSegment)) + .map(unboxFullOrFail(_, Some(cc), GlossaryItemNotFound, 404)) + updated <- Future { + DynamicGlossaryItems.dynamicGlossaryItem.vend.updateDynamicGlossaryItem( + titleSegment, body.description, body.overrides_static_item) + }.map(unboxFullOrFail(_, Some(cc), UpdateGlossaryItemError, 400)) + _ = Glossary.invalidateGlossaryItemCache() + } yield JSONFactory700.createGlossaryItemJsonV700(updated) + } + } + + resourceDocs += ResourceDoc( + implementedInApiVersion, + nameOf(updateDynamicGlossaryItem), + "PUT", + "/glossary-items/TITLE", + "Update Dynamic Glossary Item", + """Replaces the description of a Dynamic Glossary Item. The title is the resource key and cannot be changed here — to rename an item, delete it and create a new one. + | + |`description` is markdown. + | + |`overrides_static_item` is optional and left as it is when omitted. Set it to confirm an override that was flagged as undeclared in the logs, or to false to record that this item is not meant to shadow static documentation. + | + |Authentication is Required.""".stripMargin, + JSONFactory700.PutGlossaryItemJsonV700( + description = "The unique identifier of the Bank on this OBP instance.\n\nExample value: gh.29.uk", + overrides_static_item = Some(true) + ), + JSONFactory700.GlossaryItemJsonV700( + glossary_item_id = "8f2b1c44-1f2a-4c3d-9a7e-5b6c7d8e9f01", + title = "Bank.bank_id", + description = JSONFactory700.GlossaryItemDescriptionJsonV700( + markdown = "The unique identifier of the Bank on this OBP instance.", + html = "The unique identifier of the Bank on this OBP instance.
" + ), + overrides_static_item = true, + shadows_static_glossary_item = true, + created_by_user_id = "9ca9a7e4-6d02-40e3-a129-0b2bf89de9b1", + created_at = new java.util.Date(), + updated_at = new java.util.Date() + ), + List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, + GlossaryItemNotFound, UpdateGlossaryItemError, UnknownError), + apiTagDocumentation :: Nil, + Some(List(canUpdateGlossaryItem)), + http4sPartialFunction = Some(updateDynamicGlossaryItem) + ) + + val deleteDynamicGlossaryItem: HttpRoutes[IO] = HttpRoutes.of[IO] { + case req @ DELETE -> `prefixPath` / "glossary-items" / titleSegment => + EndpointHelpers.withUserDelete(req) { (_, cc) => + for { + _ <- Future(DynamicGlossaryItems.dynamicGlossaryItem.vend.getDynamicGlossaryItemByTitle(titleSegment)) + .map(unboxFullOrFail(_, Some(cc), GlossaryItemNotFound, 404)) + _ <- Future(DynamicGlossaryItems.dynamicGlossaryItem.vend.deleteDynamicGlossaryItem(titleSegment)) + .map(unboxFullOrFail(_, Some(cc), DeleteGlossaryItemError, 400)) + _ = Glossary.invalidateGlossaryItemCache() + } yield () + } + } + + resourceDocs += ResourceDoc( + implementedInApiVersion, + nameOf(deleteDynamicGlossaryItem), + "DELETE", + "/glossary-items/TITLE", + "Delete Dynamic Glossary Item", + """Deletes a Dynamic Glossary Item. + | + |If the item was shadowing a static Glossary Item of the same title, the static text is served again from the next call to `GET /obp/v3.0.0/api/glossary`. + | + |Authentication is Required.""".stripMargin, + EmptyBody, + EmptyBody, + List($AuthenticatedUserIsRequired, UserHasMissingRoles, GlossaryItemNotFound, + DeleteGlossaryItemError, UnknownError), + apiTagDocumentation :: Nil, + Some(List(canDeleteGlossaryItem)), + http4sPartialFunction = Some(deleteDynamicGlossaryItem) + ) + + // The Glossary itself, at v7.0.0. v3.0.0 serves the same merged content, but that version is + // STABLE and its JSON cannot gain fields, so the provenance flags live here. + + private val v7GlossaryDocsRequireRole = APIUtil.getPropsAsBoolValue("apiOptions.glossaryDocsRequireRole", false) + + // Same key-based expiry as the v3.0.0 endpoint: rendering every item through Pegdown is too + // expensive per request, and a lazy val would never pick up a Dynamic Glossary Item change. + private val cachedApiGlossaryJson = + new java.util.concurrent.atomic.AtomicReference[Option[(String, JSONFactory700.ApiGlossaryJsonV700)]](None) + + private def apiGlossaryJson: JSONFactory700.ApiGlossaryJsonV700 = { + val version = Glossary.dynamicGlossaryItemsVersion + cachedApiGlossaryJson.get() match { + case Some((cachedVersion, json)) if cachedVersion == version => json + case _ => + val json = JSONFactory700.createApiGlossaryJsonV700(APIUtil.getGlossaryItems) + cachedApiGlossaryJson.set(Some((version, json))) + json + } + } + + val getApiGlossary: HttpRoutes[IO] = HttpRoutes.of[IO] { + case req @ GET -> `prefixPath` / "api" / "glossary" => + EndpointHelpers.executeAndRespond(req) { cc => + for { + _ <- if (v7GlossaryDocsRequireRole) { + Helper.booleanToFuture(AuthenticatedUserIsRequired, failCode = 401, cc = Some(cc))(cc.user.isDefined).flatMap { _ => + NewStyle.function.hasEntitlement("", cc.user.openOrThrowException("user required").userId, ApiRole.canReadGlossary, Some(cc)) + } + } else Future.unit + } yield apiGlossaryJson + } + } + + resourceDocs += ResourceDoc( + implementedInApiVersion, + nameOf(getApiGlossary), + "GET", + "/api/glossary", + "Get Glossary of the API", + """Returns the glossary of the API: the union of + | + |* **Static Glossary Items**, compiled into the API and only changing when the API is redeployed, and + |* **Dynamic Glossary Items**, held in the database and maintained over the Glossary Item endpoints. + | + |Each entry reports where it came from: + | + |* `is_dynamic` — true when the entry is a Dynamic Glossary Item rather than one shipped with the API. + |* `overrides_static_item` — true when this Dynamic Item is displacing a static Glossary Item of the same title. Overriding has to be declared when the Item is created, so this is deliberate; the API also reports these in its logs at startup. + | + |This is the same Glossary that `GET /obp/v3.0.0/api/glossary` returns. That version is STABLE and its JSON cannot change, so it omits the two fields above and is otherwise identical. + | + |The response includes an **ETag** header. Clients can send **If-None-Match** with the ETag value on subsequent requests to receive a **304 Not Modified** if the content has not changed. Cache the response locally and revalidate with the ETag, since Dynamic Glossary Items can change between calls. + | + |""", + EmptyBody, + JSONFactory700.ApiGlossaryJsonV700( + glossary_items = List( + JSONFactory700.ApiGlossaryItemJsonV700( + title = "Bank.bank_id", + description = JSONFactory700.GlossaryItemDescriptionJsonV700( + markdown = "The unique identifier of the Bank on this OBP instance.", + html = "The unique identifier of the Bank on this OBP instance.
" + ), + is_dynamic = true, + overrides_static_item = true + ) + ) + ), + List(UnknownError), + apiTagDocumentation :: Nil, + None, + http4sPartialFunction = Some(getApiGlossary) + ) + + // ── End Dynamic Glossary Items ──────────────────────────────────────────── + // ── Payee Lookup ────────────────────────────────────────────────────────── // Generic "confirmation-of-payee" / pre-payment lookup. Caller supplies // an identifier { scheme, address } pair (e.g. {TZ.MSISDN, 255778300336}); diff --git a/obp-api/src/main/scala/code/api/v7_0_0/JSONFactory7.0.0.scala b/obp-api/src/main/scala/code/api/v7_0_0/JSONFactory7.0.0.scala index f7cbdf5157..bc043efea0 100644 --- a/obp-api/src/main/scala/code/api/v7_0_0/JSONFactory7.0.0.scala +++ b/obp-api/src/main/scala/code/api/v7_0_0/JSONFactory7.0.0.scala @@ -3,6 +3,7 @@ package code.api.v7_0_0 import code.api.Constant import code.api.util.{APIUtil, AuthRateLimiter, CallContext, ExampleValue, RateLimitingUtil, SelfServiceRateLimiter} import code.api.util.ErrorMessages +import code.api.util.{Glossary, PegdownOptions} import code.api.util.ErrorMessages.MandatoryPropertyIsNotSet import code.api.v2_0_0.EntitlementJSONs import code.api.v3_0_0.{UserJsonV300, ViewsJSON300} @@ -922,6 +923,106 @@ object JSONFactory700 extends MdcLoggable with code.api.util.CustomJsonFormats { ) ) + // ── Dynamic Glossary Item JSON case classes ───────────────────────────────── + // Description is carried as markdown on the way in and returned as both markdown and rendered + // html on the way out, matching GlossaryDescriptionJsonV300 as served by GET /api/glossary. + + case class PostGlossaryItemJsonV700( + title: String, + description: String, + // Declared intent to shadow a static Glossary Item of the same title. Absent or false means + // a collision with a static title is refused, so shadowing is never accidental. + overrides_static_item: Option[Boolean] + ) + + case class PutGlossaryItemJsonV700( + description: String, + overrides_static_item: Option[Boolean] + ) + + case class GlossaryItemDescriptionJsonV700(markdown: String, html: String) + + case class GlossaryItemJsonV700( + glossary_item_id: String, + title: String, + description: GlossaryItemDescriptionJsonV700, + // What the operator declared when creating or updating the item. + overrides_static_item: Boolean, + // What is actually true right now: a static Glossary Item of this title exists. The two + // differ when a static Item was added after this one, which is worth someone's attention. + shadows_static_glossary_item: Boolean, + created_by_user_id: String, + created_at: java.util.Date, + updated_at: java.util.Date + ) + + case class GlossaryItemPaginationJsonV700(total: Int, limit: Int, offset: Int) + + case class GlossaryItemsJsonV700( + glossary_items: List[GlossaryItemJsonV700], + pagination: GlossaryItemPaginationJsonV700 + ) + + def createGlossaryItemJsonV700(r: code.glossaryitem.DynamicGlossaryItemTrait): GlossaryItemJsonV700 = + GlossaryItemJsonV700( + glossary_item_id = r.glossaryItemId, + title = r.title, + description = GlossaryItemDescriptionJsonV700( + markdown = r.description, + html = PegdownOptions.convertPegdownToHtmlTweaked(r.description) + ), + overrides_static_item = r.overridesStaticItem, + // Flagged so a caller can see at a glance that this item is shadowing shipped text. + shadows_static_glossary_item = Glossary.staticGlossaryItemExists(r.title), + created_by_user_id = r.createdByUserId, + created_at = r.createdAt, + updated_at = r.updatedAt + ) + + // ── The Glossary as served: static and Dynamic Items merged ───────────────── + // Distinct from GlossaryItemJsonV700 above, which is the management view of one Dynamic Item. + // v3.0.0 serves the same Glossary without these provenance fields; that version is STABLE and + // its JSON must not change, so the flags are offered here instead. + + case class ApiGlossaryItemJsonV700( + title: String, + description: GlossaryItemDescriptionJsonV700, + // True when this entry comes from the DynamicGlossaryItem table rather than the API source. + is_dynamic: Boolean, + // True when this Dynamic Item is displacing a static Glossary Item of the same title. + overrides_static_item: Boolean + ) + + case class ApiGlossaryJsonV700(glossary_items: List[ApiGlossaryItemJsonV700]) + + def createApiGlossaryItemJsonV700(item: Glossary.GlossaryItem): ApiGlossaryItemJsonV700 = { + // Glossary Items cross-reference each other, so expand their placeholders as well. + val description = Glossary.expandGlossaryPlaceholders(item.description()) + ApiGlossaryItemJsonV700( + title = item.title, + description = GlossaryItemDescriptionJsonV700( + markdown = description.stripMargin, + html = PegdownOptions.convertPegdownToHtmlTweaked(description) + ), + is_dynamic = item.isDynamic, + overrides_static_item = item.shadowsStaticItem + ) + } + + def createApiGlossaryJsonV700(items: List[Glossary.GlossaryItem]): ApiGlossaryJsonV700 = + ApiGlossaryJsonV700(glossary_items = items.map(createApiGlossaryItemJsonV700)) + + def createGlossaryItemsJsonV700( + rows: List[code.glossaryitem.DynamicGlossaryItemTrait], + total: Int, + limit: Int, + offset: Int + ): GlossaryItemsJsonV700 = + GlossaryItemsJsonV700( + glossary_items = rows.map(createGlossaryItemJsonV700), + pagination = GlossaryItemPaginationJsonV700(total = total, limit = limit, offset = offset) + ) + // ── Qualified Identifier ──────────────────────────────────────────────────── // A (scheme, value) triple where the scheme qualifies the value's namespace. // Used wherever the API takes or returns an identifier that belongs to a diff --git a/obp-api/src/main/scala/code/glossaryitem/DynamicGlossaryItem.scala b/obp-api/src/main/scala/code/glossaryitem/DynamicGlossaryItem.scala new file mode 100644 index 0000000000..68808baf77 --- /dev/null +++ b/obp-api/src/main/scala/code/glossaryitem/DynamicGlossaryItem.scala @@ -0,0 +1,125 @@ +package code.glossaryitem + +import code.util.MappedUUID +import com.openbankproject.commons.ExecutionContext.Implicits.global +import net.liftweb.common.Box +import net.liftweb.mapper._ +import net.liftweb.util.Helpers.tryo + +import scala.concurrent.Future + +object MappedDynamicGlossaryItemProvider extends DynamicGlossaryItemProvider { + + override def createDynamicGlossaryItem( + title: String, + description: String, + overridesStaticItem: Boolean, + createdByUserId: String + ): Box[DynamicGlossaryItemTrait] = { + tryo { + DynamicGlossaryItem.create + .Title(title) + .TitleLowerCase(title.toLowerCase) + .Description(description) + .OverridesStaticItem(overridesStaticItem) + .CreatedByUserId(createdByUserId) + .saveMe() + } + } + + override def getDynamicGlossaryItemByTitle(title: String): Box[DynamicGlossaryItemTrait] = + DynamicGlossaryItem.find(By(DynamicGlossaryItem.TitleLowerCase, title.toLowerCase)) + + override def getDynamicGlossaryItems( + titleFilter: Option[String], + limit: Int, + offset: Int + ): Future[Box[(List[DynamicGlossaryItemTrait], Int)]] = Future { + tryo { + val baseQuery: List[QueryParam[DynamicGlossaryItem]] = + titleFilter.map(t => Like(DynamicGlossaryItem.TitleLowerCase, s"%${t.toLowerCase}%")).toList + // Count BEFORE applying limit/offset so the caller can page. + val total: Int = DynamicGlossaryItem.count(baseQuery: _*).toInt + val rows: List[DynamicGlossaryItem] = DynamicGlossaryItem.findAll( + (baseQuery + :+ OrderBy(DynamicGlossaryItem.TitleLowerCase, Ascending) + :+ StartAt[DynamicGlossaryItem](offset) + :+ MaxRows[DynamicGlossaryItem](limit)): _* + ) + (rows.asInstanceOf[List[DynamicGlossaryItemTrait]], total) + } + } + + override def getAllDynamicGlossaryItems: Box[List[DynamicGlossaryItemTrait]] = + tryo { DynamicGlossaryItem.findAll().asInstanceOf[List[DynamicGlossaryItemTrait]] } + + override def getDynamicGlossaryItemsVersion: Box[String] = tryo { + // Row count catches inserts and deletes; the newest LastUpdate catches edits. A delete plus an + // insert leaves the count unchanged but moves LastUpdate forward, so the pair is enough. + val count = DynamicGlossaryItem.count + val newest = DynamicGlossaryItem + .findAll(OrderBy(DynamicGlossaryItem.LastUpdate, Descending), MaxRows[DynamicGlossaryItem](1)) + .headOption + .map(_.LastUpdate.get.getTime) + .getOrElse(0L) + s"$count-$newest" + } + + override def updateDynamicGlossaryItem( + title: String, + description: String, + overridesStaticItem: Option[Boolean] + ): Box[DynamicGlossaryItemTrait] = { + DynamicGlossaryItem.find(By(DynamicGlossaryItem.TitleLowerCase, title.toLowerCase)).flatMap { row => + tryo { + row.Description(description) + overridesStaticItem.foreach(v => row.OverridesStaticItem(v)) + row.LastUpdate(new java.util.Date()) + row.saveMe() + } + } + } + + override def deleteDynamicGlossaryItem(title: String): Box[Boolean] = { + DynamicGlossaryItem.find(By(DynamicGlossaryItem.TitleLowerCase, title.toLowerCase)).flatMap { row => + tryo { row.delete_! } + } + } +} + +class DynamicGlossaryItem extends DynamicGlossaryItemTrait with LongKeyedMapper[DynamicGlossaryItem] with IdPK { + def getSingleton = DynamicGlossaryItem + + object GlossaryItemId extends MappedUUID(this) + object Title extends MappedString(this, 255) + // Lower-cased copy of Title, so uniqueness and lookup are case insensitive on every database + // regardless of its collation. The static Glossary is looked up case insensitively too. + object TitleLowerCase extends MappedString(this, 255) + object Description extends MappedText(this) // Markdown, the same flavour the static Glossary uses + // Declared intent to shadow a static Glossary Item of the same title. See the trait. + object OverridesStaticItem extends MappedBoolean(this) { + override def defaultValue = false + } + object CreatedByUserId extends MappedString(this, 255) + object CreationDate extends MappedDateTime(this) { + override def defaultValue = new java.util.Date() + } + object LastUpdate extends MappedDateTime(this) { + override def defaultValue = new java.util.Date() + } + + override def glossaryItemId: String = GlossaryItemId.get + override def title: String = Title.get + override def description: String = Description.get + override def overridesStaticItem: Boolean = OverridesStaticItem.get + override def createdByUserId: String = CreatedByUserId.get + override def createdAt: java.util.Date = CreationDate.get + override def updatedAt: java.util.Date = LastUpdate.get +} + +object DynamicGlossaryItem extends DynamicGlossaryItem with LongKeyedMetaMapper[DynamicGlossaryItem] { + override def dbTableName = "DynamicGlossaryItem" + // LastUpdate is indexed because getDynamicGlossaryItemsVersion reads the newest row on every + // Glossary call, to decide whether the cached rendering is still valid. + override def dbIndexes = UniqueIndex(TitleLowerCase) :: Index(LastUpdate) :: super.dbIndexes +} diff --git a/obp-api/src/main/scala/code/glossaryitem/DynamicGlossaryItemTrait.scala b/obp-api/src/main/scala/code/glossaryitem/DynamicGlossaryItemTrait.scala new file mode 100644 index 0000000000..2560d4fa25 --- /dev/null +++ b/obp-api/src/main/scala/code/glossaryitem/DynamicGlossaryItemTrait.scala @@ -0,0 +1,70 @@ +package code.glossaryitem + +import net.liftweb.common.Box +import net.liftweb.util.SimpleInjector + +import scala.concurrent.Future + +object DynamicGlossaryItems extends SimpleInjector { + val dynamicGlossaryItem = new Inject(() => buildOne) {} + + def buildOne: DynamicGlossaryItemProvider = MappedDynamicGlossaryItemProvider +} + +/** + * Dynamic Glossary Items are Glossary Items held in the database and maintained over the + * /glossary-items endpoints, as opposed to the static ones compiled into Glossary.scala. + * + * Title is the resource key and is unique case insensitively, matching the way the static + * Glossary is looked up. + */ +trait DynamicGlossaryItemProvider { + + def createDynamicGlossaryItem( + title: String, + description: String, + overridesStaticItem: Boolean, + createdByUserId: String + ): Box[DynamicGlossaryItemTrait] + + def getDynamicGlossaryItemByTitle(title: String): Box[DynamicGlossaryItemTrait] + + def getDynamicGlossaryItems( + titleFilter: Option[String], + limit: Int, + offset: Int + ): Future[Box[(List[DynamicGlossaryItemTrait], Int)]] + + /** Every Dynamic Glossary Item. Used to build the union returned by GET /api/glossary. */ + def getAllDynamicGlossaryItems: Box[List[DynamicGlossaryItemTrait]] + + /** + * A cheap watermark that changes whenever any Dynamic Glossary Item is added, changed or + * removed. GET /api/glossary caches its rendered JSON against this rather than for the life + * of the JVM, so an edit on any node is picked up on the next call. + */ + def getDynamicGlossaryItemsVersion: Box[String] + + def updateDynamicGlossaryItem( + title: String, + description: String, + overridesStaticItem: Option[Boolean] + ): Box[DynamicGlossaryItemTrait] + + def deleteDynamicGlossaryItem(title: String): Box[Boolean] +} + +trait DynamicGlossaryItemTrait { + def glossaryItemId: String + def title: String + def description: String + /** + * Declared intent: the operator said this item deliberately overrides a static Glossary Item of + * the same title. Creating one that collides with a static title is refused unless this is set, + * so shadowing is never an accident of title choice. + */ + def overridesStaticItem: Boolean + def createdByUserId: String + def createdAt: java.util.Date + def updatedAt: java.util.Date +} diff --git a/obp-api/src/test/scala/code/api/sweep/SuccessSweepTest.scala b/obp-api/src/test/scala/code/api/sweep/SuccessSweepTest.scala index 05202186fb..f8fae207a7 100644 --- a/obp-api/src/test/scala/code/api/sweep/SuccessSweepTest.scala +++ b/obp-api/src/test/scala/code/api/sweep/SuccessSweepTest.scala @@ -93,7 +93,10 @@ class SuccessSweepTest extends ServerSetupWithTestData with DefaultUsers with Sw "OBPv4.0.0-getMyApiCollectionByName" -> "400 OBP-30079: no ApiCollection named API_COLLECTION_NAME", "OBPv4.0.0-getMyApiCollectionEndpoints" -> "400 OBP-30079: no ApiCollection named API_COLLECTION_NAME", "OBPv6.0.0-getWebUiProp" -> "400 OBP-08003: no WebUi prop named WEBUI_PROP_NAME", - "OBPv7.0.0-getRoutingScheme" -> "404 OBP-30514: no routing scheme named SCHEME" + "OBPv7.0.0-getRoutingScheme" -> "404 OBP-30514: no routing scheme named SCHEME", + "OBPv7.0.0-getDynamicGlossaryItem" -> ("404 OBP-30571: no Dynamic Glossary Item titled TITLE. " + + "Like SCHEME above, TITLE is a placeholder the catalog does not substitute, so the literal " + + "path is called") ) private def get(path: String, headers: Map[String, String]): (Int, JValue) = { diff --git a/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala b/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala index 85e2316c6b..971e6c95bb 100644 --- a/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala +++ b/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala @@ -137,6 +137,10 @@ class JSONFactory1_4_0Test extends code.setup.ServerSetup { } scenario("Technology field should be http4s when includeTechnology=true and doc is http4s") { + // Touch Implementations7_0_0 first: resourceDocs lives on the enclosing Http4s700 object and is + // filled by the inner object at class init, so it is empty until something references the + // inner one. Without this the scenario only passes when a v7-touching suite ran before it. + code.api.v7_0_0.Http4s700.Implementations7_0_0 val http4sDoc: ResourceDoc = code.api.v7_0_0.Http4s700.resourceDocs.head val json = JSONFactory1_4_0.createLocalisedResourceDocJson(http4sDoc, true, None, includeTechnology = true, urlParameters, "JSON request body fields:", "JSON response body fields:") json.implemented_by.technology shouldBe Some(Constant.TECHNOLOGY_HTTP4S) diff --git a/obp-api/src/test/scala/code/api/v7_0_0/DynamicGlossaryItemTest.scala b/obp-api/src/test/scala/code/api/v7_0_0/DynamicGlossaryItemTest.scala new file mode 100644 index 0000000000..3edf7f3831 --- /dev/null +++ b/obp-api/src/test/scala/code/api/v7_0_0/DynamicGlossaryItemTest.scala @@ -0,0 +1,450 @@ +package code.api.v7_0_0 + +import code.api.util.APIUtil.OAuth._ +import code.api.util.ApiRole._ +import code.api.util.ErrorMessages._ +import code.api.v3_0_0.GlossaryItemsJsonV300 +import code.api.v7_0_0.JSONFactory700.{ApiGlossaryJsonV700, GlossaryItemJsonV700, GlossaryItemsJsonV700, PostGlossaryItemJsonV700, PutGlossaryItemJsonV700} +import code.api.v7_0_0.Http4s700.Implementations7_0_0 +import code.entitlement.Entitlement +import code.setup.ServerSetupWithTestData +import com.github.dwickern.macros.NameOf.nameOf +import com.openbankproject.commons.model.ErrorMessage +import com.openbankproject.commons.util.ApiVersion +import org.json4s._ +import org.json4s.native.Serialization.write +import org.scalatest.Tag + +import java.util.UUID + +/** + * Dynamic Glossary Items: role protected CRUD in v7.0.0, and the union they form with the static + * Glossary in GET /obp/v3.0.0/api/glossary. + * + * The roles are system level, so entitlements are granted with an empty bank id. Entitlements + * accumulate on a user across scenarios, so each "without the role" check calls as a user that no + * earlier scenario granted that role to. + */ +class DynamicGlossaryItemTest extends ServerSetupWithTestData { + + object VersionOfApi extends Tag(ApiVersion.v7_0_0.toString) + object ApiEndpoint1 extends Tag(nameOf(Implementations7_0_0.createDynamicGlossaryItem)) + object ApiEndpoint2 extends Tag(nameOf(Implementations7_0_0.getDynamicGlossaryItems)) + object ApiEndpoint3 extends Tag(nameOf(Implementations7_0_0.getDynamicGlossaryItem)) + object ApiEndpoint4 extends Tag(nameOf(Implementations7_0_0.updateDynamicGlossaryItem)) + object ApiEndpoint5 extends Tag(nameOf(Implementations7_0_0.deleteDynamicGlossaryItem)) + + def v3 = baseRequest / "obp" / "v3.0.0" + def v4 = baseRequest / "obp" / "v4.0.0" + def v7 = baseRequest / "obp" / "v7.0.0" + + // A title that also exists in the static Glossary, used for the override scenario. + val staticTitle = "Bank.bank_id" + + def newTitle(): String = "Test.glossary_item_" + UUID.randomUUID().toString.take(8) + + // Mirrors the placeholder Glossary.getGlossaryItem and friends emit into Resource Doc descriptions. + val GlossaryPlaceholderInDoc = """""".r + + def grantSystemRole(userId: String, role: String): Unit = + Entitlement.entitlement.vend.addEntitlement("", userId, role) + + def errorOf(response: code.setup.APIResponse): String = response.body.extract[ErrorMessage].message + + def post(title: String, description: String, as: Option[(Consumer, Token)], overrides: Option[Boolean] = None) = + makePostRequest((v7 / "glossary-items").POST <@ (as), + write(PostGlossaryItemJsonV700(title = title, description = description, overrides_static_item = overrides))) + + def put(title: String, description: String, as: Option[(Consumer, Token)], overrides: Option[Boolean] = None) = + makePutRequest((v7 / "glossary-items" / title).PUT <@ (as), + write(PutGlossaryItemJsonV700(description = description, overrides_static_item = overrides))) + + def delete(title: String, as: Option[(Consumer, Token)]) = + makeDeleteRequest((v7 / "glossary-items" / title).DELETE <@ (as)) + + def created(title: String, description: String, as: Option[(Consumer, Token)], + overrides: Option[Boolean] = None): GlossaryItemJsonV700 = { + val response = post(title, description, as, overrides) + response.code should equal(201) + response.body.extract[GlossaryItemJsonV700] + } + + def glossaryTitled(title: String): List[String] = { + val response = makeGetRequest((v3 / "api" / "glossary").GET) + response.code should equal(200) + response.body.extract[GlossaryItemsJsonV300].glossary_items + .filter(_.title.equalsIgnoreCase(title)) + .map(_.description.markdown) + } + + feature("Create Dynamic Glossary Item") { + + scenario("Authentication and the role are both required", ApiEndpoint1, VersionOfApi) { + When("no user is given") + val anonymous = makePostRequest((v7 / "glossary-items").POST, + write(PostGlossaryItemJsonV700(title = newTitle(), description = "x", overrides_static_item = None))) + Then("the call is unauthorised") + anonymous.code should equal(401) + + When("a user without CanCreateGlossaryItem calls") + val forbidden = post(newTitle(), "x", user2) + Then("the call is forbidden and names the missing role") + forbidden.code should equal(403) + errorOf(forbidden) should include(CanCreateGlossaryItem.toString) + } + + scenario("Create, then read it back", ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + val title = newTitle() + + When("the item is created") + val item = created(title, "A **bold** description.", user1) + Then("the response carries the markdown, the rendered html and the authorship") + item.title should equal(title) + item.description.markdown should equal("A **bold** description.") + item.description.html should include("bold") + item.overrides_static_item should equal(false) + item.shadows_static_glossary_item should equal(false) + item.created_by_user_id should equal(resourceUser1.userId) + item.glossary_item_id should not be empty + + And("it is listed, and readable by title") + val listed = makeGetRequest((v7 / "glossary-items").GET <@ (user1)) + listed.code should equal(200) + listed.body.extract[GlossaryItemsJsonV700].glossary_items.map(_.title) should contain(title) + + val single = makeGetRequest((v7 / "glossary-items" / title).GET <@ (user1)) + single.code should equal(200) + single.body.extract[GlossaryItemJsonV700].glossary_item_id should equal(item.glossary_item_id) + + And("the title is matched case insensitively") + makeGetRequest((v7 / "glossary-items" / title.toUpperCase).GET <@ (user1)).code should equal(200) + + And("an unknown title is 404") + val missing = makeGetRequest((v7 / "glossary-items" / newTitle()).GET <@ (user1)) + missing.code should equal(404) + errorOf(missing) should startWith(GlossaryItemNotFound) + } + + scenario("Titles are unique case insensitively, and must be non empty", ApiEndpoint1, VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + val title = newTitle() + created(title, "first", user1) + + When("the same title is created again") + val duplicate = post(title, "second", user1) + Then("it is refused with 409") + duplicate.code should equal(409) + errorOf(duplicate) should startWith(GlossaryItemAlreadyExists) + + And("so is the same title in a different case") + post(title.toUpperCase, "third", user1).code should equal(409) + + And("a blank title is refused with 400") + val blank = post(" ", "x", user1) + blank.code should equal(400) + errorOf(blank) should startWith(InvalidGlossaryItemTitle) + } + } + + feature("Update and delete Dynamic Glossary Items") { + + scenario("Update replaces the description, and needs its own role", ApiEndpoint1, ApiEndpoint4, VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + val title = newTitle() + val item = created(title, "before", user1) + + When("a user without CanUpdateGlossaryItem calls") + val forbidden = put(title, "after", user3) + Then("the call is forbidden") + forbidden.code should equal(403) + errorOf(forbidden) should include(CanUpdateGlossaryItem.toString) + + When("the role is granted") + grantSystemRole(resourceUser1.userId, CanUpdateGlossaryItem.toString) + val updated = put(title, "after", user1) + Then("the description is replaced and the id kept") + updated.code should equal(200) + val updatedItem = updated.body.extract[GlossaryItemJsonV700] + updatedItem.description.markdown should equal("after") + updatedItem.glossary_item_id should equal(item.glossary_item_id) + + And("updating an unknown title is 404") + val missing = put(newTitle(), "x", user1) + missing.code should equal(404) + errorOf(missing) should startWith(GlossaryItemNotFound) + } + + scenario("Delete removes the item, and needs its own role", ApiEndpoint1, ApiEndpoint5, VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + val title = newTitle() + created(title, "doomed", user1) + + When("a user without CanDeleteGlossaryItem calls") + val forbidden = delete(title, user3) + Then("the call is forbidden") + forbidden.code should equal(403) + errorOf(forbidden) should include(CanDeleteGlossaryItem.toString) + + When("the role is granted") + grantSystemRole(resourceUser1.userId, CanDeleteGlossaryItem.toString) + Then("the item is deleted and gone") + delete(title, user1).code should equal(204) + makeGetRequest((v7 / "glossary-items" / title).GET <@ (user1)).code should equal(404) + + And("deleting it again is 404") + val again = delete(title, user1) + again.code should equal(404) + errorOf(again) should startWith(GlossaryItemNotFound) + } + } + + feature("GET /api/glossary returns the union of static and Dynamic Glossary Items") { + + scenario("A new Dynamic Glossary Item appears in the Glossary", ApiEndpoint1, ApiEndpoint5, VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + grantSystemRole(resourceUser1.userId, CanDeleteGlossaryItem.toString) + val title = newTitle() + + Given("the title is not in the Glossary to start with") + glossaryTitled(title) should equal(Nil) + + When("a Dynamic Glossary Item is created") + created(title, "Only in the database.", user1) + Then("the Glossary picks it up straight away, without a redeploy") + glossaryTitled(title) should equal(List("Only in the database.")) + + When("it is deleted") + delete(title, user1).code should equal(204) + Then("it leaves the Glossary again") + glossaryTitled(title) should equal(Nil) + } + + scenario("A Dynamic Glossary Item replaces the static one of the same title", ApiEndpoint1, ApiEndpoint5, VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + grantSystemRole(resourceUser1.userId, CanDeleteGlossaryItem.toString) + + Given("the static Glossary carries this title") + // Note Bank.bank_id is defined twice in the static Glossary, in Glossary.scala and again in + // ExampleValue.scala, so this is a list rather than a single entry. Overriding it replaces + // every static item with that title, which is what makes the count check below meaningful. + val staticDescriptions = glossaryTitled(staticTitle) + staticDescriptions should not be empty + + When("a Dynamic Glossary Item with that title is created without declaring the override") + val refused = post(staticTitle, "Overridden by the operator.", user1) + Then("it is refused, so shipped documentation is never displaced by accident") + refused.code should equal(409) + errorOf(refused) should startWith(GlossaryItemShadowsStaticItem) + + When("the override is declared") + val item = created(staticTitle, "Overridden by the operator.", user1, overrides = Some(true)) + Then("the response reports both the declared intent and the actual shadowing") + item.overrides_static_item should equal(true) + item.shadows_static_glossary_item should equal(true) + + And("the Glossary now carries exactly one item with that title, and it is the dynamic text") + glossaryTitled(staticTitle) should equal(List("Overridden by the operator.")) + + When("the Dynamic Glossary Item is deleted") + delete(staticTitle, user1).code should equal(204) + Then("the static text is served again") + glossaryTitled(staticTitle) should equal(staticDescriptions) + } + } + + feature("Overriding a static Glossary Item has to be declared") { + + scenario("A collision with a static title is refused unless the override is declared", ApiEndpoint1, VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + grantSystemRole(resourceUser1.userId, CanDeleteGlossaryItem.toString) + + When("the override is not mentioned at all") + val silent = post(staticTitle, "text", user1) + Then("the request is refused and says what to do about it") + silent.code should equal(409) + errorOf(silent) should startWith(GlossaryItemShadowsStaticItem) + + When("the override is explicitly declined") + post(staticTitle, "text", user1, overrides = Some(false)).code should equal(409) + + When("the override is declared") + Then("the item is created") + val item = created(staticTitle, "text", user1, overrides = Some(true)) + item.overrides_static_item should equal(true) + + delete(staticTitle, user1).code should equal(204) + } + + scenario("A title with no static counterpart needs no declaration", ApiEndpoint1, VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + val item = created(newTitle(), "text", user1) + item.overrides_static_item should equal(false) + item.shadows_static_glossary_item should equal(false) + } + + scenario("The Glossary marks Dynamic Items and the ones displacing static text", ApiEndpoint1, ApiEndpoint5, VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + grantSystemRole(resourceUser1.userId, CanDeleteGlossaryItem.toString) + + // The provenance flags are a v7.0.0 addition: v3.0.0 is STABLE and its JSON must not change. + def itemInGlossary(title: String) = { + val response = makeGetRequest((v7 / "api" / "glossary").GET) + response.code should equal(200) + response.body.extract[ApiGlossaryJsonV700].glossary_items.find(_.title.equalsIgnoreCase(title)) + } + + Given("a static Glossary Item is reported as neither dynamic nor overriding") + itemInGlossary(staticTitle).map(_.is_dynamic) should equal(Some(false)) + + When("a Dynamic Item is added that does not displace anything") + val plainTitle = newTitle() + created(plainTitle, "standalone", user1) + Then("it is marked dynamic but not as an override") + val plain = itemInGlossary(plainTitle) + plain.map(_.is_dynamic) should equal(Some(true)) + plain.map(_.overrides_static_item) should equal(Some(false)) + + When("a Dynamic Item is added that declares an override of a static one") + created(staticTitle, "overriding text", user1, overrides = Some(true)) + Then("the Glossary marks it as both dynamic and overriding") + val overriding = itemInGlossary(staticTitle) + overriding.map(_.is_dynamic) should equal(Some(true)) + overriding.map(_.overrides_static_item) should equal(Some(true)) + + delete(staticTitle, user1).code should equal(204) + delete(plainTitle, user1).code should equal(204) + } + } + + feature("No Glossary placeholder ever reaches a client") { + + // Glossary Items cross-reference each other, so their own descriptions carry placeholders too. + // Missing that is exactly how 60 raw tokens once reached GET /api/glossary. + scenario("The Glossary itself carries expanded links, not placeholders", VersionOfApi) { + for ((label, url) <- List("v3.0.0" -> (v3 / "api" / "glossary"), "v7.0.0" -> (v7 / "api" / "glossary"))) { + val response = makeGetRequest(url.GET) + response.code should equal(200) + val body = response.body.toString + withClue(s"$label Glossary leaked an unexpanded placeholder: ") { + body should not include "OBP-GLOSSARY" + } + And(s"$label carries the links those placeholders stand for") + body should include("/glossary#") + } + } + } + + feature("Every Glossary title appears once") { + + scenario("The Glossary has no duplicate titles", VersionOfApi) { + // A duplicate title breaks any client that keys a list by it, and only one of the two can own + // the /glossary#Title anchor. Five pairs once shipped this way. + val response = makeGetRequest((v3 / "api" / "glossary").GET) + response.code should equal(200) + // Exact titles: anchors are case sensitive, so Account and account are distinct entries to a + // client and both are served. Only an identical title breaks a keyed list. + val titles = response.body.extract[GlossaryItemsJsonV300].glossary_items.map(_.title) + val duplicated = titles.groupBy(identity).collect { case (t, ts) if ts.size > 1 => t }.toList.sorted + withClue("titles defined more than once: ") { duplicated should equal(Nil) } + } + } + + feature("The STABLE v3.0.0 Glossary keeps its shape") { + + scenario("v3.0.0 serves the same merged Glossary, without the v7 provenance fields", VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + grantSystemRole(resourceUser1.userId, CanDeleteGlossaryItem.toString) + val title = newTitle() + created(title, "Only in the database.", user1) + + When("the STABLE v3.0.0 Glossary is fetched") + val response = makeGetRequest((v3 / "api" / "glossary").GET) + response.code should equal(200) + Then("it carries the Dynamic Item, since the content is the same union") + val item = (response.body \\ "glossary_items").children + .find(i => (i \\ "title").extractOpt[String].contains(title)) + item should not be empty + + And("each entry has exactly the two fields v3.0.0 has always had") + item.get.children should have size 2 + (item.get \\ "is_dynamic").extractOpt[Boolean] should equal(None) + (item.get \\ "overrides_static_item").extractOpt[Boolean] should equal(None) + + delete(title, user1).code should equal(204) + } + } + + feature("Glossary text embedded in endpoint descriptions honours Dynamic Glossary Items") { + + // createMyApiCollectionEndpoint embeds the "API Collections" Glossary Item in its description + // with Glossary.getGlossaryItem, which is the placeholder that gets expanded when docs are served. + val embeddedTitle = "API Collection" + val embeddingFunction = "createMyApiCollectionEndpoint" + + def descriptionOfEmbeddingEndpoint(): String = { + val response = makeGetRequest( + (v4 / "resource-docs" / "v4.0.0" / "obp") < List(("functions", embeddingFunction))) + response.code should equal(200) + val descriptions = (response.body \ "resource_docs").children + .filter(doc => (doc \ "operation_id").extractOpt[String].exists(_.contains(embeddingFunction))) + .flatMap(doc => (doc \ "description").extractOpt[String]) + withClue(s"no resource doc found for $embeddingFunction in: ${response.body}") { + descriptions should not be empty + } + descriptions.mkString("\n") + } + + scenario("Every title embedded in a description resolves to a Glossary Item", VersionOfApi) { + // A typo in a title is silent otherwise: the description just renders the literal text + // "glossary-item-not-found". That is how "API Collections" (the item is "API Collection") + // went unnoticed across six endpoint descriptions. + val response = makeGetRequest((v3 / "api" / "glossary").GET) + response.code should equal(200) + val definedTitles = + response.body.extract[GlossaryItemsJsonV300].glossary_items.map(_.title.toLowerCase).toSet + + val embeddedTitles = code.api.util.APIUtil.allStaticResourceDocs + .flatMap(doc => GlossaryPlaceholderInDoc.findAllMatchIn(doc.description).map(_.group(2))) + .distinct + + withClue("Resource Doc descriptions embed Glossary titles that do not exist: ") { + embeddedTitles.filterNot(title => definedTitles.contains(title.toLowerCase)) should equal(Nil) + } + } + + scenario("Placeholders never leak into a served description", VersionOfApi) { + val description = descriptionOfEmbeddingEndpoint() + Then("the description carries the Glossary text, not the unexpanded placeholder") + description should not include "OBP-GLOSSARY" + description should include(embeddedTitle) + + And("no field links to an empty Glossary anchor") + // "[field](/glossary#)" lands the reader at the top of the Glossary rather than a definition. + description should not include "(/glossary#)" + } + + scenario("A Dynamic Glossary Item replaces the embedded text", ApiEndpoint1, ApiEndpoint5, VersionOfApi) { + grantSystemRole(resourceUser1.userId, CanCreateGlossaryItem.toString) + grantSystemRole(resourceUser1.userId, CanDeleteGlossaryItem.toString) + + Given("the endpoint description embeds the static Glossary text") + val before = descriptionOfEmbeddingEndpoint() + before should not include "Overridden in the endpoint description." + + When("a Dynamic Glossary Item with that title is created") + created(embeddedTitle, "Overridden in the endpoint description.", user1, overrides = Some(true)) + Then("the endpoint description carries the dynamic text, despite the Resource Doc cache") + val during = descriptionOfEmbeddingEndpoint() + during should include("Overridden in the endpoint description.") + during should not include "OBP-GLOSSARY" + + When("the Dynamic Glossary Item is deleted") + delete(embeddedTitle, user1).code should equal(204) + Then("the endpoint description goes back to the static text") + val after = descriptionOfEmbeddingEndpoint() + after should not include "Overridden in the endpoint description." + after should equal(before) + } + } +}