diff --git a/content/en/building/concepts/care-guides.md b/content/en/building/concepts/care-guides.md index dd09cc9d0..98cbed365 100644 --- a/content/en/building/concepts/care-guides.md +++ b/content/en/building/concepts/care-guides.md @@ -5,7 +5,7 @@ description: > Taking health workers through care protocols and providing decision support keywords: care-guides relatedContent: > - building/concepts/forms + building/forms building/tasks/#care-guides building/contact-summary/contact-summary-templated/#care-guides aliases: diff --git a/content/en/building/contact-management/contacts.md b/content/en/building/contact-management/contacts.md index 86ffe186e..6e3b972a3 100644 --- a/content/en/building/contact-management/contacts.md +++ b/content/en/building/contact-management/contacts.md @@ -6,7 +6,7 @@ description: > Contacts and users overview keywords: hierarchy contacts care-guides relatedContent: > - building/reference/forms/contact + building/forms/contact building/contact-summary/contact-summary-templated building/contact-management/moving-contacts building/contact-management/contact-and-users-1 diff --git a/content/en/building/contact-summary/contact-summary-templated.md b/content/en/building/contact-summary/contact-summary-templated.md index 383047ed2..b2d73fdaa 100644 --- a/content/en/building/contact-summary/contact-summary-templated.md +++ b/content/en/building/contact-summary/contact-summary-templated.md @@ -5,7 +5,7 @@ weight: 2 description: > Customizing the fields, cards, and actions on profile pages relatedContent: > - building/guides/forms/form-inputs + building/forms/configuring/form-inputs relevantLinks: > docs/building/features/contacts docs/building/concepts/hierarchies @@ -55,7 +55,7 @@ Each field that can be shown on a contact's profile is defined as an object in t | `width` | `integer` | The horizontal space for the field. Common values are 12 for full width, 6 for half width, or 3 for quarter width. Default 12. | no | | `translate` | `boolean` | Whether or not to translate the `value`. Defaults to false. | no | | `context` | `object` | When `translate: true` and `value` uses [translation variables](https://angular-translate.github.io/docs/#/guide/06_variable-replacement), this value should provide the translation variables. | no | -| `appliesIf` | `function()` or `boolean` | Return true if the field should be shown. | no | +| `appliesIf` | `function()` | Return `true` if the field should be shown, and `false` if it should be hidden. Default is `true`. | no | | `appliesToType` | `string[]` | Filters the contacts for which `appliesIf` will be evaluated. For example, `['person']` or `['clinic', 'health_center']`. It defaults to all types if it is not defined. | no | @@ -87,7 +87,7 @@ Each condition card is defined as a card object in the `cards` array of `contact ## Care Guides -Each care guide accessible from a contact profile is defined as an [App Form]({{< ref "building/reference/forms/app" >}}). Context information can be provided to forms via the `context` object of `contact-summary.templated.js`. +Each care guide accessible from a contact profile is defined as an [App Form]({{< ref "building/forms/app" >}}). Context information can be provided to forms via the `context` object of `contact-summary.templated.js`. To show an App Form on a contact's profile, the form's `expression` field in its properties file must evaluate to true for that contact. The context information from the profile is accessible as the variable `summary`. diff --git a/content/en/building/examples/anc.md b/content/en/building/examples/anc.md index c0a0974cf..40bbe1d9d 100644 --- a/content/en/building/examples/anc.md +++ b/content/en/building/examples/anc.md @@ -6,7 +6,7 @@ description: > Reference application for maternal and newborn care for CHW's using a mobile app relatedContent: > building/concepts - building/reference/forms/app + building/forms/app building/tasks/tasks-js aliases: - /apps/examples/anc @@ -37,7 +37,7 @@ Once a [hierarchy]({{< relref "building/workflows/hierarchy" >}}) of people and {{< figure src="forms-hierarchy.png" link="forms-hierarchy.png" class="right col-12 col-lg-12" >}} -{{< see-also page="building/reference/forms/app" title="Controlling form properties" >}} +{{< see-also page="building/forms/app" title="Controlling form properties" >}} ## Workflows diff --git a/content/en/building/examples/covid-rdt-reference-app.md b/content/en/building/examples/covid-rdt-reference-app.md index dbf59cbf0..7eaf2d02c 100644 --- a/content/en/building/examples/covid-rdt-reference-app.md +++ b/content/en/building/examples/covid-rdt-reference-app.md @@ -5,9 +5,9 @@ weight: description: > CHT example application that uses a third party app to capture the result of a Rapid Diagnostic Test. relatedContent: > - building/reference/forms/app/#android-app-launcher - building/reference/forms/app/#cht-xform-widgets - building/reference/forms/app/#parse-timestamp-to-date + building/forms/app/#android-app-launcher + building/forms/app/#cht-xform-widgets + building/forms/app/#parse-timestamp-to-date aliases: - /apps/examples/covid-rdt-reference-app --- @@ -41,7 +41,7 @@ For more information on these features, see the ["Related Content"](#related-con Additional requirements for this application beyond CHT 3.13, include [CHT Android 0.10.0](https://github.com/medic/cht-android) or later and Dimagi's [RD-Toolkit 0.9.8](https://github.com/dimagi/rd-toolkit/) or later. -While this application calls the RD-Toolkit, the integration features in the CHT Core and CHT Android are generic. This means you could use a different RDT Android application if you prefer. Beyond the scope of RDTs, you could use this integration feature to launch any other Android app to perform an action and save the result in the CHT. To read more about this feature, see the [Android App Launcher section in the Forms reference documentation]({{< ref "building/reference/forms/app#android-app-launcher" >}}). +While this application calls the RD-Toolkit, the integration features in the CHT Core and CHT Android are generic. This means you could use a different RDT Android application if you prefer. Beyond the scope of RDTs, you could use this integration feature to launch any other Android app to perform an action and save the result in the CHT. To read more about this feature, see the [Android App Launcher section in the Forms reference documentation]({{< ref "building/forms/app#android-app-launcher" >}}). ## Workflow @@ -165,7 +165,7 @@ These are the files in the COVID-19 app where you'll want to focus your customiz The `forms/app/covid19_rdt_provision` and `forms/app/covid19_rdt_capture` forms (`xlsx`, `xml` and `properties.json`) represent the provision and capture portions of the forms. The tasks that get created are defined in `tasks.js`. Not shown are standard contact definitions in `forms/contact/*` as well as supporting configurations for icons and other CHT application settings. -To read more about how these files all work together, see [app forms]({{< ref "building/reference/forms/app" >}}), [contact forms]({{< ref "building/reference/forms/contact" >}}), and [task]({{< ref "building/tasks/tasks-js" >}}) reference documentation +To read more about how these files all work together, see [app forms]({{< ref "building/forms/app" >}}), [contact forms]({{< ref "building/forms/contact" >}}), and [task]({{< ref "building/tasks/tasks-js" >}}) reference documentation ## Example form submission diff --git a/content/en/building/examples/direct-to-client.md b/content/en/building/examples/direct-to-client.md index 137607000..b85797387 100644 --- a/content/en/building/examples/direct-to-client.md +++ b/content/en/building/examples/direct-to-client.md @@ -6,7 +6,7 @@ description: > Reference for Direct-to-client, two-way texting workflows with CHT and RapidPro relatedContent: > building/concepts - building/reference/forms/app + building/forms/app building/tasks/tasks-js aliases: - /apps/examples/direct-to-client diff --git a/content/en/building/examples/supervisor-reference-app.md b/content/en/building/examples/supervisor-reference-app.md index 28bbdae4a..9330caf25 100644 --- a/content/en/building/examples/supervisor-reference-app.md +++ b/content/en/building/examples/supervisor-reference-app.md @@ -7,7 +7,7 @@ description: > relatedContent: > building/concepts building/features/supervision - building/reference/forms/app + building/forms/app building/tasks/tasks-js aliases: - /apps/examples/supervisor-reference-app diff --git a/content/en/building/features/messaging/_index.md b/content/en/building/features/messaging/_index.md index f303d8c14..1860177c8 100644 --- a/content/en/building/features/messaging/_index.md +++ b/content/en/building/features/messaging/_index.md @@ -6,7 +6,7 @@ description: > relatedContent: > building/reference/app-settings/schedules building/guides/messaging - building/guides/forms/app-form-sms + building/forms/configuring/app-form-sms aliases: - /apps/features/messaging/ --- diff --git a/content/en/building/features/reports/_index.md b/content/en/building/features/reports/_index.md index ecc9b3b66..7ffec93eb 100644 --- a/content/en/building/features/reports/_index.md +++ b/content/en/building/features/reports/_index.md @@ -6,7 +6,7 @@ description: > relatedContent: > building/reference/app-settings/patient_reports building/guides/data/invalid-reports - building/guides/forms/report-titles + building/forms/configuring/report-titles aliases: - /apps/features/reports/ --- @@ -92,7 +92,7 @@ The buttons at the bottom are configurable. The ones you see will depend on your ## Defining Forms The reports shown in your app are the completed and submitted *forms*. These forms must be defined and included with the application. There are two types of form definitions for reports: -- **App forms**: actions within the app, such as a completed task, or an action on a contact's profile or reports tab. App forms are defined as [XForms]({{< ref "building/reference/forms/app" >}}). +- **App forms**: actions within the app, such as a completed task, or an action on a contact's profile or reports tab. App forms are defined as [XForms]({{< ref "building/forms/app" >}}). - **JSON forms**: data coming from external channels such as SMS, or via interoperability with other tools. JSON forms are defined using a [JavaScript Object Notation schema]({{< ref "building/reference/app-settings/forms" >}}). diff --git a/content/en/building/features/uhc-mode/_index.md b/content/en/building/features/uhc-mode/_index.md index 7f5e7cf6d..6f666a5ad 100644 --- a/content/en/building/features/uhc-mode/_index.md +++ b/content/en/building/features/uhc-mode/_index.md @@ -5,7 +5,7 @@ weight: 11 description: > Supporting equitable and timely care to families to increase Universal Health Coverage (UHC) relatedContent: > - building/guides/forms/uhc-mode + building/forms/configuring/uhc-mode building/reference/app-settings/user-roles building/reference/app-settings/user-permissions aliases: @@ -28,4 +28,4 @@ The _UHC Mode_ in the CHT allows health workers to see when a household within t When using the _UHC Mode_, the households in the contact list can be sorted by when they were last visited. The days since the last visit is also shown in the app, along with the number of visits made to a household in a month period. ## Configurability -The last visited date is calculated based on the number of days since an action was taken for that household, and the number of visits reflects the actions taken for that household in the current month. What constitutes as an action for a household, along with the start date for the reporting period, [are configurable]({{< relref "building/guides/forms/uhc-mode" >}}) to CHT app developers. +The last visited date is calculated based on the number of days since an action was taken for that household, and the number of visits reflects the actions taken for that household in the current month. What constitutes as an action for a household, along with the start date for the reporting period, [are configurable]({{< relref "building/forms/configuring/uhc-mode" >}}) to CHT app developers. diff --git a/content/en/building/concepts/forms.md b/content/en/building/forms/_index.md similarity index 54% rename from content/en/building/concepts/forms.md rename to content/en/building/forms/_index.md index 14ab26972..e32cb6f85 100644 --- a/content/en/building/concepts/forms.md +++ b/content/en/building/forms/_index.md @@ -1,16 +1,12 @@ --- -title: "Forms" -linkTitle: "Forms" -weight: 3 +title: Forms +linkTitle: Forms +weight: 7 description: > Building block for all CHT apps -keywords: app-forms contact-forms collect-forms json-forms -relatedContent: > - building/concepts/care-guides - building/guides/forms - building/reference/forms - building/reference/app-settings/forms aliases: + - /building/reference/forms + - /building/concepts/forms - /apps/concepts/forms --- @@ -19,9 +15,8 @@ Forms are a building block of all CHT apps. They are used when creating or editi When a completed form is submitted, it is treated as a Report in the app. All reports can be viewed in the [Reports tab]({{< ref "building/features/reports" >}}) by those with the proper access within the [hierarchy]({{< ref "building/workflows/hierarchy" >}}). There are four different types of forms: -- [**Contact Forms**]({{< ref "building/reference/forms/contact" >}}): used to create and edit contacts. Defined as CHT-enhanced XForms. -- [**App Forms**]({{< ref "building/reference/forms/app" >}}): serve as actions within the app, such as a task or an action. Defined as CHT-enhanced XForms. -- [**Collect Forms**]({{< ref "building/reference/forms/collect" >}}): used to render forms in Medic Collect. Defined as ODK XForms and need a corresponding JSON form to receive data in CHT. -- [**JSON Forms**]({{< ref "building/reference/app-settings/forms" >}}): used for data coming from external channels such as SMS, or via interoperability with other tools. Defined according to a JavaScript Object Notation schema. +- [**Contact Forms**]({{< ref "building/forms/contact" >}}): used to create and edit contacts. Defined as CHT-enhanced XForms. +- [**App Forms**]({{< ref "building/forms/app" >}}): serve as actions within the app, such as a task or an action. Defined as CHT-enhanced XForms. +- [**Collect Forms**]({{< ref "building/forms/collect" >}}): used to render forms in Medic Collect. Defined as ODK XForms and need a corresponding JSON form to receive data in CHT. Forms that can be completed in the app are built using a CHT-enhanced version of [ODK XForms](https://opendatakit.github.io/xforms-spec/) notation -- a XML definition of the structure and format for a set of questions. Since writing raw XML can be tedious, the [XLSForm standard](http://xlsform.org/) is commonly used to define forms. The [cht-conf](https://github.com/medic/cht-conf) command line tool can be used to convert to the XForm format and include the form in a CHT application. The instructions on this site assume some knowledge of XLSForm. \ No newline at end of file diff --git a/content/en/building/reference/forms/app.md b/content/en/building/forms/app.md similarity index 97% rename from content/en/building/reference/forms/app.md rename to content/en/building/forms/app.md index 6a33df50f..440760106 100644 --- a/content/en/building/reference/forms/app.md +++ b/content/en/building/forms/app.md @@ -1,16 +1,17 @@ --- title: "app" linkTitle: "app" -weight: 5 +weight: 1 description: > **App Forms**: Used to complete reports, tasks, and actions in the app relevantLinks: > docs/building/concepts/workflows docs/design/best-practices relatedContent: > - building/guides/forms/form-inputs + building/forms/configuring/form-inputs keywords: workflows app-forms aliases: + - /building/reference/forms/app - /apps/reference/forms/app --- @@ -21,7 +22,7 @@ App forms are defined by the following files: - A XML form definition using a CHT-enhanced ODK XForm format - A XLSForm form definition, easier to write and converts to the XForm (optional) - Meta information in the `{form_name}.properties.json` file (optional) -- Media files in the `{form_name}-media` directory (optional). How to [include multimedia files]( {{< ref "building/guides/forms/multimedia" >}} ). +- Media files in the `{form_name}-media` directory (optional). How to [include multimedia files]( {{< ref "building/forms/configuring/multimedia" >}} ). ## XForm @@ -91,7 +92,7 @@ Some XForm widgets have been added or modified for use in CHT applications. The ### Bikram Sambat Datepicker Calendar widget using Bikram Sambat calendar, which is used by default for appropriate languages. The CHT documentation includes a [conversion tool](https://docs.communityhealthtoolkit.org/bikram-sambat/) to check the conversion between Gregorian and Bikram Sambat dates. -{{< see-also page="building/reference/forms/app" title="`to-bikram-sambat` XPath function" anchor="to-bikram-sambat" >}} +{{< see-also page="building/forms/app" title="`to-bikram-sambat` XPath function" anchor="to-bikram-sambat" >}} ### Countdown Timer @@ -109,7 +110,7 @@ The `trigger` implementation of the countdown timer is only supported for CHT ve ### Contact Selector -A dropdown field to search and select a person or place, and save their UUID in the report. The contact's data will also be mapped to fields with matching names within the containing group. If the contact selector's appearance includes `bind-id-only`, the associated data fields are not mapped. See [the form input guide]({{< ref "building/guides/forms/form-inputs#contact-selector" >}}) for an example. +A dropdown field to search and select a person or place, and save their UUID in the report. The contact's data will also be mapped to fields with matching names within the containing group. If the contact selector's appearance includes `bind-id-only`, the associated data fields are not mapped. See [the form input guide]({{< ref "building/forms/configuring/form-inputs#contact-selector" >}}) for an example. ### Rapid Diagnostic Test Capture Take a picture of a Rapid Diagnotistic Test and save it with the report. Works with [rdt-capture Android application](https://github.com/medic/rdt-capture/). To use create a string field with appearance `mrdt-verify`. @@ -312,7 +313,7 @@ _Added in 3.14.0._ This function converts a `date` to a `string` containing the value of the date formatted according to the [Bikram Sambat](https://en.wikipedia.org/wiki/Vikram_Samvat) calendar. -See also: [Bikram Sambat Datepicker]({{< ref "building/reference/forms/app#cht-xform-widgets" >}}) +See also: [Bikram Sambat Datepicker]({{< ref "building/forms/app#cht-xform-widgets" >}}) ### `z-score` @@ -349,17 +350,17 @@ The data used by this function needs to be added to CouchDB. The example below s ## Input data -`app` forms have access to a variety of [input data]({{< ref "building/guides/forms/form-inputs#app-forms" >}}) depending on the source of the form. +`app` forms have access to a variety of [input data]({{< ref "building/forms/configuring/form-inputs#app-forms" >}}) depending on the source of the form. ## CHT Special Fields Some fields in app forms control specific aspects of CHT Apps, either to bring data into forms or for a feature outside of the form. ### Quintiles -The `NationalQuintile` and `UrbanQuintile` fields on a form will be assigned to all people belonging to the place. This is helpful when household surveys have quintile information which could be used to target health services for individuals. {{< see-also prefix="Read More" page="building/guides/forms/wealth-quintiles" >}} +The `NationalQuintile` and `UrbanQuintile` fields on a form will be assigned to all people belonging to the place. This is helpful when household surveys have quintile information which could be used to target health services for individuals. {{< see-also prefix="Read More" page="building/forms/configuring/wealth-quintiles" >}} ### UHC Mode -When the `visited_contact_uuid` field is set at the top level of a form, this form is counted as a household visit in [UHC Mode]({{< relref "building/features/uhc-mode" >}}). This field must be a `calculate` field with the place UUID of the visited contact. You may run into performance issues if you configure this to look at forms submitted very frequently. {{< see-also prefix="Read More" page="building/guides/forms/uhc-mode" >}} +When the `visited_contact_uuid` field is set at the top level of a form, this form is counted as a household visit in [UHC Mode]({{< relref "building/features/uhc-mode" >}}). This field must be a `calculate` field with the place UUID of the visited contact. You may run into performance issues if you configure this to look at forms submitted very frequently. {{< see-also prefix="Read More" page="building/forms/configuring/uhc-mode" >}} ## Uploading Binary Attachments diff --git a/content/en/building/reference/forms/collect.md b/content/en/building/forms/collect.md similarity index 97% rename from content/en/building/reference/forms/collect.md rename to content/en/building/forms/collect.md index a320d0e72..984077785 100644 --- a/content/en/building/reference/forms/collect.md +++ b/content/en/building/forms/collect.md @@ -1,11 +1,12 @@ --- title: "collect" linkTitle: "collect" -weight: 5 +weight: 3 description: > **Collect Forms**: Served to the Medic Collect application keywords: collect-forms collect aliases: + - /building/reference/forms/collect - /apps/reference/forms/collect --- diff --git a/content/en/building/forms/configuring/_index.md b/content/en/building/forms/configuring/_index.md new file mode 100644 index 000000000..67ef91038 --- /dev/null +++ b/content/en/building/forms/configuring/_index.md @@ -0,0 +1,10 @@ +--- +title: Configuring +linkTitle: Configuring +weight: 4 +description: > + Configuring and using forms in the CHT +aliases: + - /building/guides/forms/ + - /apps/guides/forms/ +--- \ No newline at end of file diff --git a/content/en/building/guides/forms/additional-docs.md b/content/en/building/forms/configuring/additional-docs.md similarity index 97% rename from content/en/building/guides/forms/additional-docs.md rename to content/en/building/forms/configuring/additional-docs.md index 53c01c4b0..861c5f54a 100644 --- a/content/en/building/guides/forms/additional-docs.md +++ b/content/en/building/forms/configuring/additional-docs.md @@ -5,11 +5,11 @@ weight: description: > Integration for sending and receiving SMS relatedContent: > - building/guides/forms/app-form-sms - building/guides/forms/multimedia - building/reference/forms/contact - + building/forms/configuring/app-form-sms + building/forms/configuring/multimedia + building/forms/contact aliases: + - /building/guides/forms/additional-docs - /apps/guides/forms/additional-docs --- In version 2.13.0 and higher, you can configure app forms to generate additional docs upon submission. You can create one or more docs using variations on the configuration described below. One case where this can be used is to register a newborn from a delivery report, as shown below. First, here is an overview of what you can do and how the configuration should look in XML: diff --git a/content/en/building/guides/forms/additional-docs/linked_docs_xlsform.png b/content/en/building/forms/configuring/additional-docs/linked_docs_xlsform.png similarity index 100% rename from content/en/building/guides/forms/additional-docs/linked_docs_xlsform.png rename to content/en/building/forms/configuring/additional-docs/linked_docs_xlsform.png diff --git a/content/en/building/guides/forms/additional-docs/repeated_docs_xlsform.png b/content/en/building/forms/configuring/additional-docs/repeated_docs_xlsform.png similarity index 100% rename from content/en/building/guides/forms/additional-docs/repeated_docs_xlsform.png rename to content/en/building/forms/configuring/additional-docs/repeated_docs_xlsform.png diff --git a/content/en/building/guides/forms/app-form-sms.md b/content/en/building/forms/configuring/app-form-sms.md similarity index 97% rename from content/en/building/guides/forms/app-form-sms.md rename to content/en/building/forms/configuring/app-form-sms.md index 8068c1295..3aa3bef15 100644 --- a/content/en/building/guides/forms/app-form-sms.md +++ b/content/en/building/forms/configuring/app-form-sms.md @@ -5,10 +5,11 @@ weight: description: > Trigger calls and SMS from within the form, or send an SMS once submitted. relatedContent: > - building/guides/forms/additional-docs - building/guides/forms/multimedia - building/reference/forms/contact + building/forms/configuring/additional-docs + building/forms/configuring/multimedia + building/forms/contact aliases: + - /building/guides/forms/app-form-sms - /apps/guides/forms/app-form-sms --- diff --git a/content/en/building/reference/forms/contact/place-contact-form-survey.png b/content/en/building/forms/configuring/contact/place-contact-form-survey.png similarity index 100% rename from content/en/building/reference/forms/contact/place-contact-form-survey.png rename to content/en/building/forms/configuring/contact/place-contact-form-survey.png diff --git a/content/en/building/guides/forms/form-inputs.md b/content/en/building/forms/configuring/form-inputs.md similarity index 97% rename from content/en/building/guides/forms/form-inputs.md rename to content/en/building/forms/configuring/form-inputs.md index ab5e612c2..42dc8ea3b 100644 --- a/content/en/building/guides/forms/form-inputs.md +++ b/content/en/building/forms/configuring/form-inputs.md @@ -5,11 +5,11 @@ weight: description: > Data accessible from within CHT forms relatedContent: > - building/reference/forms + building/forms building/contact-summary/contact-summary-templated - building/guides/tasks/pass-data-to-form - + building/tasks/managing-tasks/pass-data-to-form aliases: + - /building/guides/forms/form-inputs - /apps/guides/forms/form-inputs --- @@ -38,7 +38,7 @@ Forms for adding contacts have access to a small group of fields contained in a #### Edit forms -Forms for editing contacts have access to _all the contact's current data_. These fields are contained in a top-level group that is named for the contact_type id of the contact being added (so `person`, `clinic`, etc). If fields in the top-level group are [edited by the form]({{< ref "building/reference/forms/contact" >}}), these changes will be saved to the contact's doc. +Forms for editing contacts have access to _all the contact's current data_. These fields are contained in a top-level group that is named for the contact_type id of the contact being added (so `person`, `clinic`, etc). If fields in the top-level group are [edited by the form]({{< ref "building/forms/contact" >}}), these changes will be saved to the contact's doc. In addition, the contact's `parent` data is hydrated so that the form has access to the data stored on the parent contact doc in the `parent` group. @@ -95,7 +95,7 @@ Contact summary data is not available in `contact` forms or in forms created fro ### `inputs` data from task -`app` forms created via a task have access to any data [supplied by the task]({{< ref "building/guides/tasks/pass-data-to-form" >}}) in the `inputs` group. +`app` forms created via a task have access to any data [supplied by the task]({{< ref "building/tasks/managing-tasks/pass-data-to-form" >}}) in the `inputs` group. --- diff --git a/content/en/building/guides/forms/google-drive.md b/content/en/building/forms/configuring/google-drive.md similarity index 97% rename from content/en/building/guides/forms/google-drive.md rename to content/en/building/forms/configuring/google-drive.md index 17d972811..46217272c 100644 --- a/content/en/building/guides/forms/google-drive.md +++ b/content/en/building/forms/configuring/google-drive.md @@ -5,8 +5,9 @@ weight: description: > Using cht-conf to obtain form files stored in Google Drive relatedContent: > - building/guides/forms/ + building/forms/configuring/ aliases: + - /building/guides/forms/google-drive - /apps/guides/forms/google-drive --- diff --git a/content/en/building/guides/forms/multimedia.md b/content/en/building/forms/configuring/multimedia.md similarity index 96% rename from content/en/building/guides/forms/multimedia.md rename to content/en/building/forms/configuring/multimedia.md index eae896e3e..9d07edcd9 100644 --- a/content/en/building/guides/forms/multimedia.md +++ b/content/en/building/forms/configuring/multimedia.md @@ -5,10 +5,11 @@ weight: description: > How to include multimedia files in forms relatedContent: > - building/guides/forms/additional-docs - building/guides/forms/app-form-sms - building/reference/forms/contact + building/forms/configuring/additional-docs + building/forms/configuring/app-form-sms + building/forms/contact aliases: + - /building/guides/forms/multimedia - /apps/guides/forms/multimedia --- diff --git a/content/en/building/guides/forms/report-titles.md b/content/en/building/forms/configuring/report-titles.md similarity index 96% rename from content/en/building/guides/forms/report-titles.md rename to content/en/building/forms/configuring/report-titles.md index 510f554b3..f4385be3e 100644 --- a/content/en/building/guides/forms/report-titles.md +++ b/content/en/building/forms/configuring/report-titles.md @@ -8,6 +8,7 @@ relatedContent: > building/features/reports building/reference/app-settings/patient_reports aliases: + - /building/guides/forms/report-titles - /apps/guides/forms/report-titles --- diff --git a/content/en/building/guides/forms/uhc-mode.md b/content/en/building/forms/configuring/uhc-mode.md similarity index 98% rename from content/en/building/guides/forms/uhc-mode.md rename to content/en/building/forms/configuring/uhc-mode.md index d7b3fdca5..efa3d1d8c 100644 --- a/content/en/building/guides/forms/uhc-mode.md +++ b/content/en/building/forms/configuring/uhc-mode.md @@ -9,6 +9,7 @@ relatedContent: > building/reference/app-settings/user-roles building/reference/app-settings/user-permissions aliases: + - /building/guides/forms/uhc-mode - /apps/guides/forms/uhc-mode --- diff --git a/content/en/building/guides/forms/uhc-mode/UHC.gif b/content/en/building/forms/configuring/uhc-mode/UHC.gif similarity index 100% rename from content/en/building/guides/forms/uhc-mode/UHC.gif rename to content/en/building/forms/configuring/uhc-mode/UHC.gif diff --git a/content/en/building/guides/forms/uhc-mode/sort-dropdown.png b/content/en/building/forms/configuring/uhc-mode/sort-dropdown.png similarity index 100% rename from content/en/building/guides/forms/uhc-mode/sort-dropdown.png rename to content/en/building/forms/configuring/uhc-mode/sort-dropdown.png diff --git a/content/en/building/guides/forms/wealth-quintiles.md b/content/en/building/forms/configuring/wealth-quintiles.md similarity index 98% rename from content/en/building/guides/forms/wealth-quintiles.md rename to content/en/building/forms/configuring/wealth-quintiles.md index 796fbc45e..7af4d8a74 100644 --- a/content/en/building/guides/forms/wealth-quintiles.md +++ b/content/en/building/forms/configuring/wealth-quintiles.md @@ -4,9 +4,8 @@ linkTitle: "Quintiles" weight: description: > How to track wealth quintiles on the profile of each family member in the household -relatedContent: > - aliases: + - /building/guides/forms/wealth-quintiles - /apps/guides/forms/wealth-quintiles --- diff --git a/content/en/building/reference/forms/contact.md b/content/en/building/forms/contact.md similarity index 92% rename from content/en/building/reference/forms/contact.md rename to content/en/building/forms/contact.md index 382d40eb1..52684eb9c 100644 --- a/content/en/building/reference/forms/contact.md +++ b/content/en/building/forms/contact.md @@ -1,19 +1,20 @@ --- title: "contact" linkTitle: "contact" -weight: 5 +weight: 2 description: > **Contact Forms**: Used for creating and editing people and places relevantLinks: > docs/building/features/contacts docs/building/concepts/hierarchies relatedContent: > - building/guides/forms/form-inputs - building/guides/forms/additional-docs - building/guides/forms/multimedia - building/guides/forms/app-form-sms + building/forms/configuring/form-inputs + building/forms/configuring/additional-docs + building/forms/configuring/multimedia + building/forms/configuring/app-form-sms keywords: hierarchy contacts contact-forms aliases: + - /building/reference/forms/contact - /apps/reference/forms/contact --- @@ -44,7 +45,7 @@ For edit forms, the name of the top-level group should still match the contact_t #### Input data -`contact` forms have access to a variety of [input data]({{< ref "building/guides/forms/form-inputs#app-forms" >}}). +`contact` forms have access to a variety of [input data]({{< ref "building/forms/configuring/form-inputs#app-forms" >}}). ### Settings sheet @@ -52,7 +53,7 @@ The `form_id` should follow the pattern `contact:CONTACT_TYPE_ID:ACTION` where C ### Properties -Starting in cht-core release 3.10, we can now configure property files in contact create forms to show or hide them based on an expression or permission as specified in the [app form schema]({{< ref "building/reference/forms/app#formsappform_namepropertiesjson" >}}). Note: this applies only to the create form, not the contacts themselves. +Starting in cht-core release 3.10, we can now configure property files in contact create forms to show or hide them based on an expression or permission as specified in the [app form schema]({{< ref "building/forms/app#formsappform_namepropertiesjson" >}}). Note: this applies only to the create form, not the contacts themselves. {{% alert title="Note" %}} The form expression for contact forms will only have access to `user` data. The `contact` and `summary` data are [not currently available](https://github.com/medic/cht-core/issues/6612). diff --git a/content/en/building/tutorials/form-properties.md b/content/en/building/forms/form-properties.md similarity index 93% rename from content/en/building/tutorials/form-properties.md rename to content/en/building/forms/form-properties.md index 07d3a9317..a065a0444 100644 --- a/content/en/building/tutorials/form-properties.md +++ b/content/en/building/forms/form-properties.md @@ -1,14 +1,14 @@ --- title: "Setting Form Properties" -linkTitle: Form Properties -weight: 8 +linkTitle: Properties +weight: 5 description: > How to set form properties that contain meta information related to App forms relatedContent: > - building/reference/forms/app/#formsappform_namepropertiesjson + building/forms/app/#formsappform_namepropertiesjson design/best-practices - aliases: + - /building/tutorials/form-properties - /apps/tutorials/form-properties --- @@ -22,7 +22,7 @@ You will be adding meta-data and context to an assessment workflow that allows C ## Brief Overview of Key Concepts -*[Form context]({{< ref "building/reference/forms/app#formsappform_namepropertiesjson" >}})* defines when and where the form should be available in the app. +*[Form context]({{< ref "building/forms/app#formsappform_namepropertiesjson" >}})* defines when and where the form should be available in the app. ## Required Resources diff --git a/content/en/building/guides/forms/versioning.md b/content/en/building/forms/versioning.md similarity index 95% rename from content/en/building/guides/forms/versioning.md rename to content/en/building/forms/versioning.md index 9bfaf6ab6..fc7feff54 100644 --- a/content/en/building/guides/forms/versioning.md +++ b/content/en/building/forms/versioning.md @@ -1,12 +1,13 @@ --- -title: "Versioning forms" -linkTitle: "Versioning forms" -weight: +title: Versioning forms +linkTitle: Versioning +weight: 6 description: > Record the version of the form when creating reports relatedContent: > building/features/reports aliases: + - /building/guides/forms/versioning - /apps/guides/forms/versioning --- diff --git a/content/en/building/guides/data/csv-to-docs.md b/content/en/building/guides/data/csv-to-docs.md index 3208312b0..e16ddea11 100644 --- a/content/en/building/guides/data/csv-to-docs.md +++ b/content/en/building/guides/data/csv-to-docs.md @@ -5,8 +5,8 @@ weight: 17 description: > Seeding data with cht-conf relatedContent: > - building/guides/forms/additional-docs - building/reference/forms/contact + building/forms/configuring/additional-docs + building/forms/contact aliases: - /apps/guides/data/csv-to-docs --- diff --git a/content/en/building/guides/forms/_index.md b/content/en/building/guides/forms/_index.md deleted file mode 100644 index db7831bf6..000000000 --- a/content/en/building/guides/forms/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: "Building and Maintaining Forms" -linkTitle: "Forms" -weight: 100 -description: > - Managing and using forms in the CHT -aliases: - - /apps/guides/forms/ ---- \ No newline at end of file diff --git a/content/en/building/guides/integrations/dhis2-aggregate.md b/content/en/building/guides/integrations/dhis2-aggregate.md index ed8a5b118..00491cefe 100644 --- a/content/en/building/guides/integrations/dhis2-aggregate.md +++ b/content/en/building/guides/integrations/dhis2-aggregate.md @@ -45,7 +45,7 @@ Once you obtain the list of data elements on the data set, be sure to go through {{% /alert %}} -{{< see-also page="building/concepts/forms" title="Forms" >}} +{{< see-also page="building/forms" title="Forms" >}} ### Workflows and User Access @@ -79,7 +79,7 @@ Update the contact document of each place you wish to map to an organisation uni {{% /alert %}} -{{< see-also page="building/reference/forms/contact" title="Contact Forms" >}} +{{< see-also page="building/forms/contact" title="Contact Forms" >}} ```json { diff --git a/content/en/building/guides/integrations/oppia.md b/content/en/building/guides/integrations/oppia.md index 9b3d0ed01..17347b5de 100644 --- a/content/en/building/guides/integrations/oppia.md +++ b/content/en/building/guides/integrations/oppia.md @@ -22,7 +22,7 @@ The training modules configuration consists of five main components: ### App Forms -The CHT application uses [XLSForms]({{< ref "building/reference/forms/app" >}}) (app forms), which are a simplified method of setting up form configurations using Excel (or Libre Office Calc, Google sheets, etc). The forms contain the questions/content that the user will interact with, including [web links](https://oppiamobile.readthedocs.io/en/latest/implementers/integration/launch_from_other_app.html) that enable the users to navigate from the CHT application to a specific course in OppiaMobile. App forms are typically created in the `project-folder > forms > app` directory of a project. If the content requires a user to access any form of media, then a media folder for the specific form is created and named after the form. For example, to add video content for a form module_one.xlsx, save the video file to the following directory: `project-folder > forms > app > module_one-media > video`. Once the forms are set up with content, the forms are converted to XForms, which are in xml format. To limit access of App Forms to certain contacts, an App Forms must have a properties file, which defines when and for whom certain forms should be accessed. Once configured, the forms are uploaded to an instance using the CHT configurer with the following commands, which upload specific forms and all forms respectively: +The CHT application uses [XLSForms]({{< ref "building/forms/app" >}}) (app forms), which are a simplified method of setting up form configurations using Excel (or Libre Office Calc, Google sheets, etc). The forms contain the questions/content that the user will interact with, including [web links](https://oppiamobile.readthedocs.io/en/latest/implementers/integration/launch_from_other_app.html) that enable the users to navigate from the CHT application to a specific course in OppiaMobile. App forms are typically created in the `project-folder > forms > app` directory of a project. If the content requires a user to access any form of media, then a media folder for the specific form is created and named after the form. For example, to add video content for a form module_one.xlsx, save the video file to the following directory: `project-folder > forms > app > module_one-media > video`. Once the forms are set up with content, the forms are converted to XForms, which are in xml format. To limit access of App Forms to certain contacts, an App Forms must have a properties file, which defines when and for whom certain forms should be accessed. Once configured, the forms are uploaded to an instance using the CHT configurer with the following commands, which upload specific forms and all forms respectively: ``` cht --instance= convert-app-forms upload-app-forms -- diff --git a/content/en/building/guides/messaging/gateways/africas-talking.md b/content/en/building/guides/messaging/gateways/africas-talking.md index 28524f7c0..9ca800b67 100644 --- a/content/en/building/guides/messaging/gateways/africas-talking.md +++ b/content/en/building/guides/messaging/gateways/africas-talking.md @@ -9,7 +9,7 @@ aliases: - /apps/guides/messaging/gateways/africas-talking/ relatedContent: > building/reference/app-settings/sms - building/guides/forms/app-form-sms + building/forms/configuring/app-form-sms building/guides/messaging/sms-states building/guides/messaging/message-loops building/guides/messaging/shortcodes diff --git a/content/en/building/guides/messaging/gateways/rapidpro.md b/content/en/building/guides/messaging/gateways/rapidpro.md index 90a4860fd..6789ad1bf 100644 --- a/content/en/building/guides/messaging/gateways/rapidpro.md +++ b/content/en/building/guides/messaging/gateways/rapidpro.md @@ -8,7 +8,7 @@ aliases: - /apps/guides/messaging/rapidpro relatedContent: > building/reference/app-settings/sms - building/guides/forms/app-form-sms + building/forms/configuring/app-form-sms building/guides/messaging/sms-states building/guides/messaging/message-loops building/guides/messaging/shortcodes diff --git a/content/en/building/guides/messaging/message-loops.md b/content/en/building/guides/messaging/message-loops.md index f9707b5a9..087d8036d 100644 --- a/content/en/building/guides/messaging/message-loops.md +++ b/content/en/building/guides/messaging/message-loops.md @@ -5,7 +5,7 @@ weight: 90 description: > How to avoid messaging loops relatedContent: > - building/guides/forms/app-form-sms + building/forms/configuring/app-form-sms building/guides/messaging/sms-states building/guides/messaging/shortcodes aliases: diff --git a/content/en/building/guides/performance/telemetry.md b/content/en/building/guides/performance/telemetry.md index b5c88035b..5132f3d61 100644 --- a/content/en/building/guides/performance/telemetry.md +++ b/content/en/building/guides/performance/telemetry.md @@ -115,12 +115,13 @@ Find below the list of telemetry data recorded by CHT: | `tasks:group:modal:confirm` | Number times the user confirms navigation away from the household tasks page. Added in 3.13. | | | `tasks:group:modal:reject` | Number times the user rejects navigation away from the household tasks page. Added in 3.13. | | | `user_settings:language:` | The selected language by the user, example: `user_settings:language:en`. Added in 3.14. | | -| `enketo::add:render` | The time it took to render the training card. Added in 4.2.0 | | +| `enketo::add:render` | The time it took to render the training card. Added in 4.2.0 | Yes. Added in 4.15.0 | | `enketo::add:user_edit_time` | The time the user took to complete the training card. Added in 4.2.0 | | | `enketo::add:save` | The time it took to save the training card. Added in 4.2.0 | | | `enketo::add:quit` | The time from when the training card was rendered to when the user quits the training. Added in 4.2.0 | | | `geolocation:success` | A successful GPS response with the value showing the accuracy. | | | `geolocation:failure:` | An unsuccessful GPS response. `x` is a constant matching the [GeolocationPositionError](https://developer.mozilla.org/en-US/docs/Web/API/GeolocationPositionError/code) or with one of the following values: `-1` unknown failure, `-2` timeout, or `-3` geolocation services unavailable. | | +| `training_materials_list:load` | On the Training Materials page, the time taken to load the list of trainings on the left hand side. Added in 4.15.0. | Yes. Added in 4.15.0 | [1] "Dirty" indicates that the contact's task documents are not up to date. They will be refreshed before being used. [2] Replication can be denied when the user doesn't have permissions to create a doc (hierarchy permissions) or when a doc fails a `validate_doc_update` check. diff --git a/content/en/building/guides/updates/preparing-for-4.md b/content/en/building/guides/updates/preparing-for-4.md index ced66161b..0717236cb 100644 --- a/content/en/building/guides/updates/preparing-for-4.md +++ b/content/en/building/guides/updates/preparing-for-4.md @@ -16,8 +16,7 @@ description: > ## Introduction Medic uses [Semantic Versioning](https://en.wikipedia.org/wiki/Semver#Semantic_versioning) (aka "SemVer") which means that the CHT upgrade from the major 3.x version to the 4.x version denotes there are breaking changes. The key to a successful upgrade will be to understand and plan for these breaking changes. Aside from the Docker hosting infrastructure (out of scope for this prep document), the two breaking changes are around CHT Android and Enketo. - -While CHT 4.0 has not been released yet, the effort to be prepared can be quite time consuming, especially for large deployments that may need to do handset upgrades in a worst case. The sooner deployments start preparing for the upgrade, the easier it will be when it comes to the upgrade itself. Conveniently, all device and Android app changes to prepare for 4.x are backwards compatible with 3.x. Prepare now, so you will be ready to upgrade sooner than later! +Upgrading to CHT 4.0 can be quite time consuming, especially for large deployments that may need to do handset upgrades in a worst case. The sooner deployments start preparing for the upgrade, the easier it will be when it comes to the upgrade itself. Conveniently, all device and Android app changes to prepare for 4.x are backwards compatible with 3.x. Prepare now, so you will be ready to upgrade sooner than later! ## CHT Android v1.0.0+ @@ -207,7 +206,7 @@ After pushing your app config (see "CHT Conf" above), you can proceed to go thro #### New XPath functions * Custom CHT functions: - * [`add-date`]({{< relref "building/reference/forms/app#add-date" >}}) - Adds the provided number of years/months/days/hours/minutes to a date value. + * [`add-date`]({{< relref "building/forms/app#add-date" >}}) - Adds the provided number of years/months/days/hours/minutes to a date value. * ODK Functions: * Repeats and other node sets: * [`position`](https://docs.getodk.org/form-operators-functions/#position) - Returns the current iteration index within a repeat group. diff --git a/content/en/building/reference/app-settings/transitions.md b/content/en/building/reference/app-settings/transitions.md index 3250a92f5..0a31bca77 100644 --- a/content/en/building/reference/app-settings/transitions.md +++ b/content/en/building/reference/app-settings/transitions.md @@ -29,7 +29,7 @@ As of version 3.12.0 some transitions will partially run on the client for offli } ``` -In this example the `d` transition will not be applied, `a`, `b` `c` will be applied on the server and on the client, while `e` will only be applied on the server. +In the example above, the `d` transition will not be applied, `a`, `b` `c` will be applied on the server and on the client, while `e` will only be applied on the server. ## Available transitions @@ -57,11 +57,10 @@ The following transitions are available and executed in order. | [mark_for_outbound]({{% ref "building/reference/app-settings/outbound" %}}) | Enables outbound pushes. Available since 3.5.x | | [self_report](#self_report) | Maps patient to sender. Available since 3.9.x | | [create_user_for_contacts](#create_user_for_contacts) | Allows for automatically creating or replacing users based on data from their associated contact. Available since 4.1.x | | -## Transition Configuration Guide -Guides for how to setup specific transitions. +Below are guides to setup specific transitions. -### multi_report_alerts +## multi_report_alerts Send alert messages by SMS when specific conditions are received through reports. More flexible than simple Alerts. @@ -87,7 +86,7 @@ Understanding the different types of reports used in the configuration: `0`, `1` : `new_reports` : `counted_reports` that came in since the previous alert was sent. They haven't been messaged about yet. -#### Configuration +##### Configuration ``` "multi_report_alerts" : [ @@ -112,11 +111,11 @@ Note that we are using Mustache templates for our message templates (anything wi For performance reasons the `num_reports_threshold` cannot exceed 100. -### death_reporting +## death_reporting Updates patient documents with a `date_of_death` field which updates how the patient is displayed in the UI. -#### Configuration +##### Configuration Configuration is stored in the `death_reporting` field of the settings. @@ -136,7 +135,7 @@ Configuration is stored in the `death_reporting` field of the settings. } ``` -### Registration +## registration Configuration is held at `app_settings.registrations`, as a list of objects connecting forms to validations, events and messages. @@ -307,22 +306,22 @@ To provide an alternative location for the place name, provide a `place_name_fie Sets the `case_id` on the root of the registration document. -### Generate Shortcode on Contacts +## generate_shortcode_on_contacts -No custom configuration for `generate_shortcode_on_contacts`. +There is no custom configuration for `generate_shortcode_on_contacts`. -### Generate Patient ID On People +## generate_patient_id_on_people **Deprecated since 3.8.x** in favor of `generate_shortcode_on_contacts` -No custom configuration for `generate_patient_id_on_people`. +There is no custom configuration for `generate_patient_id_on_people`. -### update_notifications +## update_notifications **Deprecated in favor of [Muting](#muting)** -#### Configuration +##### Configuration ``` "notifications": { @@ -352,53 +351,64 @@ No custom configuration for `generate_patient_id_on_people`. } ``` -### Muting +## muting Implements muting/unmuting of persons and places. Supports multiple forms for each action, for webapp and sms workflows. +### Muting action -##### Muting action +Updates the target contact and all its descendants, setting the `muted` property equal to the current date in ISO format. -As of 3.12.0, client-side muting only runs on new reports or new contacts, before they are saved in the local database: +#### Client-side -- updates the target contact and all its descendants[10], setting the `muted` property equal to the device's current `date` in ISO format[8]. -- adds/updates the `muting_history`[11] property on every updated contact, to keep track of all the updates that have been processed client-side, as well as the last known server-side state of the contact and sets the `last_update` property to `client_side` -- updates the report doc to add a `client_side_transitions` property to track which transitions have run client-side +*Added in 3.12.0* -Server-side: +Client-side muting runs offline on a user's device. Only the contacts and reports available on the device will be updated. -- updates the target contact and all its descendants[1], setting the `muted` property equal to the current `date` in ISO format[2]. If the contact was already muted by a client, the `muted` date will be overwritten. The client-side `muting_history` will have a copy of the client-side muting date. -- adds a `muting_history` entry to Sentinel `info` docs for every updated contact[7] -- updates all connected registrations[3], changing the state of all unsent[4] `scheduled_tasks` to `muted` -- as of 3.12.0, updates the contact's client-side `muting_history` to set the `last_update` property to `server_side` and update the `server_side` section with the current date and muted state. -- as of 3.12.0, if the report was processed client-side, all "following" muting/unmuting events that have affected the same contacts will be replayed. This means the transition _could_ end up running multiple times over the same report[9]. +- Sets the `muted` property on the target contact and all its descendants to the device's current `date` (the moment the report is processed). +- Adds/updates the [`muting_history` property]({{< ref "#client-side-muting-history" >}}) on every updated contact, to keep track of all the updates that have been processed client-side, as well as the last known server-side state of the contact and sets the `last_update` property to `client_side` +- Updates the report doc to add a `client_side_transitions` property to track which transitions have run client-side -##### Unmuting action: +#### Server-side -As of 3.12.0, client-side unmuting only runs on new reports before they are saved in the local database: +Server-side muting runs as a typical Sentinel transition. Contacts that are already in the correct state are skipped. This applies to updates to the contact itself, updates to the Sentinel `muting_history` and to the connected registrations (registrations of a contact that is already in the correct state will not be updated). -- updates the target contact's topmost muted ancestor[10][5] and all its descendants, removing the `muted` property. -- adds/updates the `muting_history`[9] property on every updated contact, sets the last known server-side state of the contact and sets the `last_update` property to `client_side` -- updates the report doc to add a `client_side_transitions` property to track which transitions have run client-side +- Sets the `muted` property on the target contact and all its descendants to the moment Sentinel processed the muting action. + - If the contact was already muted by a client, the `muted` date will be overwritten. The [client-side `muting_history`]({{< ref "#client-side-muting-history" >}}) will have a copy of the client-side muting date. +- Adds a [`muting_history` entry]({{< ref "#server-side-muting-history" >}}) to Sentinel `info` docs for every updated contact +- Updates all connected registrations (for the target contact and descendants), changing the state of all unsent `scheduled_tasks` to `muted` + - Unsent `scheduled_tasks` have either a `scheduled` or `pending` state +- Updates the contact's client-side `muting_history` to set the `last_update` property to `server_side` and update the `server_side` section with the current date and muted state. +- If the report was processed client-side, all "following" muting/unmuting events that have affected the same contacts will be replayed. This means the transition _could_ end up running multiple times over the same report. + - Replaying is required due to how PouchDB <-> CouchDB synchronization does not respect the order in which the documents have been created, to ensure that contacts end up in the correct muted state. -Server-side: +### Unmuting action -- updates the target contact's topmost muted ancestor[1][5] and all its descendants, removing the `muted` property -- adds a `muting_history` entry to Sentinel `info` docs for every updated contact[7] -- updates all connected registrations[3], changing the state of all present/future[6] `muted` `scheduled_tasks` to `scheduled` -- as of 3.12.0, updates the contact's client-side `muting_history` to set the `last_update` property to `server_side` and update the `server_side` section with the current date and muted state. -- as of 3.12.0, if the report was processed client-side, all "following" muting/unmuting events that have affected the same contacts will be replayed. This means the transition _could_ end up running multiple times over the same report[10]. +Updates the target contact's topmost muted ancestor and all its descendants, removing the `muted` property. Because the muted state is inherited, unmuting cascades upwards to the highest level muted ancestor. If none of the ancestors is muted, unmuting cascades downwards only. -[1] Contacts that are already in the correct state are skipped. This applies to updates to the contact itself, updates to the Sentinel `muting_history` and to the connected registrations (registrations of a contact that is already in the correct state will not be updated). -[2] The date represents the moment Sentinel has processed the muting action -[3] target contact and descendants' registrations -[4] `scheduled_tasks` being in either `scheduled` or `pending` state -[5] Because the muted state is inherited, unmuting cascades upwards to the highest level muted ancestor. If none of the ancestors is muted, unmuting cascades downwards only. -[6] `scheduled_tasks` which are due today or in the future. All `scheduled_tasks` with a due date in the past will remain unchanged. -[8] The date represents the device's date when the report is processed. -[9] Replaying is required due to how PouchDB <-> CouchDB synchronization does not respect the order in which the documents have been created, to ensure that contacts end up in the correct muted state. -[10] The updated contacts are limited to the contacts available on the device. +#### Client-side + +*Added in 3.12.0* + +Client-side unmuting runs offline on a user's device. Only the contacts and reports available on the device will be updated. + +- Adds/updates the [`muting_history` property]({{< ref "#client-side-muting-history" >}}) on every updated contact, sets the last known server-side state of the contact and sets the `last_update` property to `client_side` +- Updates the report doc to add a `client_side_transitions` property to track which transitions have run client-side + +#### Server-side + +Server-side unmuting runs as a typical Sentinel transition. Contacts that are already in the correct state are skipped. This applies to updates to the contact itself, updates to the Sentinel `muting_history` and to the connected registrations (registrations of a contact that is already in the correct state will not be updated). + +- Adds a [`muting_history` entry]({{< ref "#server-side-muting-history" >}}) to Sentinel `info` docs for every updated contact +- Updates all connected registrations (for the target contact and descendants), changing the state of all present/future `scheduled_tasks` (ones due today or in the future) with the `muted` state to have the `scheduled` state. + - All `scheduled_tasks` with a due date in the past will remain unchanged. +- Updates the contact's [client-side `muting_history`]({{< ref "#client-side-muting-history" >}}) to set the `last_update` property to `server_side` and update the `server_side` section with the current date and muted state. +- If the report was processed client-side, all "following" muting/unmuting events that have affected the same contacts will be replayed. This means the transition _could_ end up running multiple times over the same report. + - Replaying is required due to how PouchDB <-> CouchDB synchronization does not respect the order in which the documents have been created, to ensure that contacts end up in the correct muted state. + +### Muting history + +#### Server-side muting history -##### [7] Muting history Each time the `muted` state of a contact changes, an entry is added to a `muting_history` list saved in Sentinel `info` docs (stored as an array property with the same name). Entries in `muting_history` contain the following information: @@ -408,8 +418,10 @@ Entries in `muting_history` contain the following information: | date | Date in ISO Format | | report_id | An `_id` reference to the report that triggered the action | +#### Client-side muting history + +*Added in 3.12.0* -##### [11] Client-side Muting history as of 3.12.0 Each time the client changes the `muted` state of a contact, an entry is added to a `muting_history` property on the contact's doc. The `last_update` entry is also changed to `client_side`. The `muting_history` property contains the following information: @@ -424,8 +436,7 @@ The `muting_history` property contains the following information: | client_side[].date | Date in ISO format | Client-side muting/unmuting date | | client_side[].report_id | uuid | The uuid of the muting/unmuting report that triggered the update | - -#### Configuration +##### Configuration Configuration is stored in the `muting` field of `app_settings.json`. | Property | Description | @@ -501,15 +512,15 @@ When muting events are processed both client-side and server-side, there is no g } ``` -### Accept patient reports +## accept_patient_reports Allow reporting about patient and place centric workflows by -- validating the report, -- assigning the relevant subject (patient or place) to the report if a registration with the given shortcode (patient_id or place_id) exists, -- clearing messages on the registration, and -- generating response messages on the report. +- validating the report +- assigning the relevant subject (patient or place) to the report if a registration with the given shortcode (patient_id or place_id) exists +- clearing messages on the registration +- generating response messages on the report -#### Example +##### Example ```json "transitions": { @@ -546,7 +557,7 @@ Allow reporting about patient and place centric workflows by }] ``` -### Accept case reports +## accept_case_reports Allow reporting about case centric workflows by - validating the report configuration documentation, @@ -554,7 +565,7 @@ Allow reporting about case centric workflows by - clearing messages on the registration, and - generating response messages on the report. -#### Example +##### Example ```json "registrations": [{ @@ -576,13 +587,13 @@ Allow reporting about case centric workflows by }] ``` -### self_report +## self_report Updates a `data_record` to set its patient to its sender. The resulting doc will have `fields.patient_uuid` and `fields.patient_id` filled with the sender's information. Provides hydrated patient information to subsequent transitions. The `sender` is the contact associated with the phone number that sent the original SMS. If a doc already contains a `patient` field, does not have a sender or its `form` is not configured to be enabled for this transition, it will be ignored. -#### Configuration +##### Configuration Configuration is stored in the `self_report` field of `app_settings.json` as a list of objects connecting forms to messages. Every object should have this structure: @@ -635,10 +646,10 @@ Supported `events_types` are: ] ``` -### update_clinics +## update_clinics Adds a contact’s info to a data record so as to attribute an incoming SMS message or report to the appropriate contact. -#### Configuration +##### Configuration As of version 3.12 you can add configuration to send a message whenever a contact match fails while running this transition. Configuration is stored in the `update_clinics` field of app_settings.json as a list of objects connecting forms to messages. Every object should have this structure: | Property | Description | @@ -680,11 +691,11 @@ If this configuration is not set then the message defaults to what is set in the ] ``` -### create_user_for_contacts +## create_user_for_contacts Users are automatically created for certain contacts. Both creating a new user for a new contact and replacing an existing user with a new user are supported. -#### Configuration +##### Configuration Several configurations are required in `app_settings` to enable the `create_user_for_contacts` transition. @@ -704,8 +715,6 @@ The [`app_url` property]({{< ref "building/reference/app-settings#app_settingsjs } ``` -#### Create User - When adding a new person contact, the `create_user_for_contacts` transition can be triggered to create a new user associated with that contact. _Available since 4.2.x._ ##### Example scenario @@ -732,7 +741,7 @@ The new person contacts _must_ have the following fields set: See the `person-create` contact form provided in the [Default config](https://github.com/medic/cht-core/tree/master/config/default) as an example. This form will trigger the creation of a new user for the contact when the role is set to `chw` or `chw_supervisor` and a phone number is provided. -#### Replace User +### Replace User An existing offline user can be replaced on a device so that a new user can use that device without needing to immediately sync with the server. _Available since 4.1.x._ @@ -775,7 +784,7 @@ See the `replace_user` app form provided in the [Default config](https://github. } ``` -#### Troubleshooting +## Troubleshooting Configuration is validated when Sentinel starts. Issues with the configuration will be show in the Sentinel logs. diff --git a/content/en/building/reference/extension-libs.md b/content/en/building/reference/extension-libs.md index 8ed1508ee..90cbf50f9 100644 --- a/content/en/building/reference/extension-libs.md +++ b/content/en/building/reference/extension-libs.md @@ -88,4 +88,4 @@ The function will now be available via the CHT API for [tasks]({{< ref "building #### CHT xPath functions -To execute the function from within an xform use the [`cht:extension-lib` xpath function]({{< ref "forms/app#chtextension-lib" >}}). +To execute the function from within an xform use the [`cht:extension-lib` xpath function]({{< ref "building/forms/app#chtextension-lib" >}}). diff --git a/content/en/building/reference/forms/_index.md b/content/en/building/reference/forms/_index.md deleted file mode 100644 index ff4a8c122..000000000 --- a/content/en/building/reference/forms/_index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: "forms/" -linkTitle: "forms/" -weight: 2 -description: > - **Forms**: All the App forms, Contact forms, and Collect forms -relevantLinks: > - docs/design/best-practices -keywords: app-forms -aliases: - - /apps/reference/forms/ ---- - diff --git a/content/en/building/tasks/complex-tasks.md b/content/en/building/tasks/complex-tasks.md index 26ba4080c..40048582f 100644 --- a/content/en/building/tasks/complex-tasks.md +++ b/content/en/building/tasks/complex-tasks.md @@ -128,11 +128,11 @@ We're using the `this.lmp` value which was calculated and saved in the `appliesI This function calculates timestamps for the start and end of each event. Then, it uses the [Utils helper library]({{< ref "building/reference/_partial_utils" >}}) to see if _either_ a _pnc_ or an _assessment_ followup is present within those timestamps. -The concept of _task completion_ is covered in more depth in [Task Completion vs Cancellation]({{< ref "building/guides/tasks/query-task-data#completion-vs-cancellation" >}}). +The concept of _task completion_ is covered in more depth in [Task Completion vs Cancellation]({{< ref "building/tasks/managing-tasks/query-task-data#completion-vs-cancellation" >}}). ## Actions ``` 5. The first pregnancy visit should prompt the CHW to ask some additional questions ``` -The `modifyContent` attribute allows the task to pass data from the task (in JavaScript) into the action app form (xlsx). Check out the guide for [Passing data from a task into the app form]({{< ref "building/guides/tasks/pass-data-to-form" >}}). +The `modifyContent` attribute allows the task to pass data from the task (in JavaScript) into the action app form (xlsx). Check out the guide for [Passing data from a task into the app form]({{< ref "building/tasks/managing-tasks/pass-data-to-form" >}}). diff --git a/content/en/building/guides/tasks/_index.md b/content/en/building/tasks/managing-tasks/_index.md similarity index 53% rename from content/en/building/guides/tasks/_index.md rename to content/en/building/tasks/managing-tasks/_index.md index 04ba1979f..ea675704f 100644 --- a/content/en/building/guides/tasks/_index.md +++ b/content/en/building/tasks/managing-tasks/_index.md @@ -1,9 +1,10 @@ --- -title: "Tasks" -linkTitle: "Tasks" -weight: 100 +title: Managing tasks +linkTitle: Managing tasks +weight: 5 description: > Building and managing Tasks and their data aliases: + - /building/guides/tasks/ - /apps/guides/tasks/ --- \ No newline at end of file diff --git a/content/en/building/guides/tasks/pass-data-to-form.md b/content/en/building/tasks/managing-tasks/pass-data-to-form.md similarity index 99% rename from content/en/building/guides/tasks/pass-data-to-form.md rename to content/en/building/tasks/managing-tasks/pass-data-to-form.md index 5dd6fd03a..31ed09108 100644 --- a/content/en/building/guides/tasks/pass-data-to-form.md +++ b/content/en/building/tasks/managing-tasks/pass-data-to-form.md @@ -7,7 +7,7 @@ relatedContent: > building/tasks/complex-tasks building/tutorials/app-forms building/tasks/tasks-js - building/guides/forms/form-inputs + building/forms/configuring/form-inputs aliases: - /apps/guides/tasks/pass-data-to-form --- diff --git a/content/en/building/guides/tasks/query-task-data.md b/content/en/building/tasks/managing-tasks/query-task-data.md similarity index 100% rename from content/en/building/guides/tasks/query-task-data.md rename to content/en/building/tasks/managing-tasks/query-task-data.md diff --git a/content/en/building/guides/tasks/task-schema-parameters.md b/content/en/building/tasks/managing-tasks/task-schema-parameters.md similarity index 100% rename from content/en/building/guides/tasks/task-schema-parameters.md rename to content/en/building/tasks/managing-tasks/task-schema-parameters.md diff --git a/content/en/building/tasks/simple-tasks.md b/content/en/building/tasks/simple-tasks.md index dda46951c..bf7b02e83 100644 --- a/content/en/building/tasks/simple-tasks.md +++ b/content/en/building/tasks/simple-tasks.md @@ -25,7 +25,7 @@ Tasks prompt users to complete activities on a programmatic schedule. This guide * Complete the [App Forms Tutorial]({{< ref "building/tutorials/app-forms" >}}) - Tasks prompt users to _complete activities_ by opening an app form. The app forms tutorial produces an _assessment_ app form which we will use here. You can also elect to substitute that with any [example app form](https://github.com/medic/cht-core/tree/master/config/default/forms/app). * Complete the [Contact and User Management - Part 1 Tutorial]({{< ref "building/contact-management/contact-and-users-2" >}}) to create a hierarchy of contacts and an offline CHW user. -* Read [Understanding the data available in tasks and targets]({{< ref "building/guides/tasks/task-schema-parameters" >}}) +* Read [Understanding the data available in tasks and targets]({{< ref "building/tasks/managing-tasks/task-schema-parameters" >}}) ## Implementation Steps @@ -59,9 +59,9 @@ The `tasks.js` file follows the JavaScript ES6 Module syntax and _exports_ an ar * `name` - This is used exclusively in the task's backend data. The _name_ isn't controlling any element of the tasks's behaviour, appearance, or schedule. * `title` - This is controlling the "Task title" as defined in the [anatomy of a task]({{< ref "design/best-practices#anatomy-of-a-task" >}}). * `icon` - This references a [resource]({{< ref "building/reference/resources" >}}) to be used as the task's icon. Refer to [anatomy of a task]({{< ref "design/best-practices#anatomy-of-a-task" >}}). -* `appliesTo` - We use `contacts` because we want one task _per contact_. For more details, read [Understanding the data available in tasks and targets]({{< ref "building/guides/tasks/task-schema-parameters" >}}). +* `appliesTo` - We use `contacts` because we want one task _per contact_. For more details, read [Understanding the data available in tasks and targets]({{< ref "building/tasks/managing-tasks/task-schema-parameters" >}}). * `appliesToType` - The task should only show for contacts with `contact_type` equal to `patient`. This `appliesToType` is a _short-hand_ equivalent to `appliesIf: c => c.contact.contact_type === 'patient'`. -* `appliesIf` - A predicate which gates the creation of the task's event schedule. For more details, read [Understanding the data available in tasks and targets]({{< ref "building/guides/tasks/task-schema-parameters" >}}). +* `appliesIf` - A predicate which gates the creation of the task's event schedule. For more details, read [Understanding the data available in tasks and targets]({{< ref "building/tasks/managing-tasks/task-schema-parameters" >}}). * `user.parent.contact_type` - The user is a CHW iff their parent is of type `chw_area`. The user object is hydrated. * `!c.contact.date_of_death` - The contact must be alive * `!c.contact.muted` - The contact must be unmuted diff --git a/content/en/building/tasks/tasks-js.md b/content/en/building/tasks/tasks-js.md index a610bf67d..b08892019 100644 --- a/content/en/building/tasks/tasks-js.md +++ b/content/en/building/tasks/tasks-js.md @@ -29,9 +29,9 @@ Task generation occurs on the client periodically and creates documents which tr | `name`| `string` | A unique identifier for the task. Used for querying task completeness. | yes, unique | | `icon` | `string` | The icon to show alongside the task. Should correspond with a value defined in `resources.json`. | no | | `title` | `translation key` | The title of the task (labeled above). | yes | -| `appliesTo` | `'contacts'` or `'reports'` | Do you want to emit one task per report, or one task per contact? See [Understanding the Parameters in the Task Schema]({{< ref "building/guides/tasks/task-schema-parameters.md" >}}). | yes | -| `appliesIf` | `function(contact, report)` | If `appliesTo: 'contacts'`, this function is invoked once per contact and `report` is undefined. If `appliesTo: 'reports'`, this function is invoked once per report. Return true if the task should appear for the given documents. See [Understanding the Parameters in the Task Schema]({{< ref "building/guides/tasks/task-schema-parameters.md" >}}). | no | -| `appliesToType` | `string[]` | Filters the contacts or reports for which `appliesIf` will be evaluated. If `appliesTo: 'reports'`, this is an array of form codes. If `appliesTo: 'contacts'`, this is an array of contact types. For example, `['person']` or `['clinic', 'health_center']`. For example, `['pregnancy']` or `['P', 'pregnancy']`. See [Understanding the Parameters in the Task Schema]({{< ref "building/guides/tasks/task-schema-parameters.md" >}}). | no | +| `appliesTo` | `'contacts'` or `'reports'` | Do you want to emit one task per report, or one task per contact? See [Understanding the Parameters in the Task Schema]({{< ref "building/tasks/managing-tasks/task-schema-parameters.md" >}}). | yes | +| `appliesIf` | `function(contact, report)` | If `appliesTo: 'contacts'`, this function is invoked once per contact and `report` is undefined. If `appliesTo: 'reports'`, this function is invoked once per report. Return true if the task should appear for the given documents. See [Understanding the Parameters in the Task Schema]({{< ref "building/tasks/managing-tasks/task-schema-parameters.md" >}}). | no | +| `appliesToType` | `string[]` | Filters the contacts or reports for which `appliesIf` will be evaluated. If `appliesTo: 'reports'`, this is an array of form codes. If `appliesTo: 'contacts'`, this is an array of contact types. For example, `['person']` or `['clinic', 'health_center']`. For example, `['pregnancy']` or `['P', 'pregnancy']`. See [Understanding the Parameters in the Task Schema]({{< ref "building/tasks/managing-tasks/task-schema-parameters.md" >}}). | no | | `contactLabel` | `string` or `function(contact, report)` | Controls the label describing the subject of the task. Defaults to the name of the contact (`contact.contact.name`). | no | | `resolvedIf` | `function(contact, report, event, dueDate)` | Return true to mark the task as "resolved". A resolved task uses memory on the phone, but is not displayed. | no, if any `actions[n].type` is `'report'` | | `events` | `object[]` | An event is used to specify the timing of the task. | yes | @@ -44,7 +44,7 @@ Task generation occurs on the client periodically and creates documents which tr | `actions[n].type` | `'report'` or `'contact'` | When `'report'`, the action opens the given form. When `'contact'`, the action redirects to a contact's profile page. Defaults to 'report'. | no | | `actions[n].form` | `string` | The code of the form that should open when you select the action. | yes, if `actions[n].type` is `'report'` | | `actions[n].label`| `translation key` | The label that should appear on the task summary screen if multiple actions are present. | no | -| `actions[n].modifyContent`| `function (content, contact, report, event)` | Set the values on the content object to control the data which will be passed as `inputs` to the form which opens when the action is selected. See [Passing data from a task into the app form]({{< ref "building/guides/tasks/pass-data-to-form" >}}). | no | +| `actions[n].modifyContent`| `function (content, contact, report, event)` | Set the values on the content object to control the data which will be passed as `inputs` to the form which opens when the action is selected. See [Passing data from a task into the app form]({{< ref "building/tasks/managing-tasks/pass-data-to-form" >}}). | no | | `priority` | `object` or `function(contact, report)` returning object of same schema | Controls the "high risk" line seen above. | no | | `priority.level` | `high` or `medium` | Tasks that are `high` will display a high risk icon with the task. Default: `medium`. | no | | `priority.label` | `translation key` | Text shown with the task associated to the risk level. | no | diff --git a/content/en/building/training/training-cards/_index.md b/content/en/building/training/training-cards/_index.md index 5190d2953..53cc1ddc3 100644 --- a/content/en/building/training/training-cards/_index.md +++ b/content/en/building/training/training-cards/_index.md @@ -24,10 +24,14 @@ _Introduced in 4.2.0_ ## Accessing -When health workers open or reload their app, configured training cards will automatically show on top of all other content in the app. If it is not a convenient time to complete the training, they can cancel out at any time and will be prompted again the next day they open their app (training will start from the beginning). +When health workers open or reload their app, configured training cards will automatically show on top of all other content in the app. If it is not a convenient time to complete the training, they can cancel out at any time and will be prompted again the next day they open their app (training will start from the beginning). {{% alert title="Note" %}} If there are multiple training sets configured to start on the same day, the CHT will determine the order alphabetically based on the form ID. Subsequent training sets will only be displayed once the previous ones are either completed or no longer valid the next day the app is opened. {{% /alert %}} +Training materials can also be accessed in the training page found in the auxiliary menu for users to revisit as needed. Completed training is displayed with a green checkmark. _Added in 4.15.0_. + +{{< figure src="training-materials-page.png" link="training-materials-page.png" class="col-10 col-lg-10" >}} + ## Completing Health workers read through each card one by one in a predefined sequence, tapping “Next” on each card. When they are finished reading all cards, they tap “Submit” on the last card. The training set is now considered complete and they can continue using their app. Completed training sets show up on the [main list]({{< relref "building/features/reports/#main-list" >}}) of the Reports tab and they won’t be asked to complete this set again. If there are additional training sets to complete, they will be shown the next day the app is opened. diff --git a/content/en/building/training/training-cards/training-cards-configuration.md b/content/en/building/training/training-cards/training-cards-configuration.md index d4e4a6366..b23f5e7d7 100644 --- a/content/en/building/training/training-cards/training-cards-configuration.md +++ b/content/en/building/training/training-cards/training-cards-configuration.md @@ -15,13 +15,13 @@ aliases: - /apps/guides/training/training-cards/ --- -[Training Cards]({{< relref "building/training/training-cards" >}}) enable remote training from within the CHT by showing a sequence of "cards" containing content provided by App Developers. The content might include information about a newly deployed feature, changes to a [care guide]({{< relref "building/concepts/care-guides" >}}), or simply a reminder about an underused feature or workflow. Enketo forms are used to display the content, and App Developers can specify a start date, duration, and to which [user roles]({{< relref "building/reference/app-settings/user-roles" >}}) the cards should be shown. Like [app forms]({{< relref "building/reference/forms/app" >}}), forms used by training cards will automatically be downloaded to the user’s devices. +[Training Cards]({{< relref "building/training/training-cards" >}}) enable remote training from within the CHT by showing a sequence of "cards" containing content provided by App Developers. The content might include information about a newly deployed feature, changes to a [care guide]({{< relref "building/concepts/care-guides" >}}), or simply a reminder about an underused feature or workflow. Enketo forms are used to display the content, and App Developers can specify a start date, duration, and to which [user roles]({{< relref "building/reference/app-settings/user-roles" >}}) the cards should be shown. Like [app forms]({{< relref "building/forms/app" >}}), forms used by training cards will automatically be downloaded to the user’s devices. {{% alert title="Note" %}} Example training forms are available [here]({{< relref "building/training/training-cards-resources" >}}) and provide a good starting point. {{% /alert %}} # Step 1: Create the training form -Create an [XLS Form]({{< relref "building/reference/forms/app#xlsform" >}}). In the following example, the training form is called `my_new_feature`, it has some text in the `label::en` column, and some images in the column `media::images` to illustrate the feature. +Create an [XLS Form]({{< relref "building/forms/app#xlsform" >}}). In the following example, the training form is called `my_new_feature`, it has some text in the `label::en` column, and some images in the column `media::images` to illustrate the feature. {{< figure src="step-1-xls-form.png" link="step-1-xls-form.png" class="left col-10" >}} @@ -37,11 +37,11 @@ Important, define the `form_id` located in the `settings` sheet with the prefix # Step 3: Configure the training form -Create a [properties file]({{< relref "building/tutorials/form-properties#3-define-the-forms-context" >}}) to define the starting date of the training, the number of days it will be active, and the user roles that can access the training. In our example, the file name is `my_new_feature.properties.json` and contains the following properties: +Create a [properties file]({{< relref "building/forms/form-properties#3-define-the-forms-context" >}}) to define the starting date of the training, the number of days it will be active, and the user roles that can access the training. In our example, the file name is `my_new_feature.properties.json` and contains the following properties: ``` { - "title": "", + "title": "New workflow", "context": { "start_date": "2023-07-13", "duration": 60, @@ -53,7 +53,7 @@ Create a [properties file]({{< relref "building/tutorials/form-properties#3-defi In the example above, the training cards could be shown to any user with the "nurse" role between July 13, 2023 and September 11, 2023 (inclusive). See more information about these configuration settings below: | Property | Description | |---|----| -| "title" | Optional. Enketo’s form title that is displayed under the modal’s header section. Leave this property empty if you don’t need to display a title. | +| "title" | Enketo’s form title that is displayed in the modal’s header section. | | "start_date" | Optional. Define the training start day using `yyyy-mm-dd` format. If not defined then the training will start immediately. | | "duration" | Optional. Number of days this training should be active. If not defined then the training will never expire. | | "user_roles" | Optional. List of user roles that can access this training. If not defined then all users can access the training. | @@ -64,7 +64,7 @@ In the example above, the training cards could be shown to any user with the "nu If your training form has images, create a folder with the same name as the form and add `-media` suffix. In our example, the form name is `my_new_feature`, then the folder name should be `my_new_feature-media`. -Inside that new folder, make another one called images and put inside all the `images` that your form needs. See more about [multimedia in forms]({{< relref "building/guides/forms/multimedia" >}}). +Inside that new folder, make another one called images and put inside all the `images` that your form needs. See more about [multimedia in forms]({{< relref "building/forms/configuring/multimedia" >}}). # Step 5: Put everything in the right place diff --git a/content/en/building/training/training-cards/training-materials-page.png b/content/en/building/training/training-cards/training-materials-page.png new file mode 100644 index 000000000..e6f7aefda Binary files /dev/null and b/content/en/building/training/training-cards/training-materials-page.png differ diff --git a/content/en/building/translations/localizing-translations.md b/content/en/building/translations/localizing-translations.md index c7f5bec55..15d3a1b2d 100644 --- a/content/en/building/translations/localizing-translations.md +++ b/content/en/building/translations/localizing-translations.md @@ -44,7 +44,7 @@ Translations for XForms are defined within the forms themselves. The XLSForm not Submitted forms are shown on the Reports tab, with each value in the report displayed alongside a label. The label for each value is represented by a key in the `report.{form-name}.{field-name}` format, which can be translated by including the key and translation in the [language files]( {{< relref "#translations" >}} ). If the label is omitted in the translation the full key will show in the app. {{% alert title="Note" color="info" %}} -To hide report fields from showing on the Reports view altogether, the containing group or field must be included as `hidden_fields`, as per the [form properties file]( {{< ref "building/reference/forms/app#properties" >}} ). +To hide report fields from showing on the Reports view altogether, the containing group or field must be included as `hidden_fields`, as per the [form properties file]( {{< ref "building/forms/app#properties" >}} ). {{% /alert %}} ## Build diff --git a/content/en/building/translations/managing-translations.md b/content/en/building/translations/managing-translations.md index a70e1648e..c8b2f5672 100644 --- a/content/en/building/translations/managing-translations.md +++ b/content/en/building/translations/managing-translations.md @@ -20,7 +20,7 @@ Like the rest of the code the translation files live in the GitHub repo. These t New languages must be added and configured in several places: -- Create a new `messages-xx.properties` file in the [`api/resources/translations`](https://github.com/medic/cht-core/tree/master/api/resources/translations) folder, replacing "xx" with the 2 or 3 letter [language code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes). +- Create a new `messages-xx.properties` file in the [`api/resources/translations`](https://github.com/medic/cht-core/tree/master/api/resources/translations) folder, replacing "xx" with the 2 or 3 letter [language code](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes). - Add the language to the [`LOCAL_NAME_MAP` in api](https://github.com/medic/cht-core/blob/e6d184946affc62773d569168216a5b913f38a30/api/src/translations.js#L17). Use the language code for the key, and the local name followed by the English name for the language in brackets, eg: "fr: 'Français (French)'". - Import the moment language pack in the [main.ts file](https://github.com/medic/cht-core/blob/e6d184946affc62773d569168216a5b913f38a30/webapp/src/ts/main.ts#L23). If moment doesn't provide the required language pack you may need to contribute it upstream to the moment library. diff --git a/content/en/building/tutorials/app-forms.md b/content/en/building/tutorials/app-forms.md index 0187acc2e..47ed716ba 100644 --- a/content/en/building/tutorials/app-forms.md +++ b/content/en/building/tutorials/app-forms.md @@ -5,8 +5,8 @@ weight: 7 description: > Building CHT app forms relatedContent: > - building/reference/forms/contact - building/reference/forms/app + building/forms/contact + building/forms/app design/best-practices/#forms design/best-practices/#content-and-layout design/best-practices/#summary-page @@ -29,11 +29,11 @@ You will be building assessment workflow that allows Community Health Workers to ## Brief Overview of Key Concepts -*[App forms]({{< ref "building/reference/forms/app" >}})* serve as actions within the app. +*[App forms]({{< ref "building/forms/app" >}})* serve as actions within the app. -*[XLSForm]({{< ref "building/reference/forms/app#xlsform" >}})* is a form [standard](http://xlsform.org/en/) created to help simplify the authoring of forms in Excel. +*[XLSForm]({{< ref "building/forms/app#xlsform" >}})* is a form [standard](http://xlsform.org/en/) created to help simplify the authoring of forms in Excel. -*[XForm]({{< ref "building/reference/forms/app#xform" >}})* is a CHT-enhanced version of the [ODK XForm](https://getodk.github.io/xforms-spec/) standard. +*[XForm]({{< ref "building/forms/app#xform" >}})* is a CHT-enhanced version of the [ODK XForm](https://getodk.github.io/xforms-spec/) standard. ## Required Resources diff --git a/content/en/building/tutorials/application-graphics.md b/content/en/building/tutorials/application-graphics.md index 5182fdee7..35ec101b3 100644 --- a/content/en/building/tutorials/application-graphics.md +++ b/content/en/building/tutorials/application-graphics.md @@ -222,6 +222,6 @@ To modify the icon used in contacts, you will need to edit the icon subkey in ap Finally run the command: `cht --local upload-app-settings` -To customise the icons used in tasks or the action bar, you will need to edit a form properties file and add an icon property as outline in [form properties]({{< ref "building/tutorials/form-properties" >}}) tutorial. +To customise the icons used in tasks or the action bar, you will need to edit a form properties file and add an icon property as outline in [form properties]({{< ref "building/forms/form-properties" >}}) tutorial. To customise the icons used in targets, you will need to add an icon property in a target's definition as shown in the [targets]({{< ref "building/targets/target-widgets" >}}) tutorial. diff --git a/content/en/building/tutorials/application-tests.md b/content/en/building/tutorials/application-tests.md index c33b06445..c8d93331e 100644 --- a/content/en/building/tutorials/application-tests.md +++ b/content/en/building/tutorials/application-tests.md @@ -6,7 +6,7 @@ description: > Guides for writing automated tests for CHT applications relatedContent: > building/reference - building/guides/tasks/query-task-data/#testing-task-document-data + building/tasks/managing-tasks/query-task-data/#testing-task-document-data aliases: - /apps/tutorials/application-tests --- @@ -425,7 +425,7 @@ it('followup schedule', async () => { }); ``` -You may [pass other data](https://docs.communityhealthtoolkit.org/building/guides/tasks/pass-data-to-form/) from a task to the action form using [modifyContent ](https://docs.communityhealthtoolkit.org/building/guides/tasks/pass-data-to-form/#modifycontent)attribute of a task. You can also verify that these data are present in the task. +You may [pass other data](https://docs.communityhealthtoolkit.org/building/tasks/managing-tasks/pass-data-to-form/) from a task to the action form using [modifyContent ](https://docs.communityhealthtoolkit.org/building/tasks/managing-tasks/pass-data-to-form/#modifycontent)attribute of a task. You can also verify that these data are present in the task. ```js diff --git a/content/en/building/tutorials/sms-schedules.md b/content/en/building/tutorials/sms-schedules.md index 65732b76d..a2801b1b2 100644 --- a/content/en/building/tutorials/sms-schedules.md +++ b/content/en/building/tutorials/sms-schedules.md @@ -6,7 +6,7 @@ description: > Building CHT application SMS schedules relatedContent: > building/reference/app-settings/schedules - building/concepts/forms + building/forms building/features/messaging building/guides/messaging @@ -24,7 +24,7 @@ This tutorial takes you through how to set up SMS schedules for CHT applications *[SMS schedules]({{< ref "building/reference/app-settings/schedules" >}})* are a series of SMS messages that are to be sent to specific contacts at future dates and times. They are defined in either the `base_settings.json` or the `app_settings/schedules.json` file and compiled into the *[app_settings.json]({{< ref "building/reference/app-settings" >}})* file with the `compile-app-settings` action in the `cht-conf` tool. -SMS schedules can be triggered by *[SMS forms]({{< ref "building/tutorials/sms-forms" >}})* or *[App forms]({{< ref "building/reference/forms/app" >}})*. +SMS schedules can be triggered by *[SMS forms]({{< ref "building/tutorials/sms-forms" >}})* or *[App forms]({{< ref "building/forms/app" >}})*. ## Required Resources diff --git a/content/en/building/workflows/death-reporting.md b/content/en/building/workflows/death-reporting.md index 454288ce3..3520ee432 100644 --- a/content/en/building/workflows/death-reporting.md +++ b/content/en/building/workflows/death-reporting.md @@ -32,7 +32,7 @@ You will need to: 1. [Configure your application hierarchy]({{% ref "building/tutorials/application-settings" %}}) 2. [Create some contacts]({{% ref "building/contact-management/contact-and-users-1" %}}) 3. [Know how to create an app form]({{% ref "building/tutorials/app-forms" %}}) -4. [Know how to set form properties]({{% ref "building/tutorials/form-properties" %}}) +4. [Know how to set form properties]({{% ref "building/forms/form-properties" %}}) ## Implementation Steps @@ -51,7 +51,7 @@ It is common to want to know the date of death, place of death, or cause of deat It doesn't make sense to have "places" in your hierarchy that can be deceased. It also doesn't make sense for somebody who is dead to die again. But can the administration of a health facility die? That is for you to decide. -This snippet is an example [form properties file]({{% ref "building/tutorials/form-properties" %}}) which constrains the death form to show only for contacts which: +This snippet is an example [form properties file]({{% ref "building/forms/form-properties" %}}) which constrains the death form to show only for contacts which: 1. Are currently alive 2. Are within a family diff --git a/content/en/contribute/code/core/automated-tests.md b/content/en/contribute/code/core/automated-tests.md index a0cc544b0..05e875086 100644 --- a/content/en/contribute/code/core/automated-tests.md +++ b/content/en/contribute/code/core/automated-tests.md @@ -154,6 +154,10 @@ Setting the `DEBUG` environment variable (e.g. [`DEBUG=true npm run wdio-local`] - Prevent Mocha from automatically retrying tests that fail (by default a failing test is retried 5 times, details in the [`wdio.conf`](https://github.com/medic/cht-core/blob/master/tests/wdio.conf.js#L198)file) - Prevent the `cht-e2e` Docker containers from being torn down after the test finishes +#### Run the e2e tests without re-building docker images + +After the tests are executed the first time using the command `npm run wdio-local`, the docker images are built in your local environment using the checkout branch name. If it is needed to run the tests repeatedly and there is a certainty that the cht-core code didn't change, you can use the command `npm run ci-webdriver-default`. This command will execute the e2e tests as they are run with the `wdio-local` command but without re-building the images. This command uses the images that were built previously, which makes the process faster. + #### Read the logs Read the failure carefully - it often has really good info but sometimes it's just hard to find. Most importantly it tells you exactly the line in the test that failed and you can look that up in the source to see what it was trying to do. The error message itself is also really useful. Also sometimes one error causes the next, so always start with the first test failure before looking at the others. diff --git a/content/en/contribute/code/core/dev-environment.md b/content/en/contribute/code/core/dev-environment.md index 00f670c20..587963bf4 100644 --- a/content/en/contribute/code/core/dev-environment.md +++ b/content/en/contribute/code/core/dev-environment.md @@ -128,7 +128,6 @@ Create a `docker-compose.yml` and `couchdb-override.yml` files under the `~/cht- mkdir -p ~/cht-docker curl -s -o ~/cht-docker/docker-compose.yml https://staging.dev.medicmobile.org/_couch/builds_4/medic:medic:master/docker-compose/cht-couchdb.yml cat > ~/cht-docker/couchdb-override.yml << EOF -version: '3.9' services: couchdb: ports: @@ -233,7 +232,7 @@ Medic recommends you familiarise yourself with other Docker commands to make doc ### Required environment variables Medic needs the following environment variables to be declared: -- `COUCH_URL`: the full authenticated url to the `medic` DB. Locally this would be `http://myadminuser:myadminpass@localhost:5984/medic` +- `COUCH_URL`: the full authenticated url to the `medic` DB. Locally this would be `http://medic:password@localhost:5984/medic` - `COUCH_NODE_NAME`: the name of your CouchDB's node. The Docker image default is `nonode@nohost`. Other installations may use `couchdb@127.0.0.1`. You can find out by querying [CouchDB's membership API](https://docs.couchdb.org/en/stable/api/server/common.html#membership) - (optional) `COUCHDB_USER`: the name of your CouchDB's user. The Docker image default is `medic` - (optional) `COUCHDB_PASSWORD`: the credentials of your CouchDB user. The Docker image default is `password` @@ -244,7 +243,7 @@ How to permanently define environment variables depends on your OS and shell (e. ```shell export COUCH_NODE_NAME=nonode@nohost -export COUCH_URL=http://myadminuser:myadminpass@localhost:5984/medic +export COUCH_URL=http://medic:password@localhost:5984/medic ``` ## Tests diff --git a/content/en/contribute/code/core/style-guide-automated-e2e-tests.md b/content/en/contribute/code/core/style-guide-automated-e2e-tests.md index 0cb0471f9..d645d2b1c 100644 --- a/content/en/contribute/code/core/style-guide-automated-e2e-tests.md +++ b/content/en/contribute/code/core/style-guide-automated-e2e-tests.md @@ -36,13 +36,25 @@ Automated tests cover different [CHT Configs](https://github.com/medic/cht-core/ ## Tips to write test cases ### File Structure (spec files) -Test files should represent a feature within the application. Use `describe` to identify the feature and to group test cases. Use `it` to detail individual test cases covering the feature's functionality. +Test files should represent a feature within the application. Use `describe` to identify the feature and to group helper functions and test cases. Use `it` to detail individual test cases covering the feature's functionality. +It is important that the database is clean and settings are restored once the tests are complete; we re-try the tests if they fail, and we need to make sure that for every new try, the environment is as it was the first time. Additionally, each `it` block should be independent of the others, ensuring that any single test case can be rerun on its own and still work as expected. -Observe how the following example defines a `describe` using the feature name `Immunization Visit`. It contains two test cases which detail the expected results `should add a new child under 2 years old` and `should submit an immunization visit`. +Observe how the following example defines a `describe` using the feature name `Immunization Visit`. It contains constant definitions, helper functions, the `before` and `after` hooks to prepare the environment, and two test cases that detail the expected results `should add a new child under 2 years old` and `should submit an immunization visit`. Ex: ``` describe('Immunization Visit', () => { + const firstConstant = 'SampleName'; + const secondConstant = 'SampleValue'; + const firstHelperFunction = () => { .... } + const secondHelperFunction = () => { .... } + + before(async () => { .... }); + beforeEach(async () => { .... }); + + after(async () => { .... }); + afterEach(async () => { .... }); + it('should add a new child under 2 years old', () => { .... }); it('should submit an immunization visit', () => { .... }); ... @@ -81,7 +93,7 @@ You can tag mocha tests and update suites to only include or exclude certain tag Existent tags: #### @docker -Tests that should run exclusively when running the suite over docker infrastructure. These tests will fail if run over k3d. +Tests that should run exclusively when running the suite over docker infrastructure. These tests will fail if run over [k3d]({{% ref "glossary#k3d" %}}). ### Notes: diff --git a/content/en/contribute/docs/style-guide.md b/content/en/contribute/docs/style-guide.md index 4e4368631..5229dfe37 100644 --- a/content/en/contribute/docs/style-guide.md +++ b/content/en/contribute/docs/style-guide.md @@ -18,6 +18,20 @@ This documentation site does not involve release management and acceptance testi Documentation for the Community Health Toolkit is written is American English. +## Voice and tone + +The voice and tone should be inclusive and accessible to its audience. Consider that readers come from different backgrounds and may have varying levels of ability reading English, as well as technical abilities. + +### Write like you speak +Aim for a voice and tone that’s conversational and approachable. Try to sound like a knowledgeable friend who understands what the developer wants to do. + +### Get to the point quickly +Lead with what’s most important. Make steps obvious to make your documentation easily scannable. + +### Be brief +Give the audience just enough context and information to make decisions confidently. Avoid long sentences. + + ## General guidelines and best practices This section contains suggested best practices for clear, concise, and consistent content. diff --git a/content/en/contribute/medic/product-development-process/data-migration-k8s.md b/content/en/contribute/medic/product-development-process/data-migration-k8s.md new file mode 100644 index 000000000..143a3326a --- /dev/null +++ b/content/en/contribute/medic/product-development-process/data-migration-k8s.md @@ -0,0 +1,399 @@ +--- +title: "Migration from CHT 3.x to CHT 4.x in Kubernetes" +linkTitle: "K8s Data Migration to 4.x" +weight: 1 +description: > + Guide to migrate existing data from CHT 3.x to CHT 4.x in Kubernetes environments +relatedContent: > +--- + +Like the [Deploy to EKS guide]({{< relref "contribute/medic/product-development-process/deploy-on-eks" >}}), this guide is meant for Medic Teammates migrating Medic hosted CHT Core deployments. However, given there may be other users who will benefit from understanding the process, this document is published for all to read. + +CHT Core hosting architecture differs entirely between 3.x and 4.x. When both versions are running in Kubernetes, migrating data requires specific steps using the [couchdb-migration](https://github.com/medic/couchdb-migration) tool. This tool interfaces with CouchDB to update shard maps and database metadata. + +{{% alert title="Note" %}} +If after upgrading you get an error, `Cannot convert undefined or null to object` - please see [issue #8040](https://github.com/medic/cht-core/issues/8040) for a work around. This only affects CHT 4.0.0, 4.0.1, 4.1.0 and 4.1.1. It was fixed in CHT 4.2.0. +{{% /alert %}} + + +## Initial Setup + +```shell +# Set your namespace +NAMESPACE= +``` + +## Access the Source CouchDB (3.x) +```shell +# List all pods to find medic-os pod +kubectl get pods -n $NAMESPACE + +# Access the medic-os pod +kubectl exec -it -n $NAMESPACE -- bash +``` + +## Set Up Migration Tool Inside 3.x Pod + +Once inside the pod, install required dependencies: +```shell +# Add node apt repository and update apt +curl -fsSL https://deb.nodesource.com/setup_16.x | bash - +apt update + +# Ensure nodejs, npm and git are installed +apt install -y nodejs npm git + +# clone repository +git clone https://github.com/medic/couchdb-migration.git +cd couchdb-migration +npm ci --omit=dev + +# Create a global symlink to enable running commands directly +# Note: This may require sudo if npm's global directories aren't writable +npm link +``` + +## Run Pre-Migration Commands on 3.x + +While still `exec`ed in the `medic-os` container, get credentials from 1Password and set them inside the pod: +```shell +export ADMIN_USER= +export ADMIN_PASSWORD= + +# Set COUCH_URL +export COUCH_URL="http://${ADMIN_USER}:${ADMIN_PASSWORD}@localhost:5984" + +# Verify connection +curl -s $COUCH_URL/_up +``` + +Pre-index views to minimize downtime: +```shell +pre-index-views +``` + +{{% alert title="Note" %}} +If pre-indexing is omitted, 4.x API will fail to respond to requests until all views are indexed. For large databases, this could take many hours or days. +{{% /alert %}} + +Save CouchDB configuration: +```shell +get-env +``` + +Save the output containing: +- CouchDB secret (used for encrypting passwords and session tokens) +- CouchDB server UUID (used for replication checkpointing) +- CouchDB admin credentials + +You can now exit the medic-os container by running `exit`. + +## Clone the 3.x Data Volume + +First, identify the volume ID from your 3.x data: +```shell +# Get the PVC name +kubectl get pvc -n $NAMESPACE + +# Get the volume ID from the PVC +VOLUME_ID=$(kubectl get pvc -n $NAMESPACE -o jsonpath='{.spec.volumeName}') +EBS_VOLUME_ID=$(kubectl get pv $VOLUME_ID -o jsonpath='{.spec.awsElasticBlockStore.volumeID}' | cut -d'/' -f4) + +echo "Your 3.x EBS Volume ID is: $EBS_VOLUME_ID" + +# Create a snapshot of the 3.x volume +SNAPSHOT_ID=$(aws ec2 create-snapshot \ + --region eu-west-2 \ + --volume-id $EBS_VOLUME_ID \ + --description "CHT 3.x to 4.x migration snapshot" \ + --query 'SnapshotId' \ + --output text) + +echo "Created snapshot: $SNAPSHOT_ID" + +# Wait for the snapshot to complete +aws ec2 wait snapshot-completed --snapshot-ids $SNAPSHOT_ID + +# Set cluster-specific variables +# For development: +AVAILABILITY_ZONE="eu-west-2b" +CLUSTER_NAME="dev-cht-eks" + +# For production, comment out above and uncomment below: +# AVAILABILITY_ZONE="eu-west-2a" +# CLUSTER_NAME="prod-cht-eks" + +# Create a new volume from the snapshot +NEW_VOLUME_ID=$(aws ec2 create-volume \ + --region eu-west-2 \ + --availability-zone $AVAILABILITY_ZONE \ + --snapshot-id $SNAPSHOT_ID \ + --volume-type gp2 \ + --query 'VolumeId' \ + --output text) + +echo "Created new volume: $NEW_VOLUME_ID" + +# Tag the new volume for Kubernetes use +aws ec2 create-tags \ + --resources $NEW_VOLUME_ID \ + --tags Key=kubernetes.io/cluster/$CLUSTER_NAME,Value=owned Key=KubernetesCluster,Value=$CLUSTER_NAME + +# Verify your tags took effect +aws ec2 describe-volumes --region eu-west-2 --volume-id $NEW_VOLUME_ID | jq '.Volumes[0].Tags' +``` + +## Deploy CHT 4.x with Existing Data + +Create a `values.yaml` file using the volume ID from the previous step: + +For single node deployment, create a YAML file with this contents, being sure to update: + +* `` (_two occurrences_) +* `` - 4.x version you're upgrading too +* `` - retrieved from `get-env` call above +* `` - retrieved from `get-env` call above +* `` - needs to be the same as used in 3.x - likely `medic` +* `` - retrieved from `get-env` call above +* `` - Size of original 3.x EBS volume, eg `100Mi` for 100 Megabytes or `100Gi` for 100 Gigabytes (_two occurrences_) +* `` - For production use `prod-couchdb-only`, for dev use `dev-couchdb-only` +* `` - For production use `prod-cht-alb`, for dev use `dev-cht-alb` +* `` - For production use `prod`, for dev use `dev` +* `` - For production use `SRE`, for dev use `QA` +* `` - For production use `your-url.app.medicmobile.org`, for dev use `your-url.dev.medicmobile.org` +* `load_balancer` - For dev, use: `dualstack.k8s-devchtalb-3eb0781cbb-694321496.eu-west-2.elb.amazonaws.com` For prod, use: `k8s-prodchtalb-dcc00345ac-1792311525.eu-west-2.elb.amazonaws.com` +* `certificate` - Inquire what the latest certificates are. For 2024 dev, use: `arn:aws:iam::720541322708:server-certificate/2024-wildcard-dev-medicmobile-org-chain`. For 2024 prod, use: `arn:aws:iam::720541322708:server-certificate/2024-wildcard-app-medicmobile-org-chain`. +* `` - `NEW_VOLUME_ID` from previous step, is volume containing 3.x data + +```yaml +project_name: "" +namespace: "" +chtversion: + +upstream_servers: + docker_registry: "public.ecr.aws/medic" + builds_url: "https://staging.dev.medicmobile.org/_couch/builds_4" +upgrade_service: + tag: 0.32 + +couchdb: + password: "" + secret: "" + user: "" + uuid: "" + clusteredCouch_enabled: false + couchdb_node_storage_size: "" + +toleration: + key: "" + operator: "Equal" + value: "true" + effect: "NoSchedule" + +ingress: + annotations: + groupname: "" + tags: "Environment=,Team=" + certificate: "" + host: "" + hosted_zone_id: "Z3304WUAJTCM7P" + load_balancer: "" + +environment: "remote" +cluster_type: "eks" +cert_source: "eks-medic" + +couchdb_data: + preExistingDataAvailable: "true" + dataPathOnDiskForCouchDB: "storage/medic-core/couchdb/data" + partition: "0" + +ebs: + preExistingEBSVolumeID-1: "" + preExistingEBSVolumeSize: "" + +``` + +A Note about the following section: + +```yaml +couchdb_data: + preExistingDataAvailable: "true" + dataPathOnDiskForCouchDB: "storage/medic-core/couchdb/data" # Use subPath from 3.x instance + partition: "0" + +``` +The value for partition is usually `"0"` - not partitioned. If you would like to change this, you can go to your 3.x pod and run `df -h` and observe if the existing data is on a specific partition. You then update this value to be the partition number. + +For a clustered deployment, create a YAML file with this contents, being sure to update: + +* `` (two occurrences) +* `` - 4.x version you're upgrading too +* `` - retrieved from `get-env` call above +* `` - retrieved from `get-env` call above +* `` - needs to be the same as used in 3.x - likely `medic` +* `` - retrieved from `get-env` call above +* `` - Size of original 3.x EBS volume, eg `100Mi` for 100 Megabytes or `100Gi` for 100 Gigabytes (_two occurrences_) +* `` - For production use `prod-couchdb-only`, for dev use `dev-couchdb-only` +* `` - For production use `prod-cht-alb`, for dev use `dev-cht-alb` +* `` - For production use `prod`, for dev use `dev` +* `` - For production use `SRE`, for dev use `QA` +* `` - For production use `your-url.app.medicmobile.org`, for dev use `your-url.dev.medicmobile.org` +* `` - For dev, use: `dualstack.k8s-devchtalb-3eb0781cbb-694321496.eu-west-2.elb.amazonaws.com` For prod, use: `k8s-prodchtalb-dcc00345ac-1792311525.eu-west-2.elb.amazonaws.com` +* `` - Inquire what the latest certificates are. For 2024 dev, use: `arn:aws:iam::720541322708:server-certificate/2024-wildcard-dev-medicmobile-org-chain`. For 2024 prod, use: `arn:aws:iam::720541322708:server-certificate/2024-wildcard-app-medicmobile-org-chain`. +* `` - `NEW_VOLUME_ID` from previous step, is volume containing 3.x data + +```yaml +project_name: "" +namespace: "" +chtversion: + +upstream_servers: + docker_registry: "public.ecr.aws/medic" + builds_url: "https://staging.dev.medicmobile.org/_couch/builds_4" +upgrade_service: + tag: 0.32 + +couchdb: + password: "" + secret: "" + user: "" + uuid: "" + clusteredCouch_enabled: true + couchdb_node_storage_size: "" + +clusteredCouch: # Only relevant if clusteredCouch_enabled is true + noOfCouchDBNodes: 3 + +toleration: + key: "" + operator: "Equal" + value: "true" + effect: "NoSchedule" + +ingress: + annotations: + groupname: "" + tags: "Environment=,Team=" + certificate: "" + host: "" + hosted_zone_id: "Z3304WUAJTCM7P" + load_balancer: "" + +environment: "remote" +cluster_type: "eks" +cert_source: "eks-medic" + +# Only need to specify nodes if deploying on k3s and want to use specific nodes for CouchDB pods +#nodes: +# node-1: # Only for k3s deployments +# node-2: # Only for k3s deployments +# node-3: # Only for k3s deployments + +couchdb_data: + preExistingDataAvailable: "true" + dataPathOnDiskForCouchDB: "storage/medic-core/couchdb/data" # Use subPath from 3.x instance + partition: "0" + +ebs: + preExistingEBSVolumeID-1: "" + preExistingEBSVolumeID-2: "" # Leave empty for secondary nodes + preExistingEBSVolumeID-3: "" # Leave empty for tertiary nodes + preExistingEBSVolumeSize: "" +``` + +A Note about the following section: + +```yaml +couchdb_data: + preExistingDataAvailable: "true" + dataPathOnDiskForCouchDB: "storage/medic-core/couchdb/data" # Use subPath from 3.x instance + partition: "0" + +``` +The value for partition is usually `"0"` - not partitioned. If you would like to change this, you can go to your 3.x pod and run `df -h` and observe if the existing data is on a specific partition. You then update this value to be the partition number. + +Deploy using cht-deploy script from cht-core repository: +```shell +cd cht-core/scripts/deploy +./cht-deploy -f PATH_TO/values.yaml +``` + +## Verify Deployment and Run Migration Commands + +First verify CouchDB is running properly: +```shell +# Check pod status +kubectl get pods -n $NAMESPACE + +# For single node check CouchDB is up +kubectl exec -it -n $NAMESPACE $(kubectl get pod -n $NAMESPACE -l cht.service=couchdb -o name) -- \ + curl -s http://localhost:5984/_up + +# For clustered setup (check all nodes) +kubectl exec -it -n $NAMESPACE $(kubectl get pod -n $NAMESPACE -l cht.service=couchdb-1 -o name) -- \ + curl -s http://localhost:5984/_up +``` + +Access the new CouchDB pod based on your deployment type. + +For single node: +```shell +kubectl exec -it -n $NAMESPACE $(kubectl get pod -n $NAMESPACE -l cht.service=couchdb -o name) -- bash +``` + +For clustered setup (always use couchdb-1): +```shell +kubectl exec -it -n $NAMESPACE $(kubectl get pod -n $NAMESPACE -l cht.service=couchdb-1 -o name) -- bash +``` + +Once inside the pod, set up the migration tool again: +```shell +curl -fsSL https://deb.nodesource.com/setup_16.x | bash - +apt install -y nodejs npm git +git clone https://github.com/medic/couchdb-migration.git +cd couchdb-migration +npm ci --omit=dev + +# Create a global symlink to enable running commands directly +# Note: This may require sudo if npm's global directories aren't writable +npm link + +# Set up CouchDB connection +export ADMIN_USER= +export ADMIN_PASSWORD= +export COUCH_URL="http://${ADMIN_USER}:${ADMIN_PASSWORD}@localhost:5984" + +# Verify CouchDB is up and responding +check-couchdb-up +``` + +For single node deployment: +```shell +move-node +verify +``` + +For clustered deployment: + +{{% alert title="Note" %}} +For clustered setups, shards must be moved both in software (using the migration commands) and physically (the actual data must be moved between EBS volumes). Follow the instructions from shard-move-instructions carefully. +{{% /alert %}} + + +```shell +# Generate distribution matrix +shard_matrix=$(generate-shard-distribution-matrix) + +# Get movement instructions +shard-move-instructions $shard_matrix + +# After moving shards according to instructions +move-shards $shard_matrix + +# Remove old node from cluster +remove-node couchdb@127.0.0.1 + +# Verify the migration +verify +``` diff --git a/content/en/core/releases/3.14.0.md b/content/en/core/releases/3.14.0.md index 1fb93ba36..7eb5d79b5 100644 --- a/content/en/core/releases/3.14.0.md +++ b/content/en/core/releases/3.14.0.md @@ -54,7 +54,7 @@ Old Dates | New Dates :-------------------------:|:-------------------------: ![](../images/3.14.0-7294-old.png) | ![](../images/3.14.0-7294-new.png) -Additionally, a new [`to-bikram-sambat` xPath function]({{< ref "building/reference/forms/app#to-bikram-sambat" >}}) has been added that converts a `date` to a `string` containing the value of the date in the Bikram Sambat format. +Additionally, a new [`to-bikram-sambat` xPath function]({{< ref "building/forms/app#to-bikram-sambat" >}}) has been added that converts a `date` to a `string` containing the value of the date in the Bikram Sambat format. [#7294](https://github.com/medic/cht-core/issues/7294): Use Bikram Sambat dates throughout the webapp when Nepali locale selected diff --git a/content/en/core/releases/4.15.0.md b/content/en/core/releases/4.15.0.md new file mode 100644 index 000000000..07c3febc3 --- /dev/null +++ b/content/en/core/releases/4.15.0.md @@ -0,0 +1,89 @@ + +--- +title: "4.15.0 release notes" +linkTitle: "4.15.0" +weight: +description: > +relevantLinks: > +toc_hide: true +--- + +## Known issues + +Check the repository for the [latest known issues](https://github.com/medic/cht-core/issues?q=is%3Aissue+label%3A%22Affects%3A+4.15.0%22). + +## Upgrade notes + +### Breaking changes + +None. + +### UI/UX changes + +None. + +## Highlights + +### Training Page + +After deploying the training cards feature to introduce a new workflow to over 10,000 CHPs, we received feedback that users need a way to easily revisit their training content. +Care Teams is working on a new Training Materials page which will be found in the auxiliary menu of the CHT. + +{{< figure src="../images/4.15.0-9598.png" >}} + +It will display a list of training content that have been assigned to each user, with an indication to show which have been completed, that users can access repeatedly if necessary. + +## And more... + +### Features + +- [#8806](https://github.com/medic/cht-core/issues/8806): Multiple validation functions in rule doesn't work +- [#9489](https://github.com/medic/cht-core/issues/9489): Add telemetry for offline freetext searching +- [#9598](https://github.com/medic/cht-core/issues/9598): Add training material page + +### Improvements + +- [#8216](https://github.com/medic/cht-core/issues/8216): Propagate request uuid from API to audit logging layer +- [#8402](https://github.com/medic/cht-core/issues/8402): Add support to check if either of multiple forms is submitted for a patient. +- [#9551](https://github.com/medic/cht-core/issues/9551): Revisit rules-engine telemetry entries after recalculation triggers rework + +### Security fixes + +None. + +### Performance improvements + +None. + +### Bug fixes + +- [#7375](https://github.com/medic/cht-core/issues/7375): Race condition in service worker update +- [#8573](https://github.com/medic/cht-core/issues/8573): Install button doesn't appear after staging an upgrade sometimes +- [#9286](https://github.com/medic/cht-core/issues/9286): Starting an upgrade that involves view indexing can cause CouchDB to crash +- [#9612](https://github.com/medic/cht-core/issues/9612): Tasks can be completed after resolution +- [#9617](https://github.com/medic/cht-core/issues/9617): Starting an upgrade that involves view indexing can become stuck after indexing is finished +- [#9618](https://github.com/medic/cht-core/issues/9618): Broken form.xml attachment can prevent api server from starting + +### Technical improvements + +- [#8781](https://github.com/medic/cht-core/issues/8781): Upgrade to docker compose v2 +- [#9543](https://github.com/medic/cht-core/issues/9543): Flaky e2e test: `incorrect-locale` has been failing constantly in "after each" hook +- [#9594](https://github.com/medic/cht-core/issues/9594): Add remaining e2e test to tasks for offline user +- [#9614](https://github.com/medic/cht-core/issues/9614): Bump helm charts default version in cht-deploy +- [#9622](https://github.com/medic/cht-core/issues/9622): Flaky e2e test search matches telemetry +- [#9624](https://github.com/medic/cht-core/issues/9624): `default-docs` build cache not cleared when running `build-dev` +- [#9636](https://github.com/medic/cht-core/issues/9636): Update to Node 22 + +## Contributors + +Thanks to all who committed changes for this release! + +- [Diana Barsan](https://github.com/dianabarsan) +- [Gareth Bowen](https://github.com/garethbowen) +- [Mokhtar](https://github.com/m5r) +- [mrjones](https://github.com/mrjones-plip) +- [Rafa](https://github.com/ralfudx) +- [Joshua Kuestersteffen](https://github.com/jkuester) +- [Tatiana Lépiz Soto](https://github.com/tatilepizs) +- [Jennifer Q](https://github.com/latin-panda) + diff --git a/content/en/core/releases/4.2.0.md b/content/en/core/releases/4.2.0.md index f085ab3e4..b6914c592 100644 --- a/content/en/core/releases/4.2.0.md +++ b/content/en/core/releases/4.2.0.md @@ -71,7 +71,7 @@ You can read more about it in [the transitions configuration docs]({{< relref "b ### Extension libraries -The extension libraries are blocks of code that are cached with the CHT web application giving app developers a powerful tool to extend the CHT. An example of a use for this feature is to provide a function to calculate a risk score based on a machine learning model. The function can then be called passing in values from [app forms]({{< relref "building/reference/forms/app" >}}) and return the result to be stored with the report. +The extension libraries are blocks of code that are cached with the CHT web application giving app developers a powerful tool to extend the CHT. An example of a use for this feature is to provide a function to calculate a risk score based on a machine learning model. The function can then be called passing in values from [app forms]({{< relref "building/forms/app" >}}) and return the result to be stored with the report. Read more about this feature in the [extension libraries docs]({{< relref "extension-libs" >}}) diff --git a/content/en/core/releases/4.6.0.md b/content/en/core/releases/4.6.0.md index 4fb335466..6746af50f 100644 --- a/content/en/core/releases/4.6.0.md +++ b/content/en/core/releases/4.6.0.md @@ -30,7 +30,7 @@ None. ### Allow contact searches in forms to be filtered by descendants of the current contact -A [contact selector]({{< relref "building/guides/forms/form-inputs#contact-selector" >}}) can be used in forms to allow users to select a contact by searching. In addition to limiting the searchable contacts by their type, now you can configure the search field to only show contacts which are descendants of the current contact. This is useful when you only want to allow a user to select specific contacts (such as members of the current household). Learn how to configure this functionality in [the documentation]({{< relref "building/guides/forms/form-inputs#loading-descendants-of-the-current-contact" >}}). +A [contact selector]({{< relref "building/forms/configuring/form-inputs#contact-selector" >}}) can be used in forms to allow users to select a contact by searching. In addition to limiting the searchable contacts by their type, now you can configure the search field to only show contacts which are descendants of the current contact. This is useful when you only want to allow a user to select specific contacts (such as members of the current household). Learn how to configure this functionality in [the documentation]({{< relref "building/forms/configuring/form-inputs#loading-descendants-of-the-current-contact" >}}). - [#8074](https://github.com/medic/cht-core/issues/8074): Support filtering contact search in forms by descendants of the current contact diff --git a/content/en/core/releases/_index.md b/content/en/core/releases/_index.md index cc35153fc..44bf46586 100644 --- a/content/en/core/releases/_index.md +++ b/content/en/core/releases/_index.md @@ -22,12 +22,13 @@ It is recommended that all projects update regularly multiple times a year to ge | Version | Status | Release date | End of life | |---------|-----------|--------------|-------------| -| 4.14.x | Supported | 31-Oct-2024 | TBA | -| 4.13.x | Supported | 22-Oct-2024 | 01-Mar-2025 | +| 4.15.x | Supported | 20-Nov-2024 | TBA | +| 4.14.x | Supported | 31-Oct-2024 | 20-Feb-2025 | +| 4.13.x | Supported | 22-Oct-2024 | 31-Jan-2025 | | 4.12.x | Supported | 02-Oct-2024 | 22-Jan-2025 | | 4.11.x | Supported | 26-Sep-2024 | 02-Jan-2025 | | 4.10.x | Supported | 15-Aug-2024 | 26-Dec-2024 | -| 4.9.x | Supported | 25-Jun-2024 | 15-Nov-2024 | +| 4.9.x | EOL | 25-Jun-2024 | 15-Nov-2024 | | 4.8.x | EOL | 22-May-2024 | 25-Sep-2024 | | 4.7.x | EOL | 07-May-2024 | 22-Aug-2024 | | 4.6.x | EOL | 20-Mar-2024 | 10-Aug-2024 | @@ -98,6 +99,7 @@ Devices with more navigation systems are more likely to get a more accurate loca ## Release Notes ### 4.x +- [4.15.0]({{% ref "core/releases/4.15.0.md" %}}) - [4.14.0]({{% ref "core/releases/4.14.0.md" %}}) - [4.13.0]({{% ref "core/releases/4.13.0.md" %}}) - [4.12.0]({{% ref "core/releases/4.12.0.md" %}}) diff --git a/content/en/core/releases/images/4.15.0-9598.png b/content/en/core/releases/images/4.15.0-9598.png new file mode 100644 index 000000000..e6f7aefda Binary files /dev/null and b/content/en/core/releases/images/4.15.0-9598.png differ diff --git a/content/en/design/best-practices/_index.md b/content/en/design/best-practices/_index.md index 5e5c9df21..fbb48eb21 100644 --- a/content/en/design/best-practices/_index.md +++ b/content/en/design/best-practices/_index.md @@ -224,7 +224,7 @@ After all of the required questions in a form are answered, a summary page is di *Note: The form is not submitted until the user scrolls to the end of the page and clicks “Submit”.* -All care guides are defined using [ODK XForms](https://opendatakit.github.io/xforms-spec/), an XML definition of the structure and format for a set of questions. Since writing raw XML can be tedious, we suggest creating the forms using the [XLSForm standard](http://xlsform.org/), and using the [cht-conf](https://github.com/medic/cht-conf) command line configurer tool to convert them to XForm format. Because the XLSForms are converted directly to XForms, they essentially are the form, and so it’s important that the XLS be set up properly and consistently. Read more about configuring forms [here]({{< ref "building/reference/forms/app">}}). +All care guides are defined using [ODK XForms](https://opendatakit.github.io/xforms-spec/), an XML definition of the structure and format for a set of questions. Since writing raw XML can be tedious, we suggest creating the forms using the [XLSForm standard](http://xlsform.org/), and using the [cht-conf](https://github.com/medic/cht-conf) command line configurer tool to convert them to XForm format. Because the XLSForms are converted directly to XForms, they essentially are the form, and so it’s important that the XLS be set up properly and consistently. Read more about configuring forms [here]({{< ref "building/forms/app">}}). #### Page Sections diff --git a/content/en/design/mockups/mockup-desktop.png b/content/en/design/mockups/mockup-desktop.png index bf6891a6b..decc6ed4a 100644 Binary files a/content/en/design/mockups/mockup-desktop.png and b/content/en/design/mockups/mockup-desktop.png differ diff --git a/content/en/glossary.md b/content/en/glossary.md index 3017782c8..5cde58cac 100644 --- a/content/en/glossary.md +++ b/content/en/glossary.md @@ -147,6 +147,21 @@ The ability of health information systems to work together, even if they weren't ###### Joint United Nations Programme on HIV/AIDS (UNAIDS) +## K + +###### k3d + +k3d is a lightweight wrapper to run k3s in docker. More information on [their site](https://k3d.io/). + + +###### k3s + +Lightweight Kubernetes in a single binary. More information on [their site](https://github.com/k3s-io/k3s). + +###### Kubernetes + +Kubernetes, also known as K8s, is an open source system for automating deployment, scaling, and management of containerized applications. More information on [their site](https://kubernetes.io/). + ## L ###### Last Menstruation Period (LMP) diff --git a/content/en/hosting/analytics/building-dbt-models.md b/content/en/hosting/analytics/building-dbt-models.md index ba5400cb7..6066ee5f3 100644 --- a/content/en/hosting/analytics/building-dbt-models.md +++ b/content/en/hosting/analytics/building-dbt-models.md @@ -366,6 +366,26 @@ WHERE To be performant, the table from this model is reading form needs to have the `saved_timestamp` column indexed. +## Breaking changes +Due to the way models can be imported, extended, and built upon, it's necessary to take precautions against breaking backwards compatibility when making changes upstream. +Model collections should be versioned, following semver rules, and breaking changes should only be published in major releases. + +Examples of changes that are considered breaking: +- deleting/renaming a model +- deleting/renaming a field +- changing a field data type +- changing a field data definition significantly +- removing/changing an index +- removing/changing a macro + +Examples of changes that are not considered breaking: +- adding a model +- adding a field +- updating an existent field data definition to fix a bug +- adding a macro +- adding an index +- adding tests + ## Database disk space requirements The disk space required for the database depends on a few things including the size the of CouchDB databases being replicated, and the [models]({{< relref "hosting/analytics/building-dbt-models" >}}) defined. The database will grow over time as more data is added to CouchDB. The database should be monitored to ensure that it has enough space to accommodate the data. To get an idea of the size requirements of the database, you can replicate 10% of the data from CouchDB to Postgres and then run the following command to see disk usage: ```shell