The CLSA Architecture Application Build exam consists of 3 to 6 questions of varying complexity which evaluates the ability of a candidate to develop and architect solutions using the PEGA platform. Please refer to the Exam preparation guide for further details.
Question 5 from a retired exam scenario is attached to this post. You are encouraged to work through this question by collaborating in this discussion thread. A solution will not be provided.
It is estimated that a candidate proficient in design and implementation would be able to complete this task in 7 hours.
The starting point migration file for this first retired exam is called Booking_20171102_10000.zip and can be downloaded here.
Let me start off this discussion by mentioning that Pega does have Survey-related rules in 7.3.1. But is it feasible to extend these rules to support the requirements?
The most problematic requirement is that questions and their possible responses should be randomly shuffled except for responses that contain "of the above", which should appear as the bottom-most response. There are different ways to shuffle data and sort data. Can you name and describe two completely different ways?
The shuffling requirement also raises the issue of when random shuffling should occur. There is a requirement that the user should be able to see randomly shuffled questions and responses before sending. Once sent and the responses are received, the user should be able to see the responses that the recipient selected, plus see the overall score. Suppose in the future the requirement is changed such that the survey is sent automatically?
From a data modeling perspective, a few similarities between Questions and Responses exist such as Text and ID. Would a base class be appropriate? Suppose Questions were allowed to have sub-Questions? If so, both Responses and sub-Questions would utilize a ParentID property. Also, if a Survey case exists, wouldn't it also make sense to define a Survey Data class?
With regards to the shuffled responses, my first thought was to use the random function and assign a value to each and sort using that value in a data transform. As the random function returns a decimal between 0 to 1 with several digits precision the shuffling should be pretty random.
The "of the above" instances I would display last by addressing in this using the data model. Maybe have a boolean in the class called DisplayLast. In the same DT above I would set the pagelist item with DisplayLast==true to 1 and sort in ascending order.
For each page in Responses
If DisplayLast != true, set SortOrder to random()
Else set SortOrder to 1
Sort pagelist in ascending order using SortOrder.
I would also put this logic in a data page response data transform that reloads with each interaction. This dpage should only be called once for a given list of questions/responses.
On second thought, there probably is no need to have it in the dpage data transform. I'll keep the dpage reusable with appropriate caching, and perform the logic in my previous post within a data transform within the case, likely in the flow action pre processing for the section that displays the responses prior to sending.
Posted: 2 years ago
Updated: 2 years ago
Posted: 4 Jan 2019 8:09 EST Updated: 4 Jan 2019 8:08 EST
Good point about the separation between Data and Work. Data exists to serve cases. Cases exist to manage Data.
What I would question though is executing the shuffling transform in a Flow Action pre-transform. Why not call it from pyDefault?
Suppose the requirements are changed in the future to where Survey cases are sent automatically, for example as a top-level spin-off from a Hotel case, without needing to being reviewed by an Operator? The Hotel case can propagate to the spun-off Survey case to whom the response should be sent.
An alternative solution is to configure the query perform a primary ascending sort against the DisplayLast column followed by a secondary sort against an inserted random() SQL Function column. But your point about cases managing Data is why this alternative is slightly flawed.
While the database solution does work, it is not best practice to implement business logic at the database level. Suppose a requirement in the future that it must be possible to delegate the business logic that decides the sort order for questions and/or responses? Would you delegate a Live Data editor or a When rule that contains logic such as @contains(.Text, "of the above")?
The reason to move to pyDefault makes sense for future proofing. However, I would argue that if that logic is placed in a self-contained data transform to start with, moving it from being run in a pre-processing flow action to pyDefault is trivial (when need be). Given the reusability of a self-contained DT, wouldn't it actually be better practice to leave it in preprocessing until such a time that it's required to be moved? A system architect's natural behaviour to inspect how the data is constructed might be to first check the flow action of the section. Leaving it there might actually be better from a SA user experience perspective.
A mildly related principle that was mentioned in the LSA material was along the lines of "don't create a framework for the sake of future proofing. create one or a built-on app when requirements come about"... or something to that effect.
Side question around marking... if I made the recommendation as above in the build exam. Would I have lost points by not nominating the pyDefault solution? If so can you give an indication of how much?
Actually yes - if your solution for shuffling is UI-dependent you would have lost points but since you implemented a reusable Data Transform the deduction would be minimal. A poor UI-dependent solution is one where responses are not populated at all unless each Question is expanded in the UI to review the response list. For example, suppose a Question page has a .ResponseList PageList Property sourced to a Snapshot-pattern Data Page that requires a QuestionID parameter. That data model design is acceptable but the .ResponseList for each Question should be fully populated, programmatically, outside the UI. Building For Change involves minimizing dependencies.
At home I have implemented task #3 (integration) using connector simulation. There is no mention of how this data is meant to be formatted (JSON/SOAP), but from my simulation activity I have set my own JSON serialised payload and deserialise using a JSON data transform.
If I have done this in the build, would I get extra points for it? Or should I not bother? I understand the requirements states "simple-as-possible", but if I did anyway, would I be given extra points?
We have no way of granting extra points. The fact that you did implement a Connector that at least pretends that it receives a response from an external source is better than inserting a "temporary simulation transform" directly into a flow, especially if this is not obvious to someone maintaining the code.
The Connector can be refactored in the future to become "live" and the case design can be extended in the future to receive the survey response. However coding something that is not extendable, such as a transform that later needs to be removed, goes against Best Practices.
In reality the recipient of the SurveyProxy case would respond with a PUT back to the Survey case but we felt this would take too much time, plus merely replicates an existing solution.
One issue with using Pega Survey rules is that i couldn't find any way to source Questions from a Data Page even though it is possible to source Responses from Data Page. Therefore i couldn't find a way to shuffle Questions using Pega Survay rules.
Is that the only reason to avoid Pega Survey rules?
I started by creating questions page in Pega Survey landing page and using that in my Survey Case Type , as the UI looked perfect.But i wasted a lot of time trying to shuffle the responses in the page groups that were created during run time.Later used my own sections to create the Questions/responses and the shuffling became lot easier.The downside was the UI was not as perfect as Pega Survey.
Please take a look at my design and let me know your views please
My high level design thinking and process steps as below:
Create a SurveyProxy component application with the following class and case structure:
FSG-Booking-Work-Survey-Hotel to ensure we could use the survey class for any other survey i.e Parking,Weather etc.
HotelSurvey case type with the below life cycle:
Enter test data stage to enter test data if some one wants to test this component stand alone.
Launch survey stage to present a UI to show the questions and responses to be selected.
Have a declarative rule to compute the percentage based on each response.
Provide a review screen to show all answered questions and answers.
Resolve the proxy case
On the booking case type at the Resolve stage post "capture of feedback" provide a UI to the operator to display the survey questions.
Post the display of the questions call a utility to call a "Create Case" OOTB REST service to create the SurveyProxy case and send an email notification to the hotel contacts to fill the survey questions.
Resolve the booking case once the survey questions have been filled.
In terms of shuffling the questions I was planning to use a random number generator function to generate a random number and use it to sort/shuffle the list.(not sure though)
Could someone have a look at the above and let me know if you think this works from an exam perspective.
That is a really good idea, i.e., do more than just create a FSG-Booking-Work-Survey case. Also define an FSG-Booking-Work-Survey-Hotel class. Doing so sets an example for others to follow.
Currently the only requirement to issue a Survey is related to Hotels. The Hotel contacts who confirmed rooms are the persons who should be sent the Survey. This is reason enough to specialize the Survey case for Hotels. The bulk of the logic would be in the FSG-Booking-Work-Survey case. DCR would change the class to FSG-Booking-Work-Survey-Hotel. That class would decide who is sent the Survey. Makes perfect sense.
Shuffling can be accomplished multiple ways including having the database query do it, Assigning a random number to every item in a list, then doing a sort within a data transform, would work fine. The extra complexity involved was ensuring that "of the above" responses would end up last. A When condition could do an @contains() check. If true, rather than assign a random number, a number larger than what the random number generator would generate would be assigned.
While developing this I had another question in head...
The req says I should send the survey to the hotels who have confirmed the rooms.In that case should I create a solution in similar lines to the Hotel and HotelProxyCase? i.e create a Survey case in the Response stage of the Event Booking case and create a SurveyProxy child case from this Survey case to be assigned to the hotel contacts?
How would you avoid redundancy between FSG-Booking-Work-Hotel, where the logic is mainly in FSG-Hotel-Work-Hotel, and FSG-Booking-Work-Survey-Hotel?
In other words, Can FSG-Hotel-Work-Hotel and FSG-Survey-Work-Survey leverage the same logic when it comes to creating a Proxy case and waiting for its response?
The FSG-Hotel-Work-Hotel creates a HotelProxy case by POSTing a .RoomsRequest embedded page to the PegaAPI by setting .caseTypeID = "FSG-Hotel-Work-Hotel-Proxy" and .pyWorkIDPrefix = "P-within a Interface.request.body_POST step page.
You could have a FSG-Hotel-Work-Hotel-Survey case would POST a different embedded page, .SurveyRequest,, setting .caseTypeID = "FSG-Hotel-Work-Hotel-SurveyProxy and .pyWorkIDPrefix = "SUR-" a similar Interface.request.body_POST page. The class for "Interface" would need to change, perhaps by using DCR.
FSG-Int-HotelRoomsReq could be extended to FSG-Int-HotelRoomsReq-Survey. That class would override the .Content embedded page changing the class to FSG-Int-HotelRoomsReq-RoomsRequest-Survey. Then you add properties to that class, if you truly need to. You would pattern inherit FSG-Int-HotelRoomsReq-RoomsRequest. How much more would you need to add?
Getting back to the FSG-Hotel-Work-Hotel-Survey case, in the "Email Hotel" stage, you would specify a different Email correspondence rule for Param.CorrName and different subject for Param.EmailSubject. It is possible to use a property in place of literal text for these values.
No one has suggested creating a Custom Rule to capture the hierarchy of Questions and the Responses.
The Custom Rule could have a PageList of Data-Question instances edited using a Table layout. The source of the table would be a .QuestionList Property. The "Operations" tab would be configured as Master-Detail. Modal Dialog would be the best choice IMHO.
Every row in that Table would be a Section. Data-Question would have a PageList of Data-Response instances.
The Survey case would have an embedded page Property, the class being the Custom Rule, e.g., Rule-MySurvey.
For the .QuestionList to be a Property of either a Rule- class or a Work- class its applies-to class must be made very generic, for example, @baseclass.
.QuestionList would be displayed within a Section that has two Table layouts that have mutually exclusive Visibility conditions. One layout only displays when the applies-to class starts with Rule-, the other layout would be displayed otherswise. Rule- displayed Table layout would allow Question rows to be added or removed, the other Table layout would not allow rows to be added or removed.
In similar fashion each Data-Question displays its .ResponseList using a Section that has two mutually exclusive Table layouts, one allowing Response rows to be added or removed, the other layout not. The When condition to do this would be trickier to define since the applies-to class is always Data-Question.
Ideally the same When condition that controls the display of the .QuestionList would be reused. How would that When rule be defined?
@pedel, could you elaborate a bit why Proxy-cases solutions are preferrable than Direct Web Access for externals?
Although I could explain it for myself (as a IT guy) that Proxy case is more neat solution, but from business perspective (external clients) it's not very convenient to login in someone's application (and not to forget your one more credentials!) and do some work there.
The idea was that the web-browser accessible Hotel Proxy application would be a stepping stone towards development of a Pega Mobile application. A Mobile App can take advantage of more sophisticated security approaches such as OIDC.
FYI: the Linux Lite VM does have Postfix installed as well as the Mozilla Thunderbird email client -- just type "thunderbird". In Server Settings you can see that the Inbox is configured for a user named "architect".
Exams do not require external connections as this would be a disadvantage to some. plus makes exams harder to grade.