 Yes. Okay, so we can start the recording if you want. Okay, now I'm gonna talk a little bit about error management, what are the errors that the SDK could expose, synchronization errors, and how we deal with that integrity. So we're going to start with error management. When synchronizing metadata, maintaining the integrity of information can be a bit tricky, maybe. For this in the SDK, two main guidelines are taken into account. On the one hand, that the synchronization does not fail. And for this purpose, the errors that may occur during the synchronization are stored. On the other hand, keep the metadata integrity. And all these metadata errors are stored for inspection in the maintenance module, so you can access them. Like, for example, misindependences, they're foreign carriers, or just generic API errors. So, yeah, the SDK might produce different errors, and they are wrapped in a type of exception. This is the D2 error class. It has the five following fields. So the error component, the error code, the error description, the HTTP error code, and the original exception. So the first of them is the D2 error component, which is just the source of the error. It can be used to identify where the problem occurs. Like, for example, the server, the SDK database. The second one is the error code, which is an enum with unique codes for the errors. These codes can be used for translation, so please use it. So, for example, some of the errors that you can find are the app name is not set, or invalid the HH2 version, or the file is not found, or file resizing image, etc. In addition to this too, we can also find the error description, which is nothing more than a description of the error in English with some technical details using for logging and debugging. The HTTP error code, if the error was caused by an HTTP request, and the original exception, if any. So, in a call, in a method, we can see it in, this is an example in Erics Java in a reactive way. So when you are, for example, logging in, you can subscribe and get the user if everything goes well. But if you have an error, you can just parse the error, and then you can access, for example, to log in the error code, or to handle the error. But you can do it also with blocking operations. For example, in this blocking operation, which is the login to, you have here the try cats, and then you can catch the D2 error, and just access to the name or whatever you want to log. Also, some errors like the ones producing the SDK when signing are storing the database table. So, they can be accessed from the D2 error repository as any other table. So you can enter to the maintenance module, go to the D2 error repository, and you can get those errors. So you can list them, or you can, I don't know, you can do whatever you want with these errors. Maybe you can copy it and give it to your administrator. Okay, so now we are going to talk about the error management of the data. So when data has some errors, in the SDK, we try to identify as many details as possible. So in the aggregated world, we try to find the warnings that could be causing conflicting data values. And in the tracker world, we use the tracker import conflict that contain information about all the tracker entities. So the track entity instance, but also the enrollment, some events that could be in the enrollment, also the track entity attributes of the instance or the data elements of the event, the values, and the display description. And you can use them to show the errors in your application. Here's an example of the Android app for capture where we use this display description of this data element to show the information and give some feedback to the user so they can keep the data consistency. Okay, and now the data states. So the states of the data could be different. These data objects have only a read, so a read only state. And this indicates the current state of the object in terms of synchronization with the server. And this state is fully maintained by the SDK, so you don't have to do nothing. You just have to read the states and you can use it to send them to a user. So these are the errors. We're going to talk about them. So a sync state is when the element is just synced with the server and there are no local changes. So data remains in sync. To post state is when you create some data locally. So it's not in the server yet, so you didn't post it. To update means that some data that it was in the server before it was modified locally. So you have to update it into the server. It also has the appleting state when you start and upload. And if you, for example, are syncing data between the first event of syncing the data and when it finish the syncing, you modify some value. It goes again to the to update state. So when the server response arrives, it state does not change to sync but remains into update. So you're still having those local changes. And so you have the error state. That is when you're safe and error from the server after the upload. And the warning is the same but when you're safe and warning. You also have the relationship states. That's only for fulfilling a relationship to another event or enrollment. And this relationship state means that this object only has basic information. So it doesn't have any enrollment or any event or other relationships. Those are not downloaded for this entity. And also cannot be modified or upload to the server. So it's just for information to happen there about the relationship. Also, there is two more states. If you are using SMS synchronization, you have the send via SMS. When that is sent by the SMS, there is no server response yet. But if you have the ability in the server to response to those SMS, you also will have the send via SMS. In the skeleton app, we just use these icons to show when there is an error warning or you have to post our data or delay the data. That's when it's sent. Okay. And now that integrity, we have to take care about our data. So what are the SQL database for in-keys? Well, these are keys that link to tables in the SQL world. And it helps to keep that integrity. For example, if you remove this track entity instance, the enrollment will be removed too because the enrollment can exist without a track entity instance because they are linked. Well, if we take a look of the inconsistencies that they can occur in our servers, well, we can have foreign key violations for wrong server configuration or just because the offline nature of the application. But it could be also an SDK bug. For example, during the synchronization, when you start a database transaction, you download the user, you download the app set, the program, and then you close the transaction. Well, meanwhile, the transaction is taking, so when it's happening, the transaction, the foreign keys don't have to be satisfied. But when you close the transaction, then the foreign keys must be satisfied. So the objects that doesn't have the foreign key satisfied will be deleted. So if we take a look into the inconsistencies based on the offline nature, the user can have maybe a outdated version of the metadata or the data. And it could be a problem. I will just show you. For example, the first step, we don't load the metadata. So we have the metadata A. But then several days before, your state of line and the metadata is changed in the server. And you don't have these new updates. Then we don't load the data without re-downloading the metadata. So we start working and we try to push the data. So probably you will have a foreign key error. So that will make you like to have inconsistencies in your data. So for that reason, the SDK is here and it will help you to remove the inconsistencies based of the offline nature of the work with the SDK. Also the SDK could be used as a tool to diagnose server malconfigurations. So if you're in the Aventure Server and you don't see any foreign key violations in the table, it's okay. But if you see many entries, probably you have a misconfiguration in the server. So in this example, if for example we delete the track entity instance, just what I said before, the link, the foreign key will be satisfied. And so the enrollment will disappear. So it helps us to update the data. And all these foreign key violations are in a repository in the SDK. And you can list them by going to the maintenance module, foreign key violations, and you can get the list of the foreign key violations that you have in this repository. That's everything about data errors management. If you have any questions, just this thing in content, you can use the Slack channel. So now I think I'm going to handle to my colleague Victor. Victor, are you there? Yeah, I'm here. So let's go with the last of the theoretical questions about the SDK. This is just a few words about some utility classes or services that are in the SDK and could be used to deal with some of the logic or particularities of the test. So for example, yeah, because in the SDK you have everything, you have methods to synchronize, to create new data, to deal with those kinds of things. But there are a lot of other things that are around that are pure THS2 logic, like for example, the logic that is related to events. For example, it is the app who has to decide, for example, if an event is editable or not, just to show the form to the user. This looks simple, but it actually is not, because there is a lot of things involved in this. For example, what we need to check, we need to check the user access, if the user has data access to the premise page. This is one thing. Also, if the enrollment linked to this event is active, also if their unit has opening date and also if the event date is within that range. And finally, the event has an attribute option combo associated with the event. And these option combos are composed of category options. And we need to check that the user has data correct access for all the category options that are involved in this attribute option combo. And not only that, also we have to check that all the category options, in case they have start and end date, we have to verify that the event date is within the range for all of them. So as you see, if there is a lot of things involved in checking if an event is editable or not, and all this logic is incorporated in the SDK. We started in version 2.2, and it's a working progress, because there is a lot of things to do with this. Another example, if an enrollment can be, if a user can access an enrollment or edit an enrollment, so it depends on the access level of the enrollment of the program, if it's open, protected, closed, the access level of the users for that program in particular, and also if the or unit of enrollment is in the capture scope or in the search scope. So yeah, again, a lot of things to care of just to decide if an enrollment is editable or not. Another thing in the SDK is the prom indicator engine. This is used to print the prom indicator value in the data entry form. If you have in your mind the target capture, there is a small box with the prom indicators that help the user in the data entry form, so the SDK can evaluate these prom indicators. And this is an example. There is a program module at prom indicator engine, quite easy. And the last thing I want to mention is the validation rules. This is for aggregated data entry. It is the, you know, the validation that you can configure in the data entry form to prevent values that are out of, that don't meet some requirements. For example, like the population under five years should be less or equal than the total population. And yeah, we are not going to do any exercise about this. It's just for you to know, but yeah, I would like to do a just two minutes demo about this, for example, at least for you to know how it looks like in the SDK in the application. So I have here, yeah, I have the skeleton application, so we don't have any exercise for this. So I'm going to use a debug. Sorry, if I go to data set instances, I have one data set instance, the population. Here I have less than one year, less than five years total population. Okay. So this looks okay. If I click here, I finish the values. Okay. So what is happening when I click this button is here. So what I'm doing here is I want to trigger the validation rules for this for these data sets. So easy to validate your module, validate your engine, block invalidate. And here I have in the context, I have, I need to do pass the data set the ID in the context, the ID, or unit ID, as you can see, it's quite easy to evaluate the evaluation rules for a combination of the data set, the ID, and the unit. So I went to set a break point here, not in the back mode. As I said, this is just to take a look at how the SDK can be used to evaluate this expression. So I go back to data set instances. Okay. Everything is okay. So if I click here, I get here the result. I hope you can read this more or less, but I have unestate those. Okay. So there is no violations. All good. So if I change, for example, population, 1,000, not more than that, 5,000. The total population is 3,000. So it should give me an error. Let's see. In the debugger, result, status, error, violations, two violations, actually, because, and here you can take a look at the left side of the expression, the right side, also with a display expression. So you can give some feedback to the user, like this part should be less than this other part. So the population under one year should be less than the population under five years. Here, and you have also the value, so you can regenerate the expression to give proper feedback to the user to know what's going on and why the validation rule has failed. So yeah, that's all. Maybe for the next workshop, we can prepare an exercise about validation rules. So that's it. That's all from my side. Yep. So let's go to the next session. Unless there is any question, please, if there is any question.