Concepts for BIG OutSystems Projects (Part III)

# 3 - Feedback Messages

Overview

This series is a compilation of challenges, approaches, and solutions that were part of our path as OutSystems Developers throughout different projects. Keep in mind that many resources, tips, tricks, and techniques were also shared with us in various articles and forums by peers and colleagues. We decided to share what we have been learning in our journeys in the hope that it can also bring value to you.

As we face different challenges, this series will include various random topics. Stay tuned.

 

Building a Feedback Messages Library

Why build a Feedback Messages Library?

Everyone knows that feedback is critical towards enhancing communication between all the parties involved in a given process. It is often neglected, particularly regarding the feedback messages used across applications, thus undermining the value of the products.

 

Picture 1 - Example of Feedback message
Source:
pexels.com

 
 

When talking about big projects, the usage of assertive, well-structured, and effective communication is crucial. Thus, it shouldn't be an afterthought, but instead, it should be designed with the solution's scalability in mind.

This article will focus on feedback messages: building a library that can accommodate multi-language, multi-tenancy, dynamic values at runtime and be consumed by different applications without creating strong dependencies.

How to implement a solid and well-structured Feedback Messages library?

Let’s create a list with the essentials for a hypothetical use case:

#1 – Architecture Schema 

From the architecture perspective, we suggest a basic and straightforward solution with two applications:

  • FeedbackMessages_Lib – this application contains one module exposing a set of service actions: 

    • CRUDs actions – to be used on the management screens, 

    • The main service action – GetFeedbackMessageByCode – which, as the name suggests, returns a feedback message associated with a code, and 

    • a REST API (WS) – a copy of the previous one, exposing this feature to consumers external to the OutSystems platform. This solution opts for the service actions, avoiding the strong coupling between the library and the consumers. 

This module contains the entities storing the data for the messages and their translations.

  • FeedbackMessagesManagement_UI – this application comprises a UI module containing the screens to manage the feedback messages. It should consume the CRUD service actions available from the FeedbackMessages_Lib and the entities that contain the data to present on the management screens.

 

Picture 2 - Architecture schema example

 
 

#2 – Database model 

When designing the database model, we should think about all the requirements and try to anticipate future ones. Disclose and organize the ideas behind the feature: at this stage, all the questions must be raised.

  • Do we need a multi-tenant approach? 

  • How many languages should the messages be translated into?

  • Does it make sense to organize the messages by category? 

  • Will a certain message be specific to a particular domain, or is it generic?

 

Picture 3 - ERD example

 
 

With the previous questions in mind, above is a simple entity relationship diagram that we can briefly describe:

  • Feedback Message entity – it's the header of a feedback message record where a unique code should be stored accompanied by a description.

  • Feedback Message Translation entity – containing the actual message with a specific language. Hence, one record for each of the languages used in your solution. Multi-tenancy should be enabled, giving the option for each tenant to define their own translations.

  • Message Type static entity – defining the type of the feedback message (Info, Success, Error, Warning). Here you can reference the one that is part of the OutSystems RichWidgets.

  • Domain static entity – organizing the messages by domain. When creating new domains, adding a new record to this entity won't affect the library's consumers since we are not changing the exposed service action used to fetch a feedback message. This way, only the management screens will need to be updated to comply with the new domain.

  • Category static entity – grouping the messages by category to organize the data. Thus, making it easier for the administrator to check all the data when on the management screens. Regarding the dependencies of the consumers, this entity has identical behavior to the above-referred domain static entity.

#3 – Management screens

Typically these screens will be managed by an administrator with enough knowledge about all the concepts and components of the products that will use the feedback messages library. 

A set of two screens can do the trick here: a search and list screen with a couple of filters and a master-detail screen to add and edit the messages.

Don’t forget about the permissions (who can view and who can edit) and the validations that should be applied when creating or editing the data.

 

Picture 4 - Feedback Messages Management - master detail example

 
 

#4 – GetFeedbackMessageByCode Service Action

The ‘GetFeedbackMessageByCode’ service action exposed from the library is the end goal of the solution. Its purpose is that whenever a feedback message needs to be displayed, the service action should be added to the flow of the code. 

We previously stated that this solution would accommodate dynamic messages at runtime, this is achieved by adding parameters (custom text) to the message. 

Below is a brief explanation of this action, what are the input and output parameters and the logic behind.

 

Picture 5 - GetFeedbackMessageByCode -Input and Output examples

 
 

When calling the action, it checks if there's any match for the details provided. If so, it should have logic inside to handle the MessageParameters, including a string-split action to generate a list of the received values based on our chosen delimiter. Next, these values will replace the <ParameterN> tag that we are using on the management screens according to its sequence.

As output, this action will retrieve if a message was found, what the message is, and its type.

Looking at picture 4 in the previous section on Management Screens, you can imagine the situations where the message "<Parameter1> record was successfully created" can be used. Whenever we create a record, we call our service action. We fill the inputs: Code, Locale, and the parameter name through the MessageParameters input.

As an example of that message, if you defined 'Process Configurations' on your application, it would be something like "Process Configuration record was successfully created" of type Success.

#5 – Developer’s guide

Another topic that needs to be covered is the developer’s guide. The developer team needs to know how to use the exposed service action, what are the required input parameters, and how to handle the outputs. 

If needed, the developer team can also have access to the feedback messages management to add new messages and edit existing ones.

 

Tips and tricks

  • Whenever you predict that a feature will be highly reusable and has a large amount of data, consider having an import/export functionality. Thus, facilitating the replication of the data across environments and the new installations of the product.

  • Don’t forget to add error and exception handling to the action flows, especially when these will be heavily used across multiple applications and platforms.

 

Resources


Previous articles:

This article is a part of a series on Concepts for BIG OutSystems Projects. Take a look at the others, if you would like to learn more:

Like this article? Share it:

Previous
Previous

How to handle hierarchical data using advanced queries

Next
Next

OutSystems App Development Best Practices Using the 3 Layer Architecture Canvas