applicationtype describes an instance of a stored application. It includes information about:
answersto the questions in the application
externalDataattached to the application
statethe application is in
ApplicationTemplateinterface is the heart of the whole system. Each self-service application flow depends on having a template that extends this interface. Each application template has a unique
dataSchemafor quick data validation,
answerValidatorsfor more customizable server side validation, and, most importantly, a
stateMachineConfigto describe the overall flow for the application, and how users with different roles can interact with an application in its varying states.
translationNamespacesfield on the template. It accepts an array of namespaces, in case you are using messages from multiple namespaces, coming from Contentful.
descriptionfields on each state of your state machine. These two fields will be used on the applications list on the service portal. It gives a better understanding for the user the current step of the process it is in.
institutionfield to the template. It is accepting both a string and a "translatable" object.
namefield from the same object above.
paramsfield from the error message callback. You then can pass the "translatable" object from your message file.
dataSchemais implemented using Zod which is a powerful TypeScript-first schema declaration and validation library. The schema is an object, where the keys are the ids of all the questions that need validation for this given application template, and the value is a zod object describing what validation is needed for that given question and what error message to show if it fails.
dataSchemacan offer. That is where answer validators come in. The answer validators are stored in a map, where the key is a path to the answer that needs to have this custom validation, and the value is a function which gets the current application and the new answer as parameters. The validators are only run on the server when the client tries to update an answer with a designated validator.
application-corehas types and interfaces for state machines which are extended from xstate. Each
statein the application template state machine must include a
metaobject which describes the name of the state, what
rolescan access it, and what each role can do in said state.
A state is an abstract representation of a system (such as an application) at a specific point in time. As an application is interacted with, events cause it to change state. A finite state machine can be in only one of a finite number of states at any given time.
type: 'final'. It can be defined multiple times for your application states. For example, the Meta Application (link above) is either approved or rejected, and in both case the application is in its final state. A final state is final, and there are no events that lead out of it.
type: 'final'is important because, out of it, we define a
statuscolumn in the application model. This
statusis the same for every application template and give us the general progress of the application. We have, at the moment, 3 different status as follow, and let us filters and list applications by status type.
shouldBeListed: falsethe application will not be listed in my pages or on
shouldBePruned: trueinactive applications will be automatically pruned to not waste space in the database if they are not moved into another state after a certain period of time
whenToPrune: 12 * 3600 * 1000the application can be deleted after 12 hours of inactivity
writedifferent data stored in the application. Not only that, but each role has its own
formLoaderto describe what form should be rendered for said role in this specific state. For example, when an application is in review, the
applicantshould see a different form than the
reviewer. Also, the
applicantcan no longer
writeany new answers, only
readthem, while a
reviewermight be able to
readeverything and even
writesome new answers as well. This logic is also applied by the backend to make sure when a person queries for an application, the answers stored in the database for said application are trimmed so the person only gets to see the answers that (s)he is allowed to in that state.
actionmaps to an event that is used by the state machine to transition into another state. In the example below, the
applicantcannot perform any actions in the
inReviewstate, while the
reviewerhas all the power to
REJECTthe application, resulting in a state transition.
Formtype describes how to structure the flow of a form. It is basically a big json object which is used by
application-ui-shellto know what to render on the screen.
Form, and the leaves are renderable
Fields. In between there are nodes that describe the structure in more detail, such as
idof the field needs to be present in the application template
dataSchemaobject. It is even possible to provide a field with pure
defaultValueif no answer has been provided by the user.
application-formUI renders multiple fields on the screen, instead of the default one field per screen behavior.
externalDataof an application is only updated by the backend via custom-made