From 94a213fe513a817e7ae604c73d9c2e3ee1ca796e Mon Sep 17 00:00:00 2001 From: mrjones-plip Date: Fri, 25 Jul 2025 13:58:17 -0700 Subject: [PATCH 01/16] chore(na): how to become maintainer --- content/en/community/contributing/_index.md | 1 + .../community/contributing/core-maintainer.md | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 content/en/community/contributing/core-maintainer.md diff --git a/content/en/community/contributing/_index.md b/content/en/community/contributing/_index.md index fde4f3a767..2a2316774a 100644 --- a/content/en/community/contributing/_index.md +++ b/content/en/community/contributing/_index.md @@ -12,6 +12,7 @@ aliases: {{< card link="first-time-contributors" title="First Time Contributors Guide" icon="heart" subtitle=" Starting guide for first time contributors" >}} {{< card link="code-of-conduct" title="Code of Conduct" subtitle="The code of conduct for the CHT community" icon="shield-exclamation" >}} {{< card link="code/" title="Contribute Code" subtitle="How to contribute to code to the CHT" icon="code" >}} + {{< card link="core-maintainer/" title="Core contributor" subtitle="What it takes to go from community member to be able to directly commit to CHT Core" icon="user-add" >}} {{< card link="docs/" title="Contribute Documentation" subtitle="How to contribute to documentation to the CHT" icon="document-text" >}} {{< card link="creating-good-first-issues" title="Create Good First Issues" icon="lightning-bolt" subtitle=" Set new community members up for success" >}} {{< card link="technical-resources" title="Technical Resources" subtitle="Learning resources to get started as a contributor to the CHT" icon="academic-cap" >}} diff --git a/content/en/community/contributing/core-maintainer.md b/content/en/community/contributing/core-maintainer.md new file mode 100644 index 0000000000..06860b01db --- /dev/null +++ b/content/en/community/contributing/core-maintainer.md @@ -0,0 +1,45 @@ +--- +title: "Core Maintainer" +linkTitle: "Core Maintainer" +weight: 10 +description: > + Who can commit directly to CHT reposistories in GitHub +--- + +## Requirements +To become a maintainer, a community member needs to do the following: + +* Participate in a squad where you author, commit and revise code that gets merged to at least one CHT repo
+ **OR**
+ 3 features merged to CHT Core outside of a squad
+ **OR**
+ 5 bug fixes merged to CHT Core outside of a squad +* Have a forum account and have achieved the "Member" badge. +* Attend 3 out of 12 round up calls a year +* Have 2 existing core maintainers sign off on your nomination + +## How to add a core maintainer + +* Open an issue on the repository - with TBD template for adding new maintainer +* Ensure all steps are completed per requirements above +* Have 2 existing core maintainers add their approval to the ticket +* Ticket is assigned to GH owner who can grant permissions +* TBD specific permissions are added in GitHub by a existing GitHub repo admin + +## When to remove a core maintainer + +* 3 existing core maintainers agree you should no longer be a maintainer + +This may because some or all of the following: +* You no longer attend round up calls +* You're no longer active on the forums +* You have violated the [Code of Conduct](/community/contributing/code-of-conduct) + + +## How to remove a core maintainer + +* Open an issue on the repository - with TBD template for adding new maintainer +* Ensure all steps are completed per requirements above +* Ticket is assigned to GH owner who can grant permissions +* Have 3 existing core maintainers add their approval to the ticket +* TBD permissions are removed in GitHub by a existing GitHub repo admin From dd82393facb07ee04df97976bcc35318c9e2c817 Mon Sep 17 00:00:00 2001 From: mrjones-plip Date: Fri, 25 Jul 2025 14:10:36 -0700 Subject: [PATCH 02/16] add link for member badge --- content/en/community/contributing/core-maintainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/community/contributing/core-maintainer.md b/content/en/community/contributing/core-maintainer.md index 06860b01db..dc31104665 100644 --- a/content/en/community/contributing/core-maintainer.md +++ b/content/en/community/contributing/core-maintainer.md @@ -14,7 +14,7 @@ To become a maintainer, a community member needs to do the following: 3 features merged to CHT Core outside of a squad
**OR**
5 bug fixes merged to CHT Core outside of a squad -* Have a forum account and have achieved the "Member" badge. +* Have a forum account and have achieved the "[Member](https://forum.communityhealthtoolkit.org/badges/2/member)" badge. * Attend 3 out of 12 round up calls a year * Have 2 existing core maintainers sign off on your nomination From 3e04b8326ce61fa874cd47d5b1ba62d2b8019369 Mon Sep 17 00:00:00 2001 From: mrjones-plip Date: Fri, 25 Jul 2025 15:04:55 -0700 Subject: [PATCH 03/16] add more intro, mention existing teammates and multi-repo access --- .../en/community/contributing/core-maintainer.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/content/en/community/contributing/core-maintainer.md b/content/en/community/contributing/core-maintainer.md index dc31104665..786d99c999 100644 --- a/content/en/community/contributing/core-maintainer.md +++ b/content/en/community/contributing/core-maintainer.md @@ -3,11 +3,18 @@ title: "Core Maintainer" linkTitle: "Core Maintainer" weight: 10 description: > - Who can commit directly to CHT reposistories in GitHub + Who can commit directly to CHT repositories in GitHub --- +Historically only [Medic](https://medic.org/) teammates were given GitHub permissions to merge code into CHT repositories. This is no longer the case! Now, everyone is treated as an equal: If you meet these requirements, you can commit code! Medic teammates who already have maintainer status are not having any exceptions given to them though - they've just already meet the requirements. + +This is not just for the [CHT Core](https://github.com/medic/cht-core/) repository though! We welcome maintainers for who just want to [update the documentation](https://docs.communityhealthtoolkit.org/) as well. There's actually dozens of repositories that you can contribute to - [check them out](https://github.com/orgs/medic/repositories)! + +Along with the process on how to become a maintainer, we're also including the process of removing a maintainer. + +If you have any questions about how this works in practice, please post a [question to the forum](https://forum.communityhealthtoolkit.org/c/community/10)! + ## Requirements -To become a maintainer, a community member needs to do the following: * Participate in a squad where you author, commit and revise code that gets merged to at least one CHT repo
**OR**
@@ -26,6 +33,10 @@ To become a maintainer, a community member needs to do the following: * Ticket is assigned to GH owner who can grant permissions * TBD specific permissions are added in GitHub by a existing GitHub repo admin +## Maintainer status on multiple repositories + +If a community member would like access to more than one repository, they can just get 2 of the same (or different) existing maintainers of that repository to sign off on their nomination. You can be a committer on as many repositories as you're interested in. + ## When to remove a core maintainer * 3 existing core maintainers agree you should no longer be a maintainer @@ -33,6 +44,7 @@ To become a maintainer, a community member needs to do the following: This may because some or all of the following: * You no longer attend round up calls * You're no longer active on the forums +* It's been over to 18 months since your last CHT related GitHub activity * You have violated the [Code of Conduct](/community/contributing/code-of-conduct) From a843a572985ea493e141f75444c73861bba0976c Mon Sep 17 00:00:00 2001 From: mrjones <8253488+mrjones-plip@users.noreply.github.com> Date: Sat, 26 Jul 2025 09:32:21 -0700 Subject: [PATCH 04/16] Update content/en/community/contributing/core-maintainer.md Co-authored-by: Binod Adhikary --- content/en/community/contributing/core-maintainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/community/contributing/core-maintainer.md b/content/en/community/contributing/core-maintainer.md index 786d99c999..27b51a8678 100644 --- a/content/en/community/contributing/core-maintainer.md +++ b/content/en/community/contributing/core-maintainer.md @@ -44,7 +44,7 @@ If a community member would like access to more than one repository, they can ju This may because some or all of the following: * You no longer attend round up calls * You're no longer active on the forums -* It's been over to 18 months since your last CHT related GitHub activity +* It has been over 18 months since your last CHT related GitHub activity * You have violated the [Code of Conduct](/community/contributing/code-of-conduct) From 1634cdd5c045a1b851fe0b1f2f35546a6f54832b Mon Sep 17 00:00:00 2001 From: mrjones-plip Date: Fri, 25 Jul 2025 17:12:29 -0700 Subject: [PATCH 05/16] dial down the excitiment, fix/tidy up wording --- content/en/community/contributing/core-maintainer.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/content/en/community/contributing/core-maintainer.md b/content/en/community/contributing/core-maintainer.md index 27b51a8678..5303716fe8 100644 --- a/content/en/community/contributing/core-maintainer.md +++ b/content/en/community/contributing/core-maintainer.md @@ -6,13 +6,11 @@ description: > Who can commit directly to CHT repositories in GitHub --- -Historically only [Medic](https://medic.org/) teammates were given GitHub permissions to merge code into CHT repositories. This is no longer the case! Now, everyone is treated as an equal: If you meet these requirements, you can commit code! Medic teammates who already have maintainer status are not having any exceptions given to them though - they've just already meet the requirements. +Historically only [Medic](https://medic.org/) teammates were given GitHub permissions to merge code into CHT repositories. This is no longer the case! Now, everyone is treated as an equal: If you meet these requirements, you can commit code. Medic teammates who already have maintainer status do not get exemptions - they've just already meet the requirements. -This is not just for the [CHT Core](https://github.com/medic/cht-core/) repository though! We welcome maintainers for who just want to [update the documentation](https://docs.communityhealthtoolkit.org/) as well. There's actually dozens of repositories that you can contribute to - [check them out](https://github.com/orgs/medic/repositories)! +This is not just for the [CHT Core](https://github.com/medic/cht-core/) repository though! We welcome maintainers want to [update the documentation](https://docs.communityhealthtoolkit.org/) as well. There's actually dozens of repositories that you can contribute to - [check them out](https://github.com/orgs/medic/repositories)! -Along with the process on how to become a maintainer, we're also including the process of removing a maintainer. - -If you have any questions about how this works in practice, please post a [question to the forum](https://forum.communityhealthtoolkit.org/c/community/10)! +If you have any questions about how this works in practice, please post a [question to the forum](https://forum.communityhealthtoolkit.org/c/community/10). ## Requirements From 0f7c4c23dc681ea41ca7e1d76079630d92c8fc36 Mon Sep 17 00:00:00 2001 From: mrjones-plip Date: Mon, 28 Jul 2025 15:21:39 -0700 Subject: [PATCH 06/16] quantify what a feature or bug fix is per feedback --- content/en/community/contributing/core-maintainer.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/content/en/community/contributing/core-maintainer.md b/content/en/community/contributing/core-maintainer.md index 5303716fe8..addbdd1e9e 100644 --- a/content/en/community/contributing/core-maintainer.md +++ b/content/en/community/contributing/core-maintainer.md @@ -14,15 +14,17 @@ If you have any questions about how this works in practice, please post a [quest ## Requirements -* Participate in a squad where you author, commit and revise code that gets merged to at least one CHT repo
- **OR**
- 3 features merged to CHT Core outside of a squad
- **OR**
- 5 bug fixes merged to CHT Core outside of a squad +* Participate in a squad where you author, commit and revise code that gets merged to at least one CHT repo *
+ **OR**
+ 3 features merged to CHT Core outside of a squad *
+ **OR**
+ 5 bug fixes merged to CHT Core outside of a squad * * Have a forum account and have achieved the "[Member](https://forum.communityhealthtoolkit.org/badges/2/member)" badge. * Attend 3 out of 12 round up calls a year * Have 2 existing core maintainers sign off on your nomination +_\* Features and bug fixes are measured by a PR that was succfully merged to `main`_ + ## How to add a core maintainer * Open an issue on the repository - with TBD template for adding new maintainer From a6943db65a27b0879916816d3c924cce38fcd61f Mon Sep 17 00:00:00 2001 From: mrjones-plip Date: Mon, 28 Jul 2025 15:22:44 -0700 Subject: [PATCH 07/16] fix typo --- content/en/community/contributing/core-maintainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/community/contributing/core-maintainer.md b/content/en/community/contributing/core-maintainer.md index addbdd1e9e..e673785b63 100644 --- a/content/en/community/contributing/core-maintainer.md +++ b/content/en/community/contributing/core-maintainer.md @@ -23,7 +23,7 @@ If you have any questions about how this works in practice, please post a [quest * Attend 3 out of 12 round up calls a year * Have 2 existing core maintainers sign off on your nomination -_\* Features and bug fixes are measured by a PR that was succfully merged to `main`_ +_\* Features and bug fixes are measured by a PR that was successfully merged to `main`_ ## How to add a core maintainer From b1b281c26b0d85a82a4bcd990ab4defc7c184c54 Mon Sep 17 00:00:00 2001 From: mrjones <8253488+mrjones-plip@users.noreply.github.com> Date: Mon, 28 Jul 2025 15:24:30 -0700 Subject: [PATCH 08/16] Update content/en/community/contributing/core-maintainer.md Co-authored-by: Apoorva Pendse --- content/en/community/contributing/core-maintainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/community/contributing/core-maintainer.md b/content/en/community/contributing/core-maintainer.md index e673785b63..4e8a2fde7f 100644 --- a/content/en/community/contributing/core-maintainer.md +++ b/content/en/community/contributing/core-maintainer.md @@ -50,7 +50,7 @@ This may because some or all of the following: ## How to remove a core maintainer -* Open an issue on the repository - with TBD template for adding new maintainer +* Open an issue on the repository - with TBD template for removing an existing maintainer * Ensure all steps are completed per requirements above * Ticket is assigned to GH owner who can grant permissions * Have 3 existing core maintainers add their approval to the ticket From 3f22916b32eb742e7aa7c8b836f583f12deb7555 Mon Sep 17 00:00:00 2001 From: Joshua Kuestersteffen Date: Tue, 29 Jul 2025 16:44:20 -0500 Subject: [PATCH 09/16] feat: add release notes for 4.20.1 and 4.21.1 (#1944) --- content/en/releases/4_20_1.md | 42 +++++++++++++++++++++++++++++++++++ content/en/releases/4_21_1.md | 42 +++++++++++++++++++++++++++++++++++ content/en/releases/_index.md | 2 ++ 3 files changed, 86 insertions(+) create mode 100644 content/en/releases/4_20_1.md create mode 100644 content/en/releases/4_21_1.md diff --git a/content/en/releases/4_20_1.md b/content/en/releases/4_20_1.md new file mode 100644 index 0000000000..3574a2203d --- /dev/null +++ b/content/en/releases/4_20_1.md @@ -0,0 +1,42 @@ + +--- +title: "4.20.1 release notes" +linkTitle: "4.20.1" +sidebar: + exclude: true +description: + Released 2025-07-30 +aliases: + - /core/releases/4.20.1 + - /releases/4.20.1 +--- + +## 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.20.1%22). + +## Upgrade notes + +### Breaking changes + +None. + +### UI/UX changes + +None. + +### Bug fixes + +- [#10062](https://github.com/medic/cht-core/issues/10062): Rendering issue in edit user modal for SSO user + +### Technical improvements + +None. + +## Contributors + +Thanks to all who committed changes for this release! + +- [Joshua Kuestersteffen](https://github.com/jkuester) +- [Bernard K](https://github.com/benkags) + diff --git a/content/en/releases/4_21_1.md b/content/en/releases/4_21_1.md new file mode 100644 index 0000000000..f65096e05e --- /dev/null +++ b/content/en/releases/4_21_1.md @@ -0,0 +1,42 @@ + +--- +title: "4.21.1 release notes" +linkTitle: "4.21.1" +sidebar: + exclude: true +description: + Released "2025-07-30" +aliases: + - /core/releases/4.21.1 + - /releases/4.21.1 +--- + +## 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.21.1%22). + +## Upgrade notes + +### Breaking changes + +None. + +### UI/UX changes + +None. + +### Bug fixes + +- [#10062](https://github.com/medic/cht-core/issues/10062): Rendering issue in edit user modal for SSO user + +### Technical improvements + +None. + +## Contributors + +Thanks to all who committed changes for this release! + +- [Joshua Kuestersteffen](https://github.com/jkuester) +- [Bernard K](https://github.com/benkags) + diff --git a/content/en/releases/_index.md b/content/en/releases/_index.md index 5eda35fc6e..594d23521c 100644 --- a/content/en/releases/_index.md +++ b/content/en/releases/_index.md @@ -87,7 +87,9 @@ Devices with more navigation systems are more likely to get a more accurate loca ## Release Notes ### 4.x +- [4.21.1]({{% relref "releases/4_21_1.md" %}}) - 2025-07-30 - [4.21.0]({{% relref "releases/4_21_0.md" %}}) - 2025-06-25 +- [4.20.1]({{% relref "releases/4_20_1.md" %}}) - 2025-07-30 - [4.20.0]({{% relref "releases/4_20_0.md" %}}) - 2025-06-04 - [4.19.0]({{% relref "releases/4_19_0.md" %}}) - 2025-05-13 - [4.18.0]({{% relref "releases/4_18_0.md" %}}) - 2025-03-21 From 8fceb4976cbe129f1e1d7a948d3cb61ddcc37d4d Mon Sep 17 00:00:00 2001 From: mrjones <8253488+mrjones-plip@users.noreply.github.com> Date: Mon, 4 Aug 2025 12:09:32 -0700 Subject: [PATCH 10/16] chore(na): remove CHT 3.x hosting docs (#1934) * chore: mark 3.x guides as archive * chore(na): remove CHT 3.x hosting pages * tidy up hextra cards on landing pages * remove a bunch of '4.x' instances * add missing aliases for 4.x, not that upgrades can take up to 5x, not 3x :( * remove 4.x mention per feedback * remove 4.x mention per feedback x2 --------- Co-authored-by: Andra Blaj --- content/en/_index.md | 4 +- .../querying_training_card_telemetry.md | 2 +- .../guides/debugging/obtaining-logs.md | 2 +- .../guides/debugging/sharing-4x-logs.md | 4 +- .../guides/security/securing-android.md | 1 - .../guides/updates/preparing-for-4.md | 2 +- content/en/building/local-setup.md | 12 +- content/en/building/login.md | 2 +- content/en/building/reference/api.md | 6 +- .../reference/app-settings/oidc_provider.md | 2 +- .../reference/app-settings/outbound.md | 2 +- .../community/contributing/code/cht-conf.md | 4 +- .../code/core/apdex-automation-tests.md | 2 +- .../contributing/code/core/dev-environment.md | 9 +- .../disclosing-vulnerabilities.md | 2 +- content/en/hosting/3.x/_index.md | 23 -- content/en/hosting/3.x/app-developer.md | 351 ------------------ .../3.x/app-developer/cht-docker-helper.png | Bin 94126 -> 0 bytes .../3.x/app-developer/docker-status.png | Bin 77736 -> 0 bytes content/en/hosting/3.x/ec2-setup-guide.md | 145 -------- content/en/hosting/3.x/offline.md | 93 ----- content/en/hosting/3.x/self-hosting.md | 188 ---------- content/en/hosting/3.x/ssl-cert-install.md | 46 --- content/en/hosting/4.x/_index.md | 27 -- content/en/hosting/4.x/docker/_index.md | 18 - content/en/hosting/4.x/kubernetes/_index.md | 13 - content/en/hosting/SSO/entra.md | 2 +- content/en/hosting/SSO/keycloak.md | 2 +- content/en/hosting/SSO/technical.md | 2 +- content/en/hosting/_index.md | 21 +- content/en/hosting/analytics/_index.md | 6 +- .../hosting/analytics/building-dbt-models.md | 12 +- .../couch2pg-to-cht-sync-migration.md | 16 +- content/en/hosting/analytics/dashboards.md | 2 +- .../analytics/environment-variables.md | 6 +- .../hosting/analytics/setup-docker-compose.md | 16 +- .../en/hosting/analytics/setup-kubernetes.md | 10 +- content/en/hosting/analytics/tuning-dbt.md | 4 +- content/en/hosting/cht/_index.md | 38 ++ .../en/hosting/{4.x => cht}/app-developer.md | 20 +- .../app-developer/cht-docker-helper.png | Bin .../en/hosting/{ => cht}/considerations.md | 5 +- content/en/hosting/{ => cht}/costs.md | 4 +- content/en/hosting/cht/docker/_index.md | 19 + .../docker/adding-tls-certificates.md | 15 +- .../en/hosting/{4.x => cht}/docker/backups.md | 17 +- .../{4.x => cht}/docker/installation.md | 19 +- .../en/hosting/{4.x => cht}/docker/logs.md | 13 +- .../hosting/{ => cht}/kubernetes-vs-docker.md | 7 +- content/en/hosting/cht/kubernetes/_index.md | 15 + .../{4.x => cht}/kubernetes/gcp-multinode.md | 9 +- .../gcp-multinode/add_people_to_project.png | Bin .../gcp-multinode/add_user_details.png | Bin .../cluster_networking_options.png | Bin .../gcp-multinode/gke_connect_command.png | Bin .../gcp-multinode/gke_dashboard.png | Bin .../nodepool_base_image_machine_size.png | Bin .../gcp-multinode/nodepool_chtcore_add.png | Bin .../nodepool_couchdb_3_nodes.png | Bin .../gcp-multinode/nodepool_labels.png | Bin .../nodepool_networking_internal_access.png | Bin .../welcome_project_id_dashboard.png | Bin .../kubernetes/self-hosting-k3s-multinode.md | 9 +- .../hosting/{4.x => cht}/migration/_index.md | 2 + ...ata-migration-3x-docker-to-4x-k3s-multi.md | 3 +- ...ta-migration-3x-docker-to-4x-k3s-single.md | 3 +- .../migration/migration-to-4x-docker.md | 7 +- content/en/hosting/{ => cht}/requirements.md | 17 +- .../{4.x => cht}/upgrade-troubleshooting.md | 12 +- .../container-status-unknown.png | Bin .../upgrade-troubleshooting/retry.upgrade.png | Bin .../stalled-upgrade.png | Bin content/en/hosting/couch2pg/_index.md | 2 +- .../hosting/couch2pg/couch2pg-oom-errors.md | 4 +- content/en/hosting/couch2pg/couch2pg-setup.md | 2 +- content/en/hosting/couch2pg/migration.md | 4 +- .../hosting/couch2pg/setup-and-devlopment.md | 2 +- .../medic/data-migration-3x-eks-to-4x-eks.md | 2 +- content/en/hosting/monitoring/_index.md | 2 +- content/en/hosting/monitoring/dashboards.md | 6 - content/en/hosting/monitoring/integration.md | 12 +- content/en/hosting/monitoring/introduction.md | 3 +- .../en/hosting/monitoring/postgres-ingest.md | 8 +- content/en/hosting/monitoring/production.md | 2 +- content/en/hosting/monitoring/setup.md | 6 +- content/en/releases/4_0_0.md | 2 +- content/en/releases/4_20_0.md | 2 +- content/en/releases/_index.md | 2 +- .../architecture/cht-sync.md | 2 +- .../architecture/cht-watchdog.md | 2 +- .../concepts/data-flows-for-analytics.md | 2 +- 91 files changed, 245 insertions(+), 1115 deletions(-) delete mode 100644 content/en/hosting/3.x/_index.md delete mode 100644 content/en/hosting/3.x/app-developer.md delete mode 100644 content/en/hosting/3.x/app-developer/cht-docker-helper.png delete mode 100644 content/en/hosting/3.x/app-developer/docker-status.png delete mode 100644 content/en/hosting/3.x/ec2-setup-guide.md delete mode 100644 content/en/hosting/3.x/offline.md delete mode 100644 content/en/hosting/3.x/self-hosting.md delete mode 100644 content/en/hosting/3.x/ssl-cert-install.md delete mode 100644 content/en/hosting/4.x/_index.md delete mode 100644 content/en/hosting/4.x/docker/_index.md delete mode 100644 content/en/hosting/4.x/kubernetes/_index.md create mode 100644 content/en/hosting/cht/_index.md rename content/en/hosting/{4.x => cht}/app-developer.md (95%) rename content/en/hosting/{4.x => cht}/app-developer/cht-docker-helper.png (100%) rename content/en/hosting/{ => cht}/considerations.md (85%) rename content/en/hosting/{ => cht}/costs.md (99%) create mode 100644 content/en/hosting/cht/docker/_index.md rename content/en/hosting/{4.x => cht}/docker/adding-tls-certificates.md (89%) rename content/en/hosting/{4.x => cht}/docker/backups.md (91%) rename content/en/hosting/{4.x => cht}/docker/installation.md (92%) rename content/en/hosting/{4.x => cht}/docker/logs.md (94%) rename content/en/hosting/{ => cht}/kubernetes-vs-docker.md (94%) create mode 100644 content/en/hosting/cht/kubernetes/_index.md rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode.md (99%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/add_people_to_project.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/add_user_details.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/cluster_networking_options.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/gke_connect_command.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/gke_dashboard.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/nodepool_base_image_machine_size.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/nodepool_chtcore_add.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/nodepool_couchdb_3_nodes.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/nodepool_labels.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/nodepool_networking_internal_access.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/gcp-multinode/welcome_project_id_dashboard.png (100%) rename content/en/hosting/{4.x => cht}/kubernetes/self-hosting-k3s-multinode.md (98%) rename content/en/hosting/{4.x => cht}/migration/_index.md (96%) rename content/en/hosting/{4.x => cht}/migration/data-migration-3x-docker-to-4x-k3s-multi.md (98%) rename content/en/hosting/{4.x => cht}/migration/data-migration-3x-docker-to-4x-k3s-single.md (97%) rename content/en/hosting/{4.x => cht}/migration/migration-to-4x-docker.md (97%) rename content/en/hosting/{ => cht}/requirements.md (78%) rename content/en/hosting/{4.x => cht}/upgrade-troubleshooting.md (95%) rename content/en/hosting/{4.x => cht}/upgrade-troubleshooting/container-status-unknown.png (100%) rename content/en/hosting/{4.x => cht}/upgrade-troubleshooting/retry.upgrade.png (100%) rename content/en/hosting/{4.x => cht}/upgrade-troubleshooting/stalled-upgrade.png (100%) diff --git a/content/en/_index.md b/content/en/_index.md index 000c31ba76..c2cc868199 100644 --- a/content/en/_index.md +++ b/content/en/_index.md @@ -24,7 +24,7 @@ cascade: {{< card link="community/contributing" title="Contribute" subtitle="See how to contribute code and documentation" icon="pencil-alt" >}} {{< card link="design" title="Design" icon="sparkles" subtitle="Design guidelines for developers and designers of digital health applications" >}} {{< card link="building" title="Build" icon="template" subtitle="Overview of features and reference guides for building CHT Applications" >}} - {{< card link="hosting" title="Host" icon="server" subtitle="Guides for hosting, maintaining, and monitoring CHT applications" >}} + {{< card link="/hosting" title="Host" icon="server" subtitle="Guides for hosting, maintaining, and monitoring CHT applications" >}} {{< card link="releases" title="Releases" subtitle="See what's new in CHT Core" icon="rocket-launch" >}} {{< /cards >}} @@ -48,7 +48,7 @@ cascade: {{< hextra/feature-card title="Host the CHT" subtitle="Learn how to host the CHT locally or in production" - link="../hosting/4.x/docker" + link="../hosting/cht/docker" style="background: radial-gradient(ellipse at 50% 80%,rgba(85, 210, 205, 0.15),hsla(0,0%,100%,0));" >}} {{< /hextra/feature-grid >}} diff --git a/content/en/building/guides/database/querying_training_card_telemetry.md b/content/en/building/guides/database/querying_training_card_telemetry.md index 71aeccb5f7..81dbec223b 100644 --- a/content/en/building/guides/database/querying_training_card_telemetry.md +++ b/content/en/building/guides/database/querying_training_card_telemetry.md @@ -15,7 +15,7 @@ Introduced in `4.2.0`, CHT has supported deployment of in-app training cards to Since interaction with training cards logs [telemetry data]({{< ref "building/guides/performance/telemetry" >}}), it is possible to view the data directly from CouchDB. However, it is more useful when you can run queries that provide useful metrics about the usage of training cards aggregated across many users, and interactions. -With this in mind, it is typically easier to query the data using SQL from an [analytics database]({{< ref "technical-overview/concepts/data-flows-for-analytics" >}}). The couchDB data can be replicated using [CHT Sync]({{< ref "hosting/analytics" >}}) to a postgresql instance where you can then run the SQL queries. +With this in mind, it is typically easier to query the data using SQL from an [analytics database]({{< ref "technical-overview/concepts/data-flows-for-analytics" >}}). The couchDB data can be replicated using [CHT Sync]({{< ref "/hosting/analytics" >}}) to a postgresql instance where you can then run the SQL queries. This guide includes several SQL queries that can act as a starting point for identifying useful metrics. diff --git a/content/en/building/guides/debugging/obtaining-logs.md b/content/en/building/guides/debugging/obtaining-logs.md index 89659ef23c..23824bfafc 100644 --- a/content/en/building/guides/debugging/obtaining-logs.md +++ b/content/en/building/guides/debugging/obtaining-logs.md @@ -6,7 +6,7 @@ description: > How to obtain Android and browser client logs relatedContent: > building/guides/debugging/sharing-4x-logs.md - hosting/4.x/docker/logs + hosting/cht/docker/logs aliases: - /apps/guides/debugging/obtaining-logs --- diff --git a/content/en/building/guides/debugging/sharing-4x-logs.md b/content/en/building/guides/debugging/sharing-4x-logs.md index 61ffe608fc..4ccdeb46eb 100644 --- a/content/en/building/guides/debugging/sharing-4x-logs.md +++ b/content/en/building/guides/debugging/sharing-4x-logs.md @@ -5,7 +5,7 @@ weight: description: > How to easily share logs from your CHT 4.x instance to get support relatedContent: > - hosting/4.x/docker/logs + hosting/cht/docker/logs building/guides/debugging/obtaining-logs aliases: - /apps/guides/debugging/sharing-4x-logs @@ -15,7 +15,7 @@ CHT 4.x moves from a monolithic container MedicOS to discrete containers, each s ## Prerequisites -This assumes you're running CHT 4.x have access to the command line on the server where it's running locally or via SSH. While the script will work with CHT 3.x instances, the amount of logs that a `docker logs` call yields isn't very helpful. To see more about CHT 3.x logs, see ["Investigating logs inside Medic OS"]({{< ref "/hosting/3.x/ec2-setup-guide#troubleshooting" >}}) +This assumes you have access to the command line on the server where the CHT is running locally or via SSH. This guide also assumes you have the [CHT Core repo checked out](https://github.com/medic/cht-core/) so that you have a copy of the `compress_and_archive_docker_logs.sh` script. If you do not have it checked out, you can manually create a local copy with this `curl` command: diff --git a/content/en/building/guides/security/securing-android.md b/content/en/building/guides/security/securing-android.md index bc3d2d1315..5e24b7aa81 100644 --- a/content/en/building/guides/security/securing-android.md +++ b/content/en/building/guides/security/securing-android.md @@ -6,7 +6,6 @@ description: > How to secure Android devices used in deployments relatedContent: > building/guides/debugging/replicating-production-data-locally - hosting/3.x/ssl-cert-install building/guides/android/publishing aliases: diff --git a/content/en/building/guides/updates/preparing-for-4.md b/content/en/building/guides/updates/preparing-for-4.md index 07026e6fcc..4db96df334 100644 --- a/content/en/building/guides/updates/preparing-for-4.md +++ b/content/en/building/guides/updates/preparing-for-4.md @@ -171,7 +171,7 @@ CHT 4.0 [upgrades the version of Enketo](https://github.com/medic/cht-core/pull/ You can also manually test your forms on a non-prod CHT instance. It is possible to test your forms against the new Enekto changes without having to uplift your non-prod CHT instance to the new 4.0 architecture. -An easy way of doing this is to use the [CHT Docker Helper]({{< relref "hosting/3.x/app-developer#cht-docker-helper" >}}) to deploy a 3.x CHT instance. After you have your dev instance up and running, use [Horticulturalist](https://github.com/medic/horticulturalist) to upgrade to the `3.17.0-FR-enketo-upgrade` [feature release]({{< relref "community/contributing/code/releasing/feature_releases" >}}): +An easy way of doing this is to use the [CHT 3.x Docker Helper](https://github.com/medic/cht-core/blob/master/scripts/docker-helper/cht-docker-compose.sh) to deploy a 3.x CHT instance. After you have your dev instance up and running, use [Horticulturalist](https://github.com/medic/horticulturalist) to upgrade to the `3.17.0-FR-enketo-upgrade` [feature release]({{< relref "community/contributing/code/releasing/feature_releases" >}}): ```shell COUCH_URL=https://medic:password@*your-my.local.ip.co-address*:8443/medic horti --local --install=3.17.0-FR-enketo-upgrade-beta.1 diff --git a/content/en/building/local-setup.md b/content/en/building/local-setup.md index f01d93da34..15396fa678 100644 --- a/content/en/building/local-setup.md +++ b/content/en/building/local-setup.md @@ -19,10 +19,6 @@ By the end of the tutorial you should be able to: - View the login page to CHT webapp on localhost - Upload default settings to localhost -{{< callout type="info" >}} - This guide will only work with CHT 4.x instances. See the [3.x App Developer Hosting]({{< ref "hosting/3.x/app-developer" >}}) for setting up comparable 3.x instances. -{{< /callout >}} - ## Brief Overview of Key Concepts The *CHT Core Framework* makes it faster to build full-featured, scalable digital health apps by providing a foundation developers can build on. These apps can support most languages, are [Offline-First]({{< ref "technical-overview/concepts/offline-first" >}}), and work on basic phones (via SMS), smartphones, tablets, and computers. @@ -42,7 +38,7 @@ CHT apps can be built on your local system (with the necessary libraries install Before you begin, ensure you have the following tools: - [git](https://git-scm.com/downloads) or the [Github Desktop](https://desktop.github.com/) -- [docker and docker compose]({{< relref "hosting/requirements#docker" >}}). +- [docker and docker compose]({{< relref "/hosting/cht/requirements#docker" >}}). ### Installing Docker @@ -174,7 +170,7 @@ To open a terminal running on you _host environment_ in VS Code, open the Comman When using `cht-conf` within a Docker container to connect to a CHT instance that is running on your local machine (e.g. a development instance), you cannot use the `--local` flag or `localhost` in your `--url` parameter (since these will be interpreted as "local to the container"). -It is recommended to run a local CHT instance using the [CHT Docker Helper script]({{< relref "hosting/4.x/app-developer#cht-docker-helper-for-4x" >}}). You can connect to the resulting `...local-ip.medicmobile.org` URL from the Docker container (or the VS Code terminal). (Just make sure the port your CHT instance is hosted on is not blocked by your firewall). +It is recommended to run a local CHT instance using the [CHT Docker Helper script]({{< relref "/hosting/cht/app-developer#cht-docker-helper-for-4x" >}}). You can connect to the resulting `...local-ip.medicmobile.org` URL from the Docker container (or the VS Code terminal). (Just make sure the port your CHT instance is hosted on is not blocked by your firewall). --- @@ -182,7 +178,7 @@ It is recommended to run a local CHT instance using the [CHT Docker Helper scrip Now that you have the dependent tools and software installed, you are ready to set up your local CHT environment. -Refer to the [App Developer Hosting Guide]({{< relref "hosting/4.x/app-developer" >}}) for instructions on how to deploy a local CHT instance. +Refer to the [App Developer Hosting Guide]({{< relref "/hosting/cht/app-developer" >}}) for instructions on how to deploy a local CHT instance. Note that the first time you run your CHT instance it may take a while. In case you run into issues running your docker file, ensure that the following setting in Docker is checked. > Settings >> General >> Use Docker Compose V2 @@ -197,7 +193,7 @@ If you are using macOS you will not be able to find the "Proceed to localhost" l This error can be fixed by [installing a TLS certificate](#optional-install-valid-tls-certificate) as described below. -If you encounter an error `bind: address already in use`, see the [Port Conflicts section]({{< relref "hosting/3.x/self-hosting#port-conflicts" >}}) in the Docker Setup guide. +If you encounter an error `bind: address already in use`, check for [port conflicts section](https://scientyficworld.org/how-to-avoid-local-port-conflicts-in-docker/) in the Docker Setup guide. This CHT instance is empty and has no data in it. While you're free to explore and add your own data, in step 3 below we will upload sample data. Proceed to step 2 to install `cht-conf` which is needed to upload the test data. diff --git a/content/en/building/login.md b/content/en/building/login.md index 38e4c6b80c..1606bf01a0 100644 --- a/content/en/building/login.md +++ b/content/en/building/login.md @@ -67,4 +67,4 @@ With token login, the password is never known by the admin or the user because t The CHT supports Single Sign-On (SSO) via integration with an external authentication server. When [configured]({{< ref "building/reference/app-settings/oidc_provider" >}}), users can authenticate with their SSO credentials instead of needing a CHT-specific username and password. -{{< see-also page="hosting/sso" >}} +{{< see-also page="/hosting/sso" >}} diff --git a/content/en/building/reference/api.md b/content/en/building/reference/api.md index 6009115465..8d76656588 100644 --- a/content/en/building/reference/api.md +++ b/content/en/building/reference/api.md @@ -2115,7 +2115,7 @@ If `app_settings.app_url` is not defined, the generated token-login URL will use Introduced in 4.20.0. This feature is only compatible with cht-android version `v1.5.2` or greater. {{< /callout >}} -When [SSO Login]({{< ref "hosting/sso" >}}) is enabled (by configuring the [`oidc_provider` settings]({{< ref "building/reference/app-settings/oidc_provider" >}})), a CHT user must be provisioned for each SSO user prior to them logging in. The CHT user's `oidc_username` property must be set to the value of the user's `email` claim from the OIDC Provider. +When [SSO Login]({{< ref "/hosting/sso" >}}) is enabled (by configuring the [`oidc_provider` settings]({{< ref "building/reference/app-settings/oidc_provider" >}})), a CHT user must be provisioned for each SSO user prior to them logging in. The CHT user's `oidc_username` property must be set to the value of the user's `email` claim from the OIDC Provider. Two CHT users cannot share the same `oidc_username` value. Setting the `oidc_username` property for a user will cause the user's password (in the CHT) to be set to a random value, preventing them from logging in with other authentication methods. Instead, the user must log in using the "Login with SSO" button. @@ -2127,7 +2127,7 @@ When creating/editing users via the [App Management interface]({{< ref "building When a user logs in via SSO, the CHT app will attempt to localize the interface based on the `locale` claim returned by the OIDC Provider (otherwise it will fall back to the default locale configured as the first `languages` entry in the [`app_settings.json`]({{< relref "building/reference/app-settings/#app_settingsjson" >}})). -{{< see-also page="hosting/sso" anchor="remote-login" >}} +{{< see-also page="/hosting/sso" anchor="remote-login" >}} ### GET /api/v1/users @@ -2949,7 +2949,7 @@ Content-Type: application/json ## Monitoring -See the [Monitoring and alerting on the CHT]({{< relref "hosting/monitoring" >}}) page for how to use this API in production. +See the [Monitoring and alerting on the CHT]({{< relref "/hosting/monitoring" >}}) page for how to use this API in production. ### GET /api/v1/monitoring diff --git a/content/en/building/reference/app-settings/oidc_provider.md b/content/en/building/reference/app-settings/oidc_provider.md index d634986b18..c0d60915b8 100644 --- a/content/en/building/reference/app-settings/oidc_provider.md +++ b/content/en/building/reference/app-settings/oidc_provider.md @@ -16,7 +16,7 @@ relatedContent: > Introduced in 4.20.0. This feature is only compatible with cht-android version `v1.5.2` or greater. {{< /callout >}} -To support [authenticating users with Single Sign-On]({{< ref "hosting/sso" >}}) (SSO) credentials (instead of CHT-specific usernames/passwords), the CHT can integrate with an external authorization server that supports the [OpenID Connect](https://openid.net/) (OIDC) protocol. Configure the OIDC Provider connection settings under the `oidc_provider` key: +To support [authenticating users with Single Sign-On]({{< ref "/hosting/sso" >}}) (SSO) credentials (instead of CHT-specific usernames/passwords), the CHT can integrate with an external authorization server that supports the [OpenID Connect](https://openid.net/) (OIDC) protocol. Configure the OIDC Provider connection settings under the `oidc_provider` key: ## `app_settings.json .oidc_provider` | property | type | required | description | diff --git a/content/en/building/reference/app-settings/outbound.md b/content/en/building/reference/app-settings/outbound.md index 81a801d1cb..cb22bbf810 100644 --- a/content/en/building/reference/app-settings/outbound.md +++ b/content/en/building/reference/app-settings/outbound.md @@ -199,7 +199,7 @@ Example: you want the system to send outbound pushes based on a cron schedule ev #### Troubleshooting -By default, Sentinel will log a message each time an outbound request is sent indicating if the request was successful or not. If you are having trouble getting your outbound requests to work, you can [enable debug logging]({{< relref "hosting/4.x/docker/logs#setting-log-level" >}}) to get more information about the exact contents of the request/response. +By default, Sentinel will log a message each time an outbound request is sent indicating if the request was successful or not. If you are having trouble getting your outbound requests to work, you can [enable debug logging]({{< relref "/hosting/cht/docker/logs#setting-log-level" >}}) to get more information about the exact contents of the request/response. ## How Outbound messages are sent diff --git a/content/en/community/contributing/code/cht-conf.md b/content/en/community/contributing/code/cht-conf.md index 6b06446ae9..1a39306250 100644 --- a/content/en/community/contributing/code/cht-conf.md +++ b/content/en/community/contributing/code/cht-conf.md @@ -67,7 +67,7 @@ docker run -it --rm -v "$PWD":/workdir medicmobile/cht-app-ide initialise-projec #### Note on connecting to a local CHT instance When using `cht-conf` within a Docker container to connect to a CHT instance that is running on your local machine (e.g. a development instance), you cannot use the `--local` flag or `localhost` in your `--url` parameter (since these will be interpreted as "local to the container"). -It is recommended to run a local CHT instance using the [CHT Docker Helper script](https://docs.communityhealthtoolkit.org/apps/guides/hosting/4.x/app-developer/). You can connect to the resulting `...my.local-ip.co` URL from the Docker container (or the VS Code terminal). Ensure the port your CHT instance is hosted on is not blocked by your firewall. +It is recommended to run a local CHT instance using the [CHT Docker Helper script](https://docs.communityhealthtoolkit.org/apps/guides/hosting/cht/app-developer/). You can connect to the resulting `...my.local-ip.co` URL from the Docker container (or the VS Code terminal). Ensure the port your CHT instance is hosted on is not blocked by your firewall. ### Bash completion To enable tab completion in bash, add the following to your `.bashrc`/`.bash_profile`: @@ -157,7 +157,7 @@ To develop a new command that is part of cht-conf, or improve an existing one. F Execute `npm test` to run static analysis checks and the test suite. Requires Docker to run integration tests against a CouchDB instance. #### End-to-end tests -Run `npm run test-e2e` to run the end-to-end test suite against an actual CHT instance locally. These tests rely on [CHT Docker Helper](https://docs.communityhealthtoolkit.org/hosting/4.x/app-developer/#cht-docker-helper-for-4x) to spin up and tear down an instance locally. +Run `npm run test-e2e` to run the end-to-end test suite against an actual CHT instance locally. These tests rely on [CHT Docker Helper](https://docs.communityhealthtoolkit.org/hosting/cht/app-developer/#cht-docker-helper-for-4x) to spin up and tear down an instance locally. The code interfacing with CHT Docker Helper lives in [`test/e2e/cht-docker-utils.js`](https://github.com/medic/cht-conf/blob/main/test/e2e/cht-docker-utils.js). You should rely on the API exposed by this file to orchestrate CHT instances for testing purposes. It is preferable to keep the number of CHT instances orchestrated in E2E tests low as it takes a non-negligible amount of time to spin up an instance and can quickly lead to timeouts. diff --git a/content/en/community/contributing/code/core/apdex-automation-tests.md b/content/en/community/contributing/code/core/apdex-automation-tests.md index cae01b221b..a6683e495c 100644 --- a/content/en/community/contributing/code/core/apdex-automation-tests.md +++ b/content/en/community/contributing/code/core/apdex-automation-tests.md @@ -15,7 +15,7 @@ This documentation will guide you on how to setup and configure automation to ru ## Prerequisites Before continuing with the steps below, ensure: -1. You have a [cht instance deployed]({{< ref "hosting/4.x/app-developer" >}}) and running either locally or globally. +1. You have a [cht instance deployed]({{< ref "/hosting/cht/app-developer" >}}) and running either locally or globally. 1. You have some pre-existing users and data already loaded on the app. Use the [test-data-generator](https://github.com/medic/test-data-generator) tool to achieve this. diff --git a/content/en/community/contributing/code/core/dev-environment.md b/content/en/community/contributing/code/core/dev-environment.md index 763683bcbe..63c8f1e19e 100644 --- a/content/en/community/contributing/code/core/dev-environment.md +++ b/content/en/community/contributing/code/core/dev-environment.md @@ -6,19 +6,16 @@ description: > Get your local machine ready to do development work on CHT Core aliases: - /apps/guides/hosting/core-developer - - /apps/guides/hosting/hosting/4.x/app-developer + - /apps/guides/hosting/hosting/cht/app-developer - /contribute/code/core/dev-environment --- {{< callout >}} -This guide assumes you are a CHT Core developer wanting to run the CHT Core from source code to make commits to the [public GitHub repository](https://github.com/medic/cht-core). To set up your environment for developing apps, see the [app guide]({{< relref "hosting/3.x/app-developer.md" >}}). +This guide assumes you are a CHT Core developer wanting to run the CHT Core from source code to make commits to the [public GitHub repository](https://github.com/medic/cht-core). To set up your environment for developing apps, see the [app guide]({{< relref "/hosting/cht/app-developer.md" >}}). -To deploy the CHT in production, see either [AWS hosting]({{< relref "hosting/3.x/ec2-setup-guide.md" >}}) or [Self hosting]({{< relref "hosting/3.x/self-hosting.md" >}}). +To deploy the CHT in production, see either [hosting section]({{< relref "/hosting/cht" >}}). {{< /callout >}} -> [!IMPORTANT] -> These steps apply to both 3.x and 4.x CHT core development, unless stated otherwise. - ## The Happy Path Installation CHT Core development can be done on Linux, macOS, or Windows (using the [Windows Subsystem for Linux (WSL2)](https://learn.microsoft.com/en-us/windows/wsl/install)). This CHT Core developer guide will have you install NodeJS, npm, and CouchDB (via Docker) on your local workstation. diff --git a/content/en/community/contributing/disclosing-vulnerabilities.md b/content/en/community/contributing/disclosing-vulnerabilities.md index 57fbbcec2a..be7427e4b0 100644 --- a/content/en/community/contributing/disclosing-vulnerabilities.md +++ b/content/en/community/contributing/disclosing-vulnerabilities.md @@ -34,7 +34,7 @@ If you follow these guidelines when reporting an issue to us, we commit to: ## In Scope -A local CHT instance is included in the scope. Follow the [manual instructions]({{< relref "hosting/4.x/app-developer" >}}) to set up a CHT instance. +A local CHT instance is included in the scope. Follow the [manual instructions]({{< relref "/hosting/cht/app-developer" >}}) to set up a CHT instance. ## Out of scope diff --git a/content/en/hosting/3.x/_index.md b/content/en/hosting/3.x/_index.md deleted file mode 100644 index 366fc38515..0000000000 --- a/content/en/hosting/3.x/_index.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: 3.x -weight: 7 -description: > - Guides for hosting CHT 3.x applications -aliases: - - /apps/guides/hosting/3.x ---- - -{{< callout type="warning" >}} - CHT 3.x is [End-of-Life]({{< relref "releases/#supported-versions" >}}) and no longer supported. -{{< /callout >}} - -> [!TIP] -> To get an overview on how these hosting solutions use `docker` and other key CHT concepts, be sure to read the [guide on a Local Setup]({{< relref "building/local-setup" >}}). Note that while this is for CHT 4.x, the concepts apply to 3.x. - -Before beginning any of these guides, be sure to meet all of the [CHT hosting requirements]({{< relref "hosting/requirements" >}}) first. - -To host a production instance of CHT, use either the [AWS]({{< relref "hosting/3.x/ec2-setup-guide" >}}) or [Self]({{< relref "hosting/3.x/self-hosting" >}}) hosting guides. To do app development, see our [App Developer]({{< relref "hosting/3.x/app-developer" >}}) hosting guide. - -To view 4.x hosting options, see the [4.x hosting section]({{< relref "hosting/4.x" >}}). - -{{< subpages >}} diff --git a/content/en/hosting/3.x/app-developer.md b/content/en/hosting/3.x/app-developer.md deleted file mode 100644 index d8aa7be85e..0000000000 --- a/content/en/hosting/3.x/app-developer.md +++ /dev/null @@ -1,351 +0,0 @@ ---- -title: "App Developer Hosting in CHT 3.x" -linkTitle: "App Developer Hosting" -weight: 3 -description: > - Hosting the CHT when developing apps -aliases: - - /apps/guides/hosting/3.x/app-developer - - /apps/guides/hosting/app-developer ---- - -{{< callout type="warning" >}} - CHT 3.x is [End-of-Life]({{< relref "releases/#supported-versions" >}}) and no longer supported. -{{< /callout >}} - -This guide assumes you are a CHT app developer wanting to either run concurrent instances of the CHT, or easily be able to switch between different instances without loosing any data while doing so. To do development on the CHT core itself, see the [development guide]({{< relref "community/contributing/code/core/dev-environment" >}}). - -{{< callout >}} - To deploy the CHT in production, see either [AWS hosting]({{< relref "hosting/3.x/self-hosting.md" >}}) or [Self hosting]({{< relref "hosting/3.x/ec2-setup-guide.md" >}}). -{{< /callout >}} - -## Getting started - -Be sure to meet the [CHT hosting requirements]({{< relref "hosting/requirements" >}}) first. As well, if any other `medic-os` instances using [the main `docker-compose-developer-3.x-only.yml` file](https://raw.githubusercontent.com/medic/cht-core/master/scripts/docker-helper/docker-compose-developer-3.x-only.yml) are running locally, stop them otherwise port, storage volume and container name conflicts may occur. - -After meeting these requirements, download the developer YAML file in the directory you want to store them: - -```shell -curl -o docker-compose-developer-3.x-only.yml https://raw.githubusercontent.com/medic/cht-core/master/scripts/docker-helper/docker-compose-developer-3.x-only.yml -``` - -To start the first developer CHT instance, run `docker compose` and specify the file that was just download: - -```shell -docker compose -f docker-compose-developer-3.x-only.yml up -``` - -This may take some minutes to fully start depending on the speed of the Internet connection and speed of the bare-metal host. This is because docker needs to download all the storage layers for all the containers and the CHT needs to run the first run set up. After downloads and setup has completed, the CHT should be accessible on [https://localhost](https://localhost). - -When connecting to a new dev CHT instance for the first time, an error will be shown, "Your connection is not private" (see [screenshot](/building/local-setup/privacy.error.png)). To get past this, click "Advanced" and then click "Proceed to localhost". - -## Running the Nth CHT instance - -After running the first instance of the CHT, it's easy to run as many more as are needed. This is achieved by specifying different: - -* port for `HTTP` redirects (`CHT_HTTP`) -* port for `HTTPS` traffic (`CHT_HTTPS`) -* project to for the docker compose call (`-p PROJECT`) - -Assuming you want to start a new project called `the_second` and start the instance on `HTTP` port `8081` and `HTTPS` port `8443`, this would be the command: - -```shell script -CHT_HTTP=8081 CHT_HTTPS=8443 docker compose -p the_second -f docker-compose-developer-3.x-only.yml up -``` - -The second instance is now accessible at [https://localhost:8443](https://localhost:8443). - -## The `.env` file - -Often times it's convenient to use revision control, like GitHub, to store and publish changes in a CHT app. A nice compliment to this is to store the specifics on how to run the `docker compose` command for each app. By using a shared `docker compose` configuration for all developers on the same app, it avoids any port collisions and enables all developers to have a unified configuration. - -Using the above `the_second` sample project, we can create another directory to host this project's configuration: - -```shell -mkdir ../the_second -``` - -Create a file `../the_second/.env-docker-compose` with this contents: - -```shell -COMPOSE_PROJECT_NAME=the_second -CHT_HTTP=8081 -CHT_HTTPS=8443 -``` - -Now it's easy to boot this environment by specifying which `.env` file to use: - -```shell -docker compose --env-file ../the_second/.env-docker-compose -f docker-compose-developer-3.x-only.yml up -``` - -## Switching & concurrent projects - -The easiest way to switch between projects is to stop the first set of containers and start the second set. Cancel the first project running in the foreground with `ctrl + c`. Then start the second project using either the `.env` file or use the explicit command with ports and project name as shown above. - -To run projects concurrently, instead of cancelling the first one, open a second terminal and start the second project. - -## CHT Docker Helper - -The `cht-docker-compose.sh` scripts builds on the `docker-compose-developer-3.x-only.yml` and `.env` files used above by helping start CHT instances with a simple text based GUI: - -{{< figure src="cht-docker-helper.png" link="cht-docker-helper.png" >}} -The cht-docker-compose.sh script showing the URL and version of the CHT instance as well as number of containers launched, global container count, medic images downloaded count and OS load average. Finally a "Successfully started my_first_project" message is shown and denotes the login is "medic" and the password is "password". - - -### Prerequisites - -#### OS - -This script has been heavily tested on Ubuntu and should work very well there. It has been lightly tested on WSL2 on Windows 10 and macOS (x86*) - both should likely work as well. - -\* It will not work on macOS on Apple Silicon (M1/M2). - -#### Software - -The script will check and require these commands. All but `docker` and `docker compose` should be installed by default on Ubuntu: - -* awk -* curl -* cut -* dirname -* docker (At least version 20.x) -* docker compose (At least version 2.29.7) -* file -* grep -* head -* nc -* tail -* tr -* wc - -Optionally you can install `jq` so that the script can parse JSON and tell you which version of the CHT is running. - -#### Docker compose file and helper scripts - -An up-to-date clone of [cht-core](https://github.com/medic/cht-core/) has everything you need including: - -* `docker-compose-developer-3.x-only.yml` -* `cht-docker-compose.sh` -* `docker-status.sh` - -### Using - -#### Syntax - -The helper script is run by calling `./cht-docker-compose.sh`. It accepts one required and one optional arguments: - -* `-e | --env-file` - path to the environment file. Required -* `-d | --docker_action` - docker action to run: `up`, `down` or `destroy`. Optional, defaults to `up` - -#### Nomenclature - -Docker containers, networks and volumes are always named after the project you're using. So if your project is called `my_first_project`, you will see: -* Two containers: `my_first_project_medic-os_1` and `my_first_project_haproxy_1` -* One storage volume: `my_first_project_medic-data` -* One network: `my_first_project_medic-net` - -#### First Run - -These steps assume: - -* the first project is `my_first_project` -* one `.env_docker` environment file per project -* `my_first_project` and `cht-core` directories are next to each other in the same parent directory -* you have Internet connectivity (*See [booting with no connectivity](#booting-with-no-connectivity)*) - -Follow these steps to create your first developer instance. You can create as many as you'd like: - -1. create `./my_first_project/.env_docker` with the contents: - ```conf - COMPOSE_PROJECT_NAME=my_first_project - CHT_HTTP=8080 - CHT_HTTPS=8443 - ``` -2. Change into the `docker-help` directory: `cd ./cht-core/scripts/docker-helper/` -3. Run the helper script and specify your `.env_docker` file: - ```shell - ./cht-docker-compose.sh -e ../../../my_first_project/.env_docker - ``` -4. Your CHT instance will be started when you see the text: - ```shell - Successfully started project my_first_project - ``` - -#### Second Run - -When you're done with an instance, be sure to shut it down: - -```shell -./cht-docker-compose.sh -e ../../../my_first_project/.env_docker -d down -``` - -All information will be saved, and it should be quick to start for the Nth time. - -To start an existing instance again, just run the command from the "First Run" section: - -```shell -./cht-docker-compose.sh -e ../../../my_first_project/.env_docker -``` - -This command is safe to run as many times as you'd like if you forget the state of your project's Docker containers. - -#### Last Run - -When you're done with a project and want to completely destroy it, run `destroy`: - -```shell -./cht-docker-compose.sh -e ../../../my_first_project/.env_docker -d destroy -``` - -***NOTE*** - Be sure you want to run `destroy`. The script will _not_ prompt "are you sure?" and it will just delete all your project's data. - -### Troubleshooting - -The main issue you're likely to run into is that the CHT doesn't correctly start up, the very reason this script was created. If the script either hangs on one step, or fails to start and quits after 5 tries, try these steps: - -1. Ensure your Internet is working. -2. Destroy everything by using the `-d destroy` [option](#syntax). While this will delete any data, if you can't start the CHT instance, you won't be loosing any data you care about ;). This will delete the containers and volumes. Then run `-d up` and try again. -3. Quit apps that may be causing a high load on your computer. Possibly consider rebooting and running nothing else. In one instance this helped! - -If you still get stuck review the items below as possible issues you may find workarounds to. If none of these work, see the debug file which is always output in the same directory as your `env_file`. File a ticket in this repository and attach this log file. To read more about the contents of the `cht-docker-compose.log` see [the CHT Docker Compose Log section](#cht-docker-composelog). - -#### Running without the `ip` utility - -If you're on macOS, or other OS without the `ip` utility, your IP address will always show as `127.0.0.1`. You can not connect to this IP from a mobile client on your LAN because it always references the host it's on, not a foreign host. - -To work around this, you can find out your IP on your LAN and just replace the `127-0-0-1` part of the `https://127-0-0-1.local-ip.medicmobile.org:8443` URL to be your IP address. So if your local IP was `192.168.0.22` your URL would be `https://192-168-0-22.local-ip.medicmobile.org:8443`. - -#### Booting with no connectivity - -This script can work without connectivity after the initial boot. However, it needs connectivity to do DNS lookups for the `*.local-ip.medicmobile.org` URLs. To work around this, when you have no connectivity, add an entry in your `/etc/hosts` for the URL showing up in the script. For example, if you're seeing `https://127-0-0-1.local-ip.medicmobile.org:8443` as your IP, add this line to the top of your `/etc/hosts` file. - -```shell script -127.0.0.1 127-0-0-1.local-ip.medicmobile.org -``` - -_**NOTE**_ - You need connectivity on the initial boot of the VM to connect to `staging.dev.medicmobile.org` to download the base version of the CHT. As well, certificates for `*.local-ip.medicmobile.org` are downloaded. Subsequent boots do not require connectivity as long as you do not run `destroy`. - -#### Port conflicts - -If you have two `.env_docker` files that have the same ports or re-use the same project name, bad things will happen. Don't do this. - -> [!TIP] -> Set up unique project names and unique ports for each project. Commit these `.env_docker` files to your app config's revision control so all app developers use the same `.env_docker` files. - -#### Slow downloads and wait periods - -During testing on an Internet connection with high latency (>1000ms) and packet loss, this script had trouble booting the CHT instance because it was taking too long to download the assets from `staging.dev.medicmobile.org`. Each version is about 38 MB. - -To account for this, the wait time is multiplied times the boot iteration for each time it reboots. It starts at 100 seconds and then 200, 300, 400 up to the fifth time it will wait 500 seconds. - -#### Too many containers - -If you're on a resource constrained computer, like a very old or very slow laptop, be sure to watch the total number of containers you're running. More than one or two projects (2 or 4 containers) and you may notice a slow-down. You can use the `./docker-status.sh` script if you forgot which projects you have running: - -{{< figure src="docker-status.png" link="docker-status.png" >}} - -The docker-status.sh script showing 4 sections. The top section lists the running CHT containers, their IP, their mapped ports and the state (running time). The second section found on the left is a list of docker networks. The third section is on the top right and lists downloaded docker images. The furth section on the bottom right, shows docker volumes - -A word of caution though - for now this script doesn't scale well if you have 10s of containers and volumes. Content [can scroll off the screen](https://user-images.githubusercontent.com/1608415/137566806-e13b765e-4f95-48be-82e7-c8e6351e14b7.mp4) and seem confusing! - -#### Output on macOS is too narrow - -There's a known bug with the bash library we're using that causes it to always render at 80 characters wide. [The fix is](https://github.com/metal3d/bashsimplecurses/issues/51#issuecomment-905914780) to use `brew` to run a more recent version of `ncurses`. - - -#### "Device '' does not exist'" and "curl: (6) Could not resolve host" errors - -If you see either of these errors, you're very likely off-line such that you effectively cannot reach the Internet. The script will not work as is. See the "Booting with no connectivity" section above for work-arounds. - -#### Resetting everything - -If you REALLY get stuck and want to destroy _**ALL**_ docker containers/volumes/networks, even those not started by this script, run this (but be _**extra**_ sure that's what you want to do): - -```shell -docker stop $(docker ps -q)&&docker system prune&&docker volume prune -``` - -### cht-docker-compose.log - -This log will be output every time you call the script. It will be created and appended to in the directory where you specified your environment file (`-e PATH/TO/env_file`). - -There are three types of lines in this file. The first line will always be the Start line: `item="start"`. Then there will be a Status line: `item="status"`. Finally, there will be two lines, one for each docker container: `item="docker_logs"`. - -#### Shared head - -All lines start with a date, PID and count: - -| Name in log | Note | Example | -| --------------- | --------------- | --------------- | -| (none - first item) | value from `date` command with `DAY DATE MONTH YEAR TIME AM/PM` | `Fri 15 Oct 2021 02:19:30 PM` | -| `pid` | process ID of the shell script. Will always be an integer | `398399` | -| `count` | how many times the shell script has looped internally | `2` | - -#### item = `start` - -When you first call the script, a line is output with generic information about the project. This is only shown once per call: - -| Name in log | Note | Example(s) | -| --------------- | --------------- | --------------- | -| `item` | which log item this is | `start` | -| `URL` | the full URL of the instance, with port | `https://192-168-68-17.local-ip.medicmobile.org:443` | -| `IP` | the IP address of the instance | `192.168.68.17` | -| `port_https` | port used for `https` | `443` or `8443` | -| `port_http` | port used for `http` | `80` or `8080` | -| `project_name` | The user specified project name. This will be used in docker container and volume names | `helper_test` | -| `total_containers` | Total docker containers running on the host. Useful for catching high load scenarios. Healthy is under `10`. | `2` | - -#### item = `status` - -For each internal loop of the script, each one taking 1-5 seconds, a status line is output: - -| Name in log | Note | Example(s) | -| --------------- | --------------- | --------------- | -| `item` | which log item this is | `status` | -| `CHT_count` | number of CHT containers running for this project. Healthy is `2` | `2` | -| `port_stat` | Status of the `https` port. Healthy is `open` | `open` or `closed` | -| `http_code` | If the `https` port is open by the web server, what `HTTP` response code is returned for a `GET`. Healthy is `200`. If you see `000`, [see workarounds](#booting-with-no-connectivity). | `200` or `404` | -| `ssl_verify` | If the `https` port is open by the web server, is the valid `local-ip.medicmobile.org` certificate installed. Healthy is `yes` | `yes` or `no` | -| `reboot_count` | How many times `docker restart` has been called. Max is `5` | `3` | -| `docker_call` | The docker action call to the script | `up` | -| `last_msg` | Last message the user was shown | `Running "down" then "up"` | -| `load_now` | Load average for the past minute. Healthy can vary, but should be < `10` | `2.66` | -| `*_haproxy_1` | Name of container based on `project_name`. Showing the "has booted" status, healthy is `true` | `false` | -| `*_medic-os_1` | Name of container based on `project_name`. Showing the "has booted" status, healthy is `true` | `false` | - -#### item = `docker_logs` - -| Name in log | Note | Example(s) | -| --------------- | --------------- | --------------- | -| `item` | which log item this is | `docker_logs` | -| `container` | Container name based on `project_name` | `helper_test_medic-os_1` | -| `processes` | Number of process running in the container. Medic OS should have 60-90, Nginx 4-10 | `64` | -| `last_log` | Result from calling `docker logs` on the container. Will never have `"` in them and date may differ from start of line date | `[2021/10/15 19:53:39] Info: Horticulturalist has already bootstrapped` | - - -#### Sample -```shell -Fri 15 Oct 2021 02:30:26 PM PDT pid="410066" count="1" item="start" URL="https://192-168-68-17.local-ip.medicmobile.org:443" IP="192.168.68.17" port_https="443" port_http="80" project_name="helper_test" total_containers="2" -Fri 15 Oct 2021 02:30:26 PM PDT pid="410066" count="1" item="docker_logs" container="helper_test_medic-os_1" processes="64" last_log="[2021/10/15 19:53:39] Info: Horticulturalist has already bootstrapped" -Fri 15 Oct 2021 02:30:26 PM PDT pid="410066" count="1" item="docker_logs" container="helper_test_haproxy_1" processes="4" last_log="Oct 15 21:30:20 576ca039cd88 haproxy[25]: 172.20.0.3,200,GET,/medic/_design/medic,-,medic,'-',21703,5,21402,'curl/7.68.0'" -Fri 15 Oct 2021 02:30:26 PM PDT pid="410066" count="1" item="status" CHT_count="2" port_stat="open" http_code="200" ssl_verify="yes" reboot_count="0" docker_call="up" last_msg="Initializing" load_now="2.66" helper_test_haproxy_1="true" helper_test_medic-os_1="true" -Fri 15 Oct 2021 02:30:28 PM PDT pid="410066" count="2" item="docker_logs" container="helper_test_medic-os_1" processes="67" last_log="[2021/10/15 19:53:39] Info: Horticulturalist has already bootstrapped" -Fri 15 Oct 2021 02:30:28 PM PDT pid="410066" count="2" item="docker_logs" container="helper_test_haproxy_1" processes="4" last_log="Oct 15 21:30:27 576ca039cd88 haproxy[25]: 172.20.0.3,200,GET,/medic/_design/medic,-,medic,'-',21703,5,21402,'curl/7.68.0'" -Fri 15 Oct 2021 02:30:28 PM PDT pid="410066" count="2" item="status" CHT_count="2" port_stat="open" http_code="200" ssl_verify="yes" reboot_count="0" docker_call="up" last_msg=" :) " load_now="2.69" helper_test_haproxy_1="true" helper_test_medic-os_1="true" -``` - -## Cookie collisions - -The CHT stores its cookies based on the domain. This means if you're running two concurrent instances on `https://192-168-68-40.local-ip.medicmobile.org:8443` and `https://192-168-68-40.local-ip.medicmobile.org:8440` (note different ports), the CHT would write the cookie under the same `192-168-68-40.local-ip.medicmobile.org` domain. When logging out of one instance, you would get logged out of both and other consistencies. - -To avoid this collision of cookies, you can use different IP addresses to access the instances. This works because of two reasons: -1. the TLS certificate being used is valid for any subdomain of `*.local-ip.medicmobile.org`. Further, the URL always resolves to the IP passed in the `*` section, so you can use any IP -2. the IPs that are available to reference your `localhost` are actually a `/8` netmask, meaning [there are 16 million addresses](https://en.wikipedia.org/wiki/Localhost#Name_resolution) to choose from! - -Using the above two reasons, these URLs could work to avoid the cookie collision: - -* `https://127-0-0-1.local-ip.medicmobile.org:8443` -* `https://127-0-0-2.local-ip.medicmobile.org:8440` - -This would result in the domains being `127.0.0.1` and `127.0.0.2` from the CHT's perspective. When using a mobile device for testing, you're limited to use the LAN ip output in the helper and can not use the `127.x.x.x` IPs. diff --git a/content/en/hosting/3.x/app-developer/cht-docker-helper.png b/content/en/hosting/3.x/app-developer/cht-docker-helper.png deleted file mode 100644 index 5f4d8c00faf2dc5d59cd5694645f6dffdc3fb359..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94126 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 diff --git a/content/en/hosting/3.x/app-developer/docker-status.png b/content/en/hosting/3.x/app-developer/docker-status.png deleted file mode 100644 index c55db2eb8481e3ccfe4097b48db6008d85d73830..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77736 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

`%R!rs@5kPO$*U2_`~^7A zkmuO>qYoehb@tOT-DGXTSKRUtXV=EPpV0D1j_Hvk znyOw?7@0hT)d9l6%ZUEPD}N$ylc90db7_3Svs1!arh!?$a^ed9CBvprEBoyi_kadZ z#HHXb(~sSDo|(lSz@lo)9lpZZ@1ze{1XhYW9ZX72v*;STu(%6)AX36ReX3Irt?;2k zfJD7q44_l_in&f6ls(V+ynDrCl^Ud6Ai2tJEP^kYSqZE*ugG2T<>>9T-N$*A^s7$hLrp8k6fVC_`%Ls= zWgoctVr@2zlAq4PJdUA@PZE8}^%cTCZe-Ss>evHoEl zn>4&e*zv=FIWU-t5~qzcUozg(z2sNuztX!Bh#Nu*bqkLeWj{28IsFY5C)veNBszu< zsuV_Y=Lh`0ZSrZPGWn^m%$=7@)`9ii-t&F8?-Kw?I+YXB;Ra=(`}7NHCAvHZI>#nN z`$};df$6UtJ0_WX&)8y!uy};etH13?MEru?&X;!n^4&VpCd!9qc64mrwT=CZ(${E$ zeI35v5AYLTelz$!dWAFj-8he^O+dI2*_)g&vip8rtOda3T^Gf@Kuj29(fgNTHp5kE z@7vc_uz0EdS8g-dED+I&wPMaJ8HmZ;z8y}qIRxL8+${*YQy^tum!3kB2YkWVgk)Od z{>J$(5ZIe}8L;}Gi`pEy#7R%C(~{Hj`3N3*G*>j zz%UE%>6rrvC@xR+-Ml*#2WWvyRNl@HO>>-gF%VEVw($?Zk50LN^$2l@#p2V5+@Pp= z1-b>bh%;4WN~5NPHsMZOeqRvM@#>IN7ygZkW8jRk=G*brqwWgCp&PPmB{;7Vz@Ial zrZ9s)0;F+>zt_OhPhq3Yr!VnPXE}&OBjtG6O?jw;k z8{lkF5TxJ9oF^iF%^v&CR#uO}edA`+Tl+?+gQ{nT|1NlG67N zrlc%{Q0v@Wqeu>@#F16xOg>876shwbe?HWT$4pS`nDK~uBsFgOTlM252i&tv>b{59 z`ia$Yw8(5-WUY&H0uN+u$#dvtK_b1zv^^|iF|5TXj^o8tZoe6UUy^0B|APo?e-$jv zOiqKv_T+{cK>0MWs?cAi6s0%ui+7OeWnr^{QD=>b(2ENb+xsv}>5Yc&t$}+SE;5N- zurvQFR2-zI)Fi4F3HyAfJeR5NrI+wd=uxt7GknLkm+^B;zu+$S`QK!}*@-Q0)dFC` z^Nde;QQD%tI3gk(J@vP?uamzu^&B};OKl`s?fY`>RmN!WG`qqOp=5?luH#`##dF_W z1ifFKE;|WvP1x~ZoX7dVV?sygXwgX?LvgJjEOxeM^0?_4GlAmw*_=tQf5kTb19nCo zdRxo!9I{{-bpQeCu5yL7p^_#wumZOQ~Kejk&@298#<{G@hiyBO?SSR}x80*_)?j+PY8Ar3X zNfNseFcf;+`OZk4gDj5_(zM)9(b%z}#b63_f z`htbO$Uk_qv?u@I%|_GY14%5Xz0uYZ6KVtg;j0S%XQ56a5?BM3A7KG|+eg#G zHlyYh>ZiYJ!Y&B@w&SB0kCh)}AgKOZ;RgQ&&6S&Oj0%E^(grqHJ$ClL<%8H~ynR0G zj7%%x>%0w@)GuOZxEkzHl_2-^^}D8!diCtAEcZEMMC?2J6GtM#2G}NWp?07xpU>f} ztNj6i$0WSh@(Rp2uel3)AsTNi`gr|Sco;zr1WZv^2Gh6`7h==P=W;0h_Mdglf1uy^ zgi>O$lpW_vNq2<}Q*$_TLD7R#Muj9@?7-sFrXyz}yRH7Z^68x8@O&6ktv2ckdL2Jl zuS#wT`Mj|a(G$1Td#wH+SXUrdhs~>+k0*_oEhmw{Au7olH+b6Qq)2iKb%^`GUy~gt?A*pD_O(6i6;E<@pY%af@u8&of`sp$ ztK<$!H-6-`sw1eY%62@G$qkLnp1Q|Tkyt)dL~8yp<9NnaUe%dZt}Vb=v7$Vv8`^Bi zQqe;CDPHB|(674$AHV0S=u|5G9?M@;-=H3TZCdG2KXZkAi{ZU44b(x1Iey}LkoSUQ zm0Yrv4vfokP2=dF1F1oM>5xK*l%ZsxWRwJX@EP${l4LwUpihI&QT%l^GMe26-kROD zNH!DL!>j_IZR6Crl-Furse%0Mg{)$2M$8)Di5zsYJg)!{4k<_#oaR-JYPK6c2O+?7s<&nu z41L4Q9bmigqCJMNqNPAfr-o$6^v>}kfS-n%zp(Xp&pFjY?R#_(Fpp>=JFvB=)wjdKxoLTdiV_5=+&Qd3RFKcP(TE&L1K*6D&*%eT{bde-Iy6c5IFB z?;g1wFM@-3dIq+QCqMda4u#<^g(Z~hW%e2zNKDma&57s;4{g>a`l^m3&qwFVB_CW( z4Sv3$XSJcvx4ig17s-+6ffWU62qV^V6yKbGusraij~IB)A~%G4_0U~d0dNHwkNOr0 zRU!7YN^6v1CTNF4XJvtRb2?9#*n{J#GfGQq#t?B;ZbT~@5_@$qP3P0caG$M2LOB$3 z$~5nu0THk4&5MF>dj)v#CugI4e~t^hX5cf(RHtlb0zjHH1#T7hHse(G=`9Jj=b`%Q z*9xa^oV^&>R%1dB_#mG@XZBmNg1dVaB-~aur>wS2hlfMkc&PRbJB9mlp&elZjUCM# zuUo}sR*LLoBc2+Szl_}BlFkfWKvOVf21sKoo(5`!@>#;b4goo`J=uGs`Rw^tgoz8V z-{vQgaW=RfLAMHjw*d98U-R7Q@f*c019dVXtxUGQ!_7fQbJ=_)XVl?(g>roiyIG$}S8RA@|c!ErfW z+w=ME|B^zuNiL^GmQuJp!u$lwh9BXJkwQBocNaVvwuN*os&pql+)}u$Mq&O@b zzU}`V9ORu8_a&uK!5HFAu`HP25L>Is<9%FL;nYkAahtvywN7mnm1(jt=8rEo5ccZ3 zS1{%(dz)$*#zXT*Z3& zCX9+q`bFRDIZ8Txd|qd%qtLz34hWSbGF7by9F9IVmGafj4qru6d+aN)-6-Kq`$CDg zdt|l^Gl7$bA~x+%#D0kbM65+1znWg(5xsY>kF2M>sC%a^$&^USrho;3gTGh7ZW4zR z2ZmRp7EIk`sO1P<|35$NXE zo^*lAD8p!O`r!s#_d^reh@9LAH=PN7RXZ7ZxC(Dj1Ih^51*#}kkS6@)h{ZAge%c!a zia6xk;Uqb|{y|ao51q}aem#9ZjwB{pfp5O9QD-ROBhYN==<-SWSy_5K@;M~Jzi*zY|WQD5cw1Lmg>8pQJVm`P`OhM zZziF_GEu=CCzFx&pYIm@`S9HWe!Uw|N%-F*tm_wC=HC~9W2vZ#e|10oeO(xU&;Dr@ z{`=DZaa7ZP>mmQYIWd79qiUdVG~Lrja=HLu;@{(c4|?_gZIa4Ea;$7&PtyBsh5y%o z_|Esl8o2zmEdT#}OV|^Y4~swGVl`*~>0A8g4Z_|ZR#g7?&^{{nFM!tJ)r{l6Te|<13_l?jHpzo9AZC{Rj4X?zRr(g3i`Iz*Z%Q6Yka@ zahCQnPu;>!=AVb<_Btm1Dm4#$l>MqY{8Y8)A6oC0F8o?qT;aU}Q*C zK`#7}m0AzQvs34-rwm{e(kv2?T|f~WN*6u z-j->KeYdY1?p)5le{T-i0lVFA^b=;dtxu#~zmbPw*S_uF3dkQ@K6AGou*n1Isjn4j*^|_QucE7`7Gws!G}7N2!yjVzsp(jXTw*j< zly+mn>x_9!q5m$GQdpm0!;U8dxdUn;f7VJmkiY40L$AvU{uTgV^sWnE*fvV8;2WxV zj28x@a>@5_``e~1GXAywfh>Y2Oyi1IZ(L<_;)uwM$kp*#cL%7x@q1}x2Yk#p%x%-1 zf;bHboe{Q;2kuOU`^CYOO#vp%CQaC{MS-nUSb>7E=V(imr+Oo|GdAx?r^$h&GG4G# zw#N591@mvAmV)%LaaR{hYQd;Ha>7hnByT*>KhM$=RM+jxjG@ukxwNVj75t)m+^{=u z7u*2M{Xnu#Hh;meuaO&**~Y6LS0-a}F+B?Q2>L`SSG~YA_?3|qyf-mPbJ~|rc!r(k zwFFw_T7pd>;0|zFLxYrw(BiSID%~O~t)#(z;&ETwR`WbtdB2QION>+&Kcr1MTk(L> z>1zVDemQAcs1`t&7U+wxT4B52f{D1Hkvqu39|MT)E0%vK2M<5C7IG_?&pzvg$kHft zuCs?DU-~c$mZmb*kPTMC+lL3k_TNzIC+@V9g7wDTx>g31q1O8-8k$7&kA%s9GQoXI z5qapJ?!Lt>h7qrHxX1Pg8~w~@zJGNlRK&kvr1-PFzsi(-7KZS)ulNNFg0Md+SDBy zidMBL5#ntc1@lkzsnjM!99Wh%HiRGe?MiZK>D=^IQiy(;gLyO31?^q9dHFd_?&@Sul7B;a;wO2Pf)sAo{_yXYOuUo;Hn&o#Dq?1nfqfRDE z`f2elh@HNh^iTu7E6RLAdTx|wU1>^Ys^y}}(F4n=`7&XqG6b_!>8v>@b=5YIKLE8i zzLA3w=^37n?R$J0wWX1Rc|hJy-3QrR)CfO9my-HN+jjEUv{H;3`y#jytaeu=O4NE9 zY>0k8&Gs^BzI+4*)5VI)WKZ<_Y@`chkTn_&f}DJ$&p!R zczLwr$NZ20swPmqsImROtdmwm*h*LT8P83MIdPBl!dL6BgaT%8UwruP^SZk;Z!Cda z6QYxU19QC4&{pg@Xa#ibP=Z}>kKKP$@NCw54ooy$D>XOf)Ne?7(ahgNOPAqQI8ZyT zfN`|sN>3qlv$=bljU5wOyS#>_LUrOu?q}R=Q1cpa!iO2unY*u8O_uIsB!R@1D}N-W zxO7qPeB2Z$#-H$%m;)C$*v^p=$Bt2kHVZMFS^H-wGd zFQjuF5IEnc&O}D3G|!;ylV;kvGGskB${0;XWv zS3c2>Q8H;Yn#~9uK|@VL8x*yOG%gw*{^bq-^}y+zM<@Cnl#brmKBs*B^mjhBrofXH z_bzH_$+cb1R6ce3^6?B-#N7+`mA-yamY+GSU?Z6;R2KQtWB1;z*%~yldW{^|+4&{p=eHT4P1L$#IFkXQgnK2y-F^;KLF-869wL46r+vol`eb11mBHGoEv) zb!~lHuyRvmf;CQoBHoxUm(KHBg?U`ceUl(yoZ1cZ5pT)k*tM1437Wp4sM+=P_|pDq zD($ZMt-o<$Gy6tEhKAi2gjeEg=eKn31KpH93PnYJvtyupJ+ktG30mT^nnaOLZog`_ zDQTf$hkZ@v8f$O^+giDC-3{&ym#_A;!3ud}WrGK0P~eh2m`5uTcJ$Uq=R) z^W#LKhzo)Oq}=`7mEhf~2#E?yV~p5de0`cpyv|>?s{LY{Z@09?bk~!?p7vt{vDhPw^GxN<04dq_4!rGLYk z_Rf!55cBCX%hP+&20bn(cEzh=25N^Xh1DTZ5^3;K)9&+zIyXbE87QTyta~EHOm9Bf z)h9(lMQ&}#Wy&0+4AAfBk=~iH?PGkSX3w(L_r~Zg4+!opjSMI=k*`W2SxH_OZw>n@ zT~$d~vQS=wD!VWUk4W^BBHFBCxBL5d@p#o1&7bl(G?7~uvO-`s7iVJo1fq; z;zD6EJCoaoFI_&~(S?#uX#|=x@M}1)at2z0RF6{XkcJ%!Iq`d2nhsR9XZ{UGkVr|M7D?`P8kN=9EkbPF3=>=Gwqs zKFLs*bEJp*)4lLcLMcQzFYIu06 zkmKMD2AZdCU8Xk`Ko{f%ZwfH`)w7P|P#~5A{Q)^B1s^SkSt`ba(bc=s>xz-&wbsw&V z=?Rjq zFvZUIhRD0!0=?ybQrN;3cmzoUVh~WjU zhb0aegAvee0NnCUTu1zUt_R@AM9q=Ft#x6R3wH&KV_Ox%4bAM@>v45Fh%)%IR-|rd zuHVhnqIN$pmop~wy$1U7i_xhr`It{Ju>6m0_D>=wzU!uj3U!q7F-{eQ+;J)*Z*h3? zy1nbz=#b7BDo`;h8Rr@H*BLZ3w7;TO3AfQ+|yO#fPz{F2R(u=$BjM!V3X^br+&dMv^V#A)TV z86Hw`X#kZdP=BRMRD$T_mzvdX$|gFO`iX*!ddnYFmhkwNID0J*;!@9|g`ocO+;>}m z=UpIB8ka91ZxS-wnHC$*!+B!f8^K~Vsm%)A)6FUn+pXqNj>NNd-O$E zlYPfZz{?3&0sWEnN2Vjsc`(ba$)&4To5Jf9LU|-6$K_+bb{78i1y#oj)S7|7r$*#i z?Jq}(5?rX%=;|#&G~}7i@&jr2JIR+B0We|6|Ha;WhBehb>!TBNGi+MVTs0z0V$$r<*R6VHzcUlyeQ+SRENt=b z)7#~zC1Y%tro=4bYK+y8FyO;-FnbhVEW+P~PZW*w%C< zm+lSc!v_X@ZMW^tCEBn16*%4Z94YaW2>=>!Ti)jwc^=GIPZ$XEQTl_&v{Dg zy4$P7QQhE?h)K1%>*t_iSY2=PQj@PP)pVNa;baTe&Jpzpk-_`7@BYvo1K!|do)R*z z1-+-Q1IAxZyVcorjTwBSsxn%<_n^RhaorP6?R7I;ihX6{L$E*{&PCl#b~#-KBV3_( z?6d4I?$c6CU0e|7N;4xehP+3@E(fa&yk99YCyY&5Dm?+o6h8;d%( z>$WI(Y*2}h4=E{X==T5asb9RwXHk6|54b%wHkn1|q6L{H_8xJd6hhU>G57MSgLA7c zJ-oBsuZKx&kyzh-j*z;xJP2koCvvwkJUq3wKD_7IRfS@f59SfVG(L)zMrhCS3*wd| zClgbLK~KyZc;=Gpb_Fe(1`K(26!~3fc?1f|IZ=@^qjtu3z0)EOD!Lm#a~lSBFAjztkC4u?Uu=%tE%Kwk8W(t z<$TvZ`UAAITm7LhFe!P`r4^vcF+B{joU1I=uP^?r;;e-{*-xSRN_9|G>K+dr?Edfs;w?g2r=qu zPNim)khb}VZYx=+V2{^5l%&yKc3-Tvz1pRcwBz8QK3(}zU8^ZIajHjt85ZC+UaGH; z#$HUcr#IJwHU4azC*9MMAzJ^ecVyl&Yd|s+UfYer)i#+i8-z-wY-~?#vwVD3$eKq_ zj5+ymUDEo%&RER1t$|rg#@Z6Brf0P-9_8Pa7-6C0|3r6)9{>mDn47?!r${}RzjGBx zne`d?(5pYzS~Odl0GrG1a;w_N_f(II4jI3i{sds+Ety}%7BdpSFrpYf7Z%M!tj(LF~=>fw8NX;3tT4@|L^FI8;ecQ1&@{FBR!YRyg4v5Rr z5V{=cMakSXsLkk44noiwU=Hk!9M!oyIat6zi=E$ITH<&A-k|ZF4JT$VH>SUMz~Gd)xWV5QIqnFD%Dh?{x6Ka z;qG)}==OnU3_D4=YQ4XkfADJI?&UIAm{DB&uku1XJ!bOPOGG^)AQZ75hl4<3$lm%J;_(_1A5*! zJ4|5Ju7xY@iDC=mJte=i3D5kzUsmrGWRq3Kw@bqKRAVH5$ zr19eEBRs-oy>&lb(A-OSa(#RV#+t!EQ*)2N(a}p4T|SUKjY}@PI1T$tBoQrz5G=`;2Sk* zrz3pOO0Czp4OuMQWcTWOX@@WM8Fu!n9wGucp~-3IYK=uL zeT8WJzE<&TsJt;JR$M0VZjIMqv#s7Z7c&^U+|>+2ciq*r0|MB%w;`f0e>N~D;YvOA(*!*9Lp^!|p`tzx^_=|p z!cw=j;dWsHUnL5?ZWD^SYiFn&v0-o$$BFnyb^nFA$2G36FaIDeii~LKoJ_ai=?G)# z_yNF+md^h6=*M^6P|b0@qKyY$r7;2ad^N!@_Okc$?`%NG(y3%ICt-!Ku{m=KI2tJR z4@?5?e04XWE56*+gQM7w!g-vM!fMzzcxiousX91<{xFw8IR?NS<|(Y zQ~{>CI~V-%n#VtSHu?{^p|CbEeJ-xn<3(RCYW^#!A?6A@7KrrU2{cKZ3lcoOm4f2M zz26}zkkVKAuKqky`H{*yRxi7OjMQfa{jKKO2-&UOs7*>Sk* zIA>3Sb$oA9kw{w8+(iRv7I|8W3yZn0NLI)A{C`~);15)I{4of}|K>ld3RFuB|3IVT zH~zDbz{UUnk>BCg@xuJSv|{H_eL=MBvi^G;)89h=eW8Izr@-Ha|9k!Ki>R&H9*r?> z_y2nH?>9p?fOo#O{^vXXeg?hovcTo|g0ZgVh~@Y}DW=r_hIqim|F0bXn~?z)=KouJ zh81dD*Y`(HohLZ$cZN!Gk$>8Rrrg}COF;?bwC934wPzD(gxmTbT*6J-W5D=*`_-mZQgVg`l4#>54&ssUizn;H0a8o31V7 zF(qo_la#uPgq132p=@UTwz5K%o!#+|zttq}NLi)Mb7u333A!6n;6wiSL@essDKE=A z%S&F71q1YB#!^IN84ZorH<}#aaSnd_uP-TF^_%LeXo$n7%}v*<?0Bsoo{YI_(qb4o(PFt45!?U7#=Fn@>Sp_kKn)QMRxOn-K6U!Ma1 zH$8%tnr%+u31ud9$SU8^6?r(`pl5!8=FB(hf1dGo+2wyeBMTwMQeaOjX=GmPNByi< zEEZ?$5F~i++fMWAD>%x{d-O=39OEvtujC-k*0es3KD*buI#?tecUMF!4P!J1u{S~% zNPsZCwhQkUBS+znBfcN%TJcGTv93BEWX^WFIzB2@fo0Q@o}-_w9yxl~_$cPe`s&^` zYm~!3mk&#YG=h&r`DsQf5X;oq>Ko<82T7D){^D4C%H~v0^25nmtU=#i+!IjiQ-`ke z+*73vcfS6QM;hByF9gJbtwF$k`X|-;*U$G$SrB`KXDbQy%33m|~*3Qvhf2rg# z)*YrY@Wvx3@@rB@0afMFTy0{CFsQhGyE4+a6b6f5!LG9}CVUoP+|A1oluEbT&BpQ` z4Hb8q4A)=Qu$zF%^$A&}sK|m2_w!R%W*n)ypIt**$PF_Z#TFc_Q(`wAk#VX4>OyKz z1ql8^!$lz{f0J*YWvHyd{~Ehi?ixGlTj&1Kx8G%oFDW6Lktd4$>&Fn(#xsMJW>MsH z$ArWE<)&wDP8cN@So%|ZO&CVoxT(vSgNM8C#m1Wq1!;#=z*Z!o5^}jNeb?bRb0`&i(#*}VDM7~%Wn4`K>z=Hd z)3JPryt+aa7&+Zs>Q}}6^%CSL)=~I#7))z))@^65T5f4CVXMxFjpYkC9#LQT1a{1BK zVUx%ga!EYE`AV$5Pu2**yO44j(?*v^xHdoOzKCHTaTg=}(qUMv^_mb$P(f^~mQdk? z8tze~rz(Ekv3w;~f4_g}n`8+zrO{}kK1XiK>fEQpXBq~1G;;91)=w%#LYJdMvWN-O z3r3^IKYDKl30l;7n}+PNNfxQhWg{w(nQv}m;|Yxn92`E7kN_k+M`umTQ3&(x$Z$qe zhA<6}WKu!08svluCqCj3vr7>iZ9GEsKywn-RC_b0)_&p=gcHPdadUq%xx0dQYV4GpH{ABWpcCC-bd>XNOASi#UdD)uAbo+nAJGL}#Mhzl*ZvP4 zJx9MVIOu*FE0I%ZZ}8-z=_$zL^{?D4Z@K3p!h-KS>&<-+KvwNv7FzotKK8*nQ z75DLK@v!Yq)uVD@#o=R#sTClk3)mOlU%<1=VKlTI!RabSpBSKoVsoYVPYy!1pZ%n6 z6EOkkACV}3f?34H+6g+bxo-2Sj0)FS$CTpj54#z$d0pV${ETTr%u-j_W-7+eb$~ae zjJ`!@6{b9!L}Uxot&k{E(IK=7h;Ao1@RkbQ1XU>(`*zEpO6&ex)%RmmcLryw#>0#X zH%**gx+msDtldr5uXGX=Rh?b3y0I>G*4IdTQgT%)rtIx0Z4a$8{3EHbPXD)p9*Ml} zONrUE0Uqk`(X1r!HfbOfZ)spfL9r(K+bO)0e@i=4L?uJ7tjmp)@w|6W@b29SVada? zZA{5~kfgz?m#SVy=I)&I1%lfzO1FwR4N}qpur9K>#v;K%vN58DP7sr&;&B zDXiVNz-UeiGW?E#z5e>*0>G%?2Vo+Y%A1i1wg*OXYPAAEf|O!5ZA$byqgF0;dB)n& zhWx5wsu^uvlMa0RrRPN_`t+hs(h%;M(^Hvg>izmWAK=@#>9=6{@mD#Ow>{&~oP+~v zz#9rWjLuy!uPjurkZ_=+B(xS?VeI=F!DxSUCI*wdb*`;f;uY>cIKavojI_&M@Yr1p zV3pBKGb8y{#a$2TfZIa|Rq8dAc}cBUk--u5G3~_4DHR8UB#h}+b9N*m9Q1r-Z*m6|i>ll{L84R^nLT-XmNjs;7z_2)M1@JW1&)-R zZ9OgNH&YVHE}0RXOYOdIP_mBDuy*)_uTkA~^GBFW+QRxQc)%8lFP!Bfm%4&f5Uw(3 zi+M+j=A!D_Ae?QT!K6{aU-FD1m>1e7p^!lnQtu@H0Ih}`Q<*VM^ulhXqm81+Tl^{OJ`3++bFqk|-MNWB(rVn>0v;o^1Oku2svFNhI)-s#sy z%XOQ)3KZj5!Tmfb(ylrSg7Gy-_&wu^?Kf^V9E6={LV@59%M-N$v!B!*j@n$HVtQM_ zmV5QcTMXiQLi~rkd!)wUD&QpAjr?22ZYgNkFGk;{J62DyKLvQJ$UPk}@kNd({Ye!}Zkv^BwL*@ek0X41-8M{0k4SD${j74wQ!}np2>;0#y*jq1e1rL*K~cobw5LNG zFW48IL!n8ou?HnL+|PG>IH8l!v%dF)&#DIiL(x0-H?+0SSlHSUMH@t+rMdz~55o=4 z^4y|cyCU{t`h=C97Su$pr%H_~=|h&yI*WTf`SKOj)7gi|La~ft)y}`&0BQiCEj_HS5&#s+ZI-pVy$uq_ zwS9m+x$q4)^2Ij2`KmQXo0`-phy{$u<{@x)K?%w%n~ZS%h$pCweWh!fvehvzwHpqSv#t_h_m`o>!Zju(cSNi?qc-_(x@V%Jnge{YI^l6#zZ!B z@Pi#8bg>7|krz!0aOfls$wuq9CpQ%U@Cn7q81xtK+l!hhxf&=C6uWl7zC>PDH?p5m zz>I?0`pg8wzgeN*I@AA}aeReA4w2s(DRpKV#9>(Rg|+?dg|x6rFHiTu7^SPHT4_cM zQLD`$XVY>n@T}3GPF=1L4NVT)a97l!`-OSlqw&1>BJsQS_zI)NE5tah;n7~vLGv^* zQM;5dd$b?E#ZTCK5Fp02B>qmhW=!qhnDG5vr-NQbpAav$#)wpQUcJEfEA;#_`^ib} zfssP=GWMRR;NANZ=ji+QItOM?9AnMvZ6a65?<<}>TX7XvH2Ng!oN{HkHPm9*vD*@jA|c;8pQkWKe`9UK zWjk#$i`Jr6hB?y0s4yOJSj9+PdDk%FqkMc`4@$)?NU(WJ59F_7XlY^ljU=y;9*Z?uj4u(u!Ygz59sXPhou_?=)eq0a`T^+X1PlaDvgW5kq^# zk{9k7AGjxKy_pntID`y#}nM^YOU@C2Sy zRX@h`stWxV<);)+_0V(bBiRQNxr`}==_tA5-@QqTlpxM0L*<_BkUnYNB=wu!rH{|Z zMmYp(@TK7%h`&smFav-`*~FL)t&=UL-oZNw&DrPnI-oL$5j2OZD9N4$m=r~kekut36LYPw%;f6>+6+a zuASiz#FMAssyl99t&3zWVHAcr;czv(+D-2IE`wGmo|FXWL+rfOJKOi7ZcIx?<50pUzo>}p_sAT zJseJjUo)C^t+z6Ke5)qEd%G(yCUmbW3GzUv?RU_$Scg(xM8N=dgYiF~)sV)Ce@M?sxwyv)(DejW1^SYT6RVtG0vOm@jQ#C^`f(Zsc_uk)J!VFEXs; zE@`~A$C%xnGZ7~ob+}u$?tN$kct#vA-ZVa#V{zVR=;Tp7LGiHb^FIZW8|T$z-@(-U z9B5}?emApsd#U&_p}|y};7XC)Mv8BJHD89j(F%`ei!YMJd?y^y>xlY#lP!nN2BH}P zE=2|#3QD1~Nejb=?@3;gxGHRI7VAzB9Ygf2MN&IaLgyc`$n0P?miBq8dJ$Sx+O^QJ za_EoGlIuB<1q~CB`pd|Ktmg8xLC~iQ0pod<<+;2Ch9Z~`m(P$! zmD5$UtS}z)pHsMX3i#af8RPSY{Io@HS_Dt{`vGIdwB{eggE&yzy5*Bh{m+JegxYyz z{Mh$P(nZL*D*GJ^Lj{>|4lzv-?dprpyUbK;(Bzoem;g7HDhC}nL!G~PLUj%cy`&p& zMByIo@2q2Sed z{OCD>amP*Jxvr*2_a?2jeC{uM;m^;m6<2bl0Hl$`p0!y(4%xFJ2C$n0Uy4Hi5krCH zKP9kN+-QnI5%9rTthpj{( zVp`v%)siGc4okXMgO3`t?_~MMZ;kY(-?Bvyc`R}WJ`JxrSkVj1abJ*+u(ch%6`sH4 zxLku>AzRQ5Q@TeJz$rfidY3vON3Q%*b2>=7qr;q?LFLws=E~-PUC`n^m3@xggs89z zsQjXbZt*ZfT}_s3tvq@agYGtC^|!HZ!S9RJI90jEI}A0NTWve(m+}@vMw(!27!4fl zQknVvPbZ7mN8RO=*IXLv54C2!AZ{YtHI@+wUR=iMNR9?uCJBh3#t|iCWQWR%sL+^rquP#JF4IjB^`YJ~GlwZXb1sFRhoHl(4J-Fe zF_Ws$Lb!sW&Vv`rlG_93sh$itc2`J$RcW*$;wH)!{6Wi(d*@$9$xvjH%z9A!~d{Y^#~YJTl-dTm1bZIPF_lWF)yDw?|U`& zv5=;A{84&G@D|fSPa=GNH0pI@c*VNGY;Cc0gTWx3bd`upV@8h+%>-lcX;@%$oYNLiDNY$q`~Htwx3x*718RLb+p=ho18ul=T%RO~-1UVenEg7ml}}R%%Tf0=hS)#I%6R72uNlN!Ja6Z+ z-e+M_e`iukM?!(q&i3dI1oOHyAW|`1rS~)z&+RTz;3V>u&%KsoMyt}kdP}xGnUK7& zGtIEJZ)=jFWI2~VRo4)u;^8~$J?RjFl3UWQ9*uM0!wd^-*~Rm^+G8N!QmbGZaRo0| z{ImTktlqv(9{B<7f9p)DRT_)-JscE4RP>(o$b1qKui6I;+@`>C{F^fkc!R3B({O-? zL^yFCz;_s07!$|8568Ve5o2gN^^B~^ZU#8&el(@wS*155)Ju|u73c`!<2ymWSIMHv z!Ml|$!&^<8jObkoS?aL?Q$`74Tu8EY0K-@s!Ni{Ixz@Yy;oEO@d~64n?au~C&!^f{ zv;Os{KHuea>85(#yEe#3?|9QgR41M`tJ8gM!AQ+DiYdvw5Y9fhDs~zfaA@E*CSs*G zJLZ%;JJu229I$GJYy0Uv+PHq~fnBE*QmPoQR6IA;?(FlpX7+)>p1W*Ep|*qYlUHP- zAtk(Y%W?4^>+`;uRG>(XO|5%|#*3_u)ueTs8~V1(KGdFf)O-Ym17iWplib8AgKph5 zC$j_s^dRI`MQ7=qJ`Q{$w&jy%wPso`02Y4eb9-9u?|qngnA_e1j-E+jD`;O3J)T z;|nXwq*u$93Fl?u`I0y}*bSFp#*`F3&Ip$Ml-WwxCTXd2*NwH#9bV*5`gDJU za_qD$+Z40(x@BZR$^_&L6RHVNJ*&yFY>1p;I>&8g-fx*lCkYK{>?|0NNGJR7QP-@B zN7v@1`l=>%flk{)U(w;-Qf~L9y^0Y=Y*Tm#sNO0e)${7L)9Zu~w~Cj$?hz5Klt*tr zb{JRcuFFLixr{4NSDYby??)I1_4uzUrB}VbeyOa;xMiV}qgFXMHK|TDiE#A+M2{rL zhvs`85J|XV=y-Wu!@o{e^H{FQ>YuPhrYdnHytt!zc!cPfM;gg*`@ z)(IKiT3fgnWjBvTa^yerT<)eixGH?YTIgTD6m-gKj<<=JtIjHsXRfS~SCTa(@uc$1 zrEFB?jAqp9&!NE9J-FLY-CH}4pg$AKK-Pe<$ROWjsEBEUOr*-b)@D5?*kGqVJJ#&} zKpM+r%I)I&o1s)5%U>-P482mDhbYt_p8PLAi~*##_^g_%0%KGDN%;YA-p)g<=5=NF znRek6S;M?fb$9d3ileG00i`JT&8GpB!vB(!y^*PX{p^*cJw9%qDV(IvvadC0Yika{ zEdlYf4~bgdPAISQ-U&mzftlDs%9>xwp>vla@JK2*UH16o;rwqQ9>n#|W}s!Hw_^sr z9Z7nf`F*p@_$qnT-l}F|5;B7gnUXb;pc_NqmV_do%!$9jv`)_@zH|bxhqcJduV=`1 zuvdmVNfR3O>FoTRy{Pzw$7^IkfC|#lK*VK!N!UgnAG$?O_ zL$_Kp5QsQSf#u@MHJ8#vaGP?dq}`@6T!tCaMr^e(Nkqdk7L zoJ$e7FtOfD&aW?fBy|5ODuJ#BmcBbeKLRp70yCsAdc5%Z}M z`=zN4o{$V_2yNG34s^t8TrpPad;v2E1nG04E*EW?T~JUgmm|jtzi1G|hJUeb^y^vr z`I?dld4VU7?|E6&?cwdC<{~cKiy36D6=KO)TzGqqI1{r)s{J)^6BrJ!ku-AOyxUAI z+?Row0-(eH?yJF~K1?BfK*K>qi(O}6nhgz2S~AgYsC>U?$5cj#9!L^L@;COdiM*^Stk&Q@F zjf`i_Sh7Ny!sQ5o=D`#~Ah7r{2UyAy`OTMdX9g1#X%WtQQE<3rKFocYN%nY~vra&Q znQEIP)dqu`$deG=7hmKIO@^*{y#NXhLk_$bzdLn+4#_9k6;GcbN-zKjSZu#5j-fb( zIUv02YmB60O6KPx4v-(j(XX zsk}xgHa|Be2_u$HWR#wWQTh5@pvx}3uZ6jt;6;0heYoa3WUM+Wk3) zt>1dr1F6ff8@AvTk|-YZtKxQ=yPs0oRH_Lzf^*aovUStYrvxBgM&Kmx!IpH}DBbNX zM}QSv;rKUyHBGfChP%eZc#UQKhobah*&SQ&&cE(D#hZBfi&iZL@-P{?ozTQCg z)S`My#w4FbJ*ggtUyt&DJ!Yswws*4n9A_`sR~d)h^xklom%OknsW3@DO3K&aGI2UQ z5PR3`BkpE|Uj^#2*6YO&qY|**Z8DvTbZ-`j2fJRPnaZ7LxEN z{pH$+D4Fxd2;QEhcCeF;dJ_Y2NI{2Wz9gx;ZZA8i3W+VKH$}zCirw9|QWHrWRPuq; z0C4TKY_Ux-TEgjakl;hq%pWi6x$Y97o|;|FP~1PShH_u*(@c>tOoN53giDu!2fW7_E%4nzMe9(SO&)BgY~8*j0fCqXO$^&K>15f zjfNU7QJWbphjzKVH&b3w9^*POr`IJ{K!Tz8 z_@~B2v1Y%yWU$fZ=WDlmE#j=t?bgI95pdIk94tS0iMH7GCAHIyJKQ`z~N)g(htY@jlWr*x3bCZOcRtJoy7PD8c4>Zr7=B=GJ z*dn!^hQgz-j*F%N%GUk2Jy`Dv>t@jT0tfS%Wx0y`qYGtC27hOTC|TZF4I%VNvY+UO1XJ|J4lKYVO&)3KNTojP~P zN9X+q5pkvidsTHqRzU^Et>feIhy4~Q(Dl5`4`p~$R;|-3eh9Bjhn%z16pwLqn|mD^mG1^A~b0v=J?NzS^n0| zG=V4AvZJD~RISx6UvRpCr_)%U{zG$HtBpH}tI&kxmtZ}kCin;Uqg-Q_O9g=QNzlJ_ z{uSLUC*_qk8~jm+eS*ezklsXo?&G)pjkEMLTh_D`*gwRjK8A{%6HfoVgbK1fqTSYI1V|*l*=0vd#!AXE=HZz91#cb3|;cO-Rn+-nIQuF=QwX1cH z$9f%v0a+kvFUE-S!z~01b!z4l`a-6PcnFjRr9+2q+uiB63`>nVgE&gBem^|!o)`Fc z$@thea^4?2V|4m)IE$)0O^tu(2YoeR0*pWWN^KuV9`iz0FQttsO0)Am6Rhi=-HrQO1@Qj25%Z_)uXORqn(h>Fcj#?6_=#X2moIX=mNJ+_>EevsSWmDRaa6`;~)L|<23dHuh|lOeI{IsOe&siQC$e*e*Ac= zCiTQrkJ)cl|Cdmg=o7*~bJXYMg^?6x4qm%v*;pK#HQ1zUaLX8=LJTas$xZG07?~^m zwC$V@M{M(7w5cs=DO@CQ?SDVrK`L~yx)nxfOL38X^{*C+fTC2@k&)_^}28VV4%SA{I*Da z3~w)Zce-zWxrmo>H;C_00qJ|_$Dfb1hD?wQVq$)}-AK;Uv=Lf~7V=smln3!P>LTpu zj}~W^D2a1hu?8_L8>8x?&0o!#=|AUJGZc;FM4;TKrY@%(ZWSKZ`s&jUXY&g2=rpIZ zS32y=cP}ppR~B%Ipy?N7b$Zne3dQWItk<2;Am{0fFurFxKAA=!@lG8RUrk1J)`7#K zmF>9$mI!+rfhFhGT$}y1D^Vw+X=70_xB{4Ul33TahE{xf;{KQ)wjK&sXFNm7DN~Id z=HM+S&TYS7{lT^xf4bL>NQvBHD4z{`ZuBYVWkUube!*rzD8zkN{^PSZXxE~djGm+2 z6y2!af%0Q~=BKedIkn%UtC_V$Rkd8cIxTR)fM(lm?1qI#0C*BFnemkmtn*@g;lGl+ zh@5vyb_RPJ*R`upbg&$T>B7p?NKvT+tp#8m6ISV?Sg`vJTtu>RoytK!p#V&k+p?$@ zjTZft&*V#vCG4n~H14vWoq)rrikpAUOc8=T*21<4z;w?2=xpD8mnNq(O5TkJ+iu!s zz+Rwm{L@l+!}6MV(BTAw;$6oukQ~b^LD;) z%djnl^Tr+SzT}YRs{a!SuB8NiyEk+7f>8+DCsIQ?8DrncFkX}9FiRC|5B~OYjWND( zNhEG%rTES4oC25oA$-c?s&o!7pA}z2T9f)}KQd~fpHD-2R8?wzOVV7z@GZtI4eefZ zR9;c)Jq0K{>_et|l!Lam+|ZHz0unKkCL6F^TGs?qEtlhQ<_BxQuzOoEx_8(@`0J{gi3o`oCyBR}o$q?0^A5K$6kuX*hDf6{?9%g54= zVUOf!1H9vY1)%y`u3V3E1u?Mq=h)n?cgy-9A8$FvKR8FpZr4Lbx~RV=j$UzL1NF9e zEb?fY&*MD>4c&b*P1e>Xkm?U+$KqU@-U=JI70y*5kVo0jVk^7Pm>QX6vJFqM$meoJ zKbhR9Jyn?Q=y^RPe2CbuA+es)Gh0F204YD}VqbsnRU!UzK*_j_@s`e7e^@~1%_gVz zpX=_!0W=3F^{s|DB!X^H2E5N`OgIkZ?hT^(p8*B2E1QJRnv`PeTU&@ik}+ubXn8xB zo_IjY2$l~7WmO(gd5buj^slRM`Dzr{(gD((chPrhTJ?F6bq0ki{Va)8AFSw?$+Oo@5G)M9 z`oS}%xz5^#VJO`d$iQDz!JY5)2RaAw2brv+$m&>Cc5ub53s;I>+qHhA@9=CYHP3>x zV}`0Pk}lc_l+xOh?DX1rS%E2wJehQG~~oN7%(CfQ*nQK ztIUF3w5{RZVXk8@Yv9rBpECtuSoY8Nix9+Q&+cmslEKuuec4J0f=4xavv`tOJ^Z?2 zvaDJLB zRzRe#M$J$jq5_(LA8CXWmZPZS6($Dqc*!6>HjnkF=GpUJrrzaxewGH5*P~{`mHx#; zV7_&*aS4q(a7 zPj>UtPR;k@gy`~45u=eJ%N(MR`@$MpIHlG(-*e27L_&NTH(2X2l%_WB@F?1@?_nD+ z&g43;V}zHa6+a&{95Tzg#jhk5 zf*SowmHbleuG5jnn!gY}+qeXZ)`v7e%Y!&xgwGwGDlVw@GI2Em2f@|te5>wISfl?n z8~48O53@U2-WNpod&KCj)-PV$_=mn^3~A*G%5G+Zl{J5!gR_p6S||YTV{W-JawE zpWB=(qYra(E_4hHZQJAiWf?3_E^@P4Af6 z)NbN}?%j2~_oJ6bVPvte;p~xRf}nlx@KCD9zT((Jwd6(iv~NQ$NajD~^C%pv!biyC6E`a+ z#>vG+ce8b@YyZWsOsD0N zf-fD|sAwmv``S0O(GTUW@3VzV1O{;^eFn;JT$6+B7>6KTOqA_T^qSi#3a>MNK}Ch= zmkZBWcPbC7Xo>QcgJ)ABGM87a5=S|<2{hdXxwmkpJJ?V{%wSg<$AD>buM0fO|()OwC_TCVfaD=U78*z|y7ZY+uKJVWA zHG8i`yq8&j2dsR*2OG-30E+p z9cLdNvOu#cUOVR5r6mM}*T5qx%ohO(8VOij}%6miyf zwif~%38;~3E6x5rzksz>A~sicq#_QPG8Lfa>locL!uVpmK1)u#5t%PwG8lDjaY4Du zKWbDl>B##YSkEjtpX{UBTO^6^GJ+WtmLg#optbaOwe$$yAaxXpXrFv=hy!z+D=6a@ zeD|tjs_*7GsTcHTPn}3O@wnwt@QKT;^ryh4UxIEF@IPYs2!*(xQhjwQgJ1tC-91>( z7C!jY+Q3spv~A*@b;$*f$dEB4(h!P@A`EJPPgq~L;CPoZWnn38g<7{a!gf)KL{3S~ zmWWrYIa;}71!0}HhG!O=F6nj`&E+5hf`S;|_pI~`q-a;69A%wO)7mak4>w^;{7vpV zUNBFafTS6wz}J|YHr_fV;09Dkl{OQGz6~n9c?AN6-g=OBC zI>34`fy8I4=4&l-MvR@S<|TUf^xlz0`)h(j^eb+4EkzLalywCpD; zU(NS6Xq|GqZ2}K*X-WkKD#R2?h86_?$)p;mU#trjbB*6eq`7E@%d~s^a;_NbOYqDv z7V}Ux>86TEYi@??a!7rpQ+mXxvB@!SROJQx0w*mI7yJ-PrhPPhK?;m`4Pp zUfD2)3*KLIOS$69W8NiSWP(z*>VXXG4BR^H6rWe|v+P%Is%EO&>C}#s4$xt@BIftG zJ-)`3!6T#gCcVgj5bMneIceO@ar(mce%j0f9I=LdJtdR0KI%-i|0zYq%J(b?Svps& zSl@Q*X+TDCTW$nseyezI!cNR~QM$ThTVlR%im36p>J3Mg9O1>Mi})IiQM zpL)gFRq@Y}*36WX-P&)jca4Zte5+i|*}_Oq%St!>c&C(Qp~|`p(yI~S4BR?@ZrdQ^ zs4jrR#YCSH;W+OAj}N;3O)rnYxEQy<)n^kn0w=7|K*1$52*Fic8fcKqRtJ>`+nHG| zZUp2O5!CX3wfEjpO?A<}D1HhS1XM(nYC}M}G^s&Q5D<~xK}Dp4^ctclAR?e3MM`MW zn@Dd#x`2dGLg)wxfdoPcA&?OAHtKiIS3Kvvf6lvO+q9;r+WKEvjB@egCOVB z$CX=Lwk6FWjIn)@*TGyJ6n{Dz`FmBE%T=TUPZMWgT|Ozv+2ku`_z8^bSYWRO>iX{R zWT$W1;G|DYTH%-_XW~)u<8_Ci?@L?ZK`v-}YyV!WHz-#q1%r$(#)@XTut~^_H|pN* zx+}D7t`^zW0d|S|9Lrqs&=rbS)2Pf7L{#-dStRdtFb9>4VZ4xRrncpN3IWlpVpfMs z0!l+p&6mC}X|62(?4jmkBX}J*0?X64QBxdPlq;-i$n;C*ES#Kx6%}U%s4li z`^3WNP>_qCP79WGzRI(3|u2|LIoIsFAy`0>PJcgqW17H2SaglmltszvNoyqep#{3N$KM5Qnk z+Pak;`;$QmdnK+!3-{G9oNhrfglnL#Yw09W*}H(~H~P@{w!FE~h5liA&|cNn1iSXO zOo?NsFGOcye+(Qqo1*H7se9lM%hI`8hrw^kVO?m|6h)@FAYdBL#b@Sq%8UY}ElF&@6yJ#iylAvRzqO{8c=5Wqe*izAb<99CbF=`3XHj1=?vU+5GE;g^j{ zgPbhF-d^4uZs>*7RdMrA$rvqpg#lXe8O za7Ptp84@BIi+7kAjg~E%C6b#?lz}Z7U}CQ${UOg>0)h&7c5h{=2_k&h88NzU>fc!` zUC@rx$m5gm8l&dD zd-Q|6il<(oMf~q5O3!Zkoh1T(vo)pBg4hwvVVZ}bAoOBf!b&t<0X4)y!RQ|)mx?5 zZ^`*5(NpaJm)~|z6Y-joDa}BGn)XzB?{XGB(B9IW?xYrM;`H9l1FIc3ttFsqc%)%z z;V?orxfeS+&!d$H`O-+xjk`Z8R(w03=e(Yf+Z#m%ecz@lh9(~d@pJ-`Ya#H-08R~q zhPgDauvE5!3_P%h>(`8CLfT8GLz+&XM1iC%R6HnkwX4v{>`?mXU%9=6eX4EG)cxa^ zezkDnAjP}jhCTx(FdcYq>L78!yB9J6Nr~?A3;FQDww9i?`4Xv!#41tMSJ*5aT6S`Z z)xQ)=zsUgxeO$=wSExes1}i0>*5V+Sz)T=_Xy@S%t$p)*oq8dk7OaYg$PG^U8E;0& z>t&=xd?|sF@POLiNm<=9&FfIkEcSDeu{0@ZT+n>S`k-{ppT&txQDe1O9pon9nD^!y zbk&Nzgwnlb4pGFVu}Rik!O}#`oN2Xe!NWO4>49N!+oqw*tCDFF zH?2545nTO>{o3!ro%Ro_rxs8)D(Kpf?7p(Z@)Lsjx}|@`snSV_-_HQ{J#)ouY<{=hblzYk$+%UwSU4V?YdARsB6y^F zN8!C;QVgZ@IW>TxSJw(@V;eHQT_M?bw6XI3xTFs#;nQYLZjEkQuyZ>46a_OOM;<;3 zMwa7<_TTbl#;_BIcOg7=Fx!ldsts8x}7*wT}UxeKO!JLo(5{9VcqR<{FA7 zq)n31tdd~A5?iPdmSI(cH^VQbaUsSrIe9}M!_R5%ddKC(Q#f>h52$(9RiZK8qjXh1 z09ndqvn0E@lr4j$H@EUlz**&;44<02_|ZL$eae5~r6czJCosLlSMu&~u&@^rTOd&b zf4uHra?1B%@F)10$<^}NOmA?FZmvcO-Yla;|P}R~bA%Ke;MrTxZ5D z@9gi~ShOxKB~VQ&|FDtdE+sV7CVNm?#5mDbGtF8IwRT_q`NC*!#@td#ICq+xMYYXg zYO&4~QHVxD{I8nKuaz83`tTw_)NAVFyMo0g(Bhzuip2RYO3E{-E;c#497PU`fCuyN zGS0_XTU0`Qd-u))Lu7-G$G8Q>^2^X}f9qsZ&04BaI2^K*L^sK<>BGR)a3?oaIw?cU zYWn(MrFK3N|LKYKS!N+#I}50XdG^%_YT1<FI2+ z0IOs3n+t4bGnCFQO6bX@Xm$_R-C3q*kQEUqVmam9>mi-3Jv~p7yyv?#J|S5yk+VXX z!{~inp=<+op{zu4q}M{65Z6>{n3&3TZ> zhBv~$bc0=_8Ir0rv!jT&KKho%Z*7JeW0*bjtr~HR^j=bqC=cTnD@p5ilgS2YZJuuG z9s|SO#f&l!#+s^Y$EM`-a z`hw&OaM&*`@@6|65w)Ronrzqm6d5?QAA-Q{pBr2Bak9S@*jcV}oqB!CBx zOgh05z?0IQ^X^C zAn36pahOx~$+s86EO9ju8|I=pls-MY;<3nlrJ+r2W_!*?}K2C%g~L! z==JQY0(HK`iKw)pTD(l1`=w3)(7i_A9zn>n9=d6ChYDbNSN~ypa}Ik^;WjD}`1(#0%k5ajz-A9Bj=t`Nqf`@iIXp|&Yvc9Ct5;yFwXjx} zh{kc0ujGB`BxR_a%LXg!xhUt~2uwK5PRoDLu1AS6Aq6MVbbGTV{Al=23aXzljTw&y z4MG%m?+7FmA=g2v&p05Uz4eI|0gS&zVx(+xF;?cobb4HOtrui@-bl*Pg&-v+G)P!# zE{wwRZ*nPYXOPFj)3sOoyoUSH3UMeEv_qY zj;Dnt6#+G*vm*-&iu?CGq|HnFds7rhGgH&$6%Uq*OfAbpd&>#y6=0Qdi&d;+(edLn zLSO&FU8|wef(ZK^T*`)Er!NU@lT#pJDRn!@6sq5u?}@_ zU5@|*+6oLP`X2*&B`pyUe<=F9t*xD7l=PufCLd>my|tEBA&ORrZ13h*@)UXS8)nTj?=W-KqNv03|TJ7E>2#kAbW4BRzNx<2K=`vSMqHjY8O zgU%6__o(4!76RQ91_cA$XuEry2aW@{@mrr*&mRhk1NKI~g)Z|(hNulo=MnjFu4s`I zLpM`_06l>}Xa;|jOtL#3D4j@Xm?=JG2QrNqh7L2VmWo_FibKr`(@~$NN+{7w&CAB` zz5YyYFIjDH&@ss@JgkTuVw9XdZz?0=C><*HX2=RJ{XMU!N`|pMHCLO~ zDv0k1T(1n?U`EEGAFeA(uMJ%W2Yg76M@?MP1;N&bGE4kZ+hxsKOVC_wRGd!SM1WJi zhPJRy&Z>AuZjOi?nsn#rLSWWXiBLF&6uoPikUB09(h8c^j&R71RqC`KOIqELuV=1M zFI2E&e(VNi-;{a$e&v2wsv^5+UsY%9HHSvIJR_JMy|qLF4I(k|M`b7_>u>eVMO21W z@TBBN^mL`&x+x`a@%6@DL&3nSQ*qOE87+>rvXEt7pfL0)O2E(&hWr^w2RMebNRT$P zLuE{Fs;R&2{^c+TQpi)Vf)o%B6N$@&WrfmHsbt(VX|u;E^?Gt)VRn0+iN6VJ)MLlq zqB{)u$w1YC&-hRN)@Ki@cO}UaG;LO8GUy?@e#D7jlxOjIHJK)k{%3?~yU_}DHj1y7 z^eu*zv^GnBuQexdZD3(kieheXCVK{|R=@d`GRtI5-b8FbrDHpj_|bo=KqE@)0_W;nLP>l=!uOi9%Vm8qFQc5s(<`Y#+8&2DjZ9y3 zs=XUAD{b5hsaloG+HFB#S#jlj+O@nvx?8r?VbDRa1C?N*EE0J)t#F>&HT+i3)+>9h zu3H&=$dxs$!`o!XHX8FS)U`6O<8q^Eqg9pGJ}0f=MJ@lyNlXhcenWi9X+&FiM1@Pw zgZb}PIy!!DU%8s=;>uFTHk;*=Htskd*iDd-@JmumY%))l!VQ#J^Li=r8bMAQ_IlXe zb&tX!a){Hz-{A@uV-)T?Ub($RpiY*^TG}m7(YVSh2PD37;e6U(YRiCfT4UiOC6q zP;#Yk^j4iH0J|tUr>qyy4VQI);jBW-6e$9FeUveN!hq^mB?kq(9KDT^x;vGX{sOaQ zG>C?uoJlj==`+VMqsj&3ZuuVhHQA(TYt>9D+X!~_dYNn+e^p%7tXBTS5H@p2Wp07f zyY!65vUQ~MR}}Dw+oPZJftTDaDL^I@;`V>Ea044|ny_lFo^{g}#5P*vXf}j(=+~mi z<>pN{B0+VIw@Jq+rWoVid2eV{^y=hCq&~3uN5@aZLbE>j-6h4Ue>`nvFkB@J<4T1{ z)GLg?ABys$1F9<77T$eW$PHvaeamLtQ}tsZ8hO+jtQQ*csFgYQx8`*ru}-AI1=q%c zS%Id-O<0=O_Ypr9!|TezQ~`taW+szfU}tJN(H}k*nl^2{dbhhr7N4hvMB($pHqtg% z;fF*W+T{<@JPmvL(Y&s-tgR~sB{_VN2i z*dir{>IP)xCEEWeId?uNX)IFw!0W@$_xsFr;HR$ys2Ns-^tG9UUG?kW$6N&%`a{i}gSK5`RWVij}EE666I8a~fkDtyjpjpGT zANaLuvEdV4!=hYCzr6!NHX^3}?qGpe0Aakn=jyR|zOxNEg|(fPuJdY1$gJE|Um#0Q z;b*)18GBFp{v0#lM|#=M+4%kqnwK%ZzJLD*o814zBRWSbH2V{W)Jf=y5dTt$EA2%N zAPEsM^xG~yK6MzA#p!pom=9S@jSD%wG&J!{V~Y#O^hO*X`ROLv@9BSj!{e9%02q{lk9FGIpt-`noCh7H5pu7cQ`M-GR2C(^Wmzau=&|AwapONM1TK?O#R6TG@>f|rBc6f{bGUrdlKG1=V>&bkMDQw zX@C<_-HEWDe+j&DtX#J~9 zmV?L%X4ynS{sIB#eCDY-rueHHw?l8obJ+wRlMrco15Zk@d(>VYf&Q_*yKUl9Qog(+I(@?-D8x&_i`&+W#`H-$@6Ml>y zj;Utm^_nq#%lkw((~;fQ;eK##TAO}jJ&)CViM6JIWqfXmc&?`+wICR3U>STXpfXR* zr!TS2@oPiYRSzz9E^V9+=SbZxIjP5vt56kLpLx>co(tz7tB4=z_I6=T?~Wn6k)SinKa@5%oN1e3a2}l|cZjnFm-%;{37DZI!%O*g8Od*bT$C1R9YcqzGR!K?j9XAcSa zF1al(w#|*pLW$yf?}Zv69`v3mS(N#xGJ_N&Ln;?+4xsq&xe%7F`Sxxv=i-Fl9j@SkxaZQ6^QX6*YFJU;_5oumIKQ##o|U>5mt z^Yslxwh#8)m=0#debM__)ocIty=gOwR&r_FbrRpuOttPsI^91~so4kN2=#db=RV&q z@SR+KQwZ!!<%VYE{dNP3k?I?TIod;c-cu~r7cT*6qBM7OcmXpA950!EzC;IMlk_Qq z<3<7y-(g=llKbMhs7+K8we()V72*cS$avgj3_N(wl79%Nt^n@j@!6?|P5P+Yl*C!2 zXn5iKR7|C1EbOPyYd@+l|Eu-Lbj^KVumxjpk^QZN9h~!Pz(c>5R(_1*K0cdxVth>M)fa3)BzIuFmPGG+_-k58Md#XUC{+X+`1i?rb zGp{?d0{+g1RT}~+g=IfnIT~J(`C*p8wu4*6=0&tBp?3E*sfh@e5E4=gONX*=LY#ukS{*DxvXkkWs!WVr1Gw35 zti4fOvDCB!K#GL@Kfh0G@ziiG*3*WwcGj$M9=3K>B)7tT<3wNlEg#x3ZDc6k$iQ-L zj`OPP;%pU@WHwmZ3Z$q`k%Xv3bz?9@Z>SVQKtC108wkOB|B#FM^qxt@gGtxj-VQs< z6s7D6T)iryyB?|8tx%_OZweVP$>OMNXf-9GF>B`9**$#G2}~Rwhx~nL zA7>tkpI}HxLA?5`xfcXTsh>(RL_}Y-Wv(HZg|))5n}(`!^-Skr{R$trs#IzIBo|uG z&!Q<%Le+i>sAR2FuKaiI5r^GZ&+k6w5$CZ`bC*-DxS{2t_LJ=rQQ|X$p ztmq6=@9t5x@RFjG5BjSfAs>$Kn)<=tXtax%#w{PoA33Y7{Ap_1ueDNFbMMnpjc`$@ zQkcvbdQrf*&cI{*|Jyr1`~oL*zXvC$*A$H+p4^_dlKpl(U*8hB^*UiWir2mZCWGbB zJ{?T1tcmdOIt!@Yl;2N{UI+6GzO(p#BwqiF-MF3Fbsi3Reve%WBxFpyHi25(G6o;O zCBvVnXLxI4?0w{gtOo0LNpu#BKTBSg5b&EZEf> zwa&8W&yHHJ;K(gX0UFt|@AvqBX+&K`0sL-1XsWTUXms0wdCoadZobIeq@y}#=?3(7%g=83wWP86IARN|3P%5S{1YxcgI9x@On za=l9ElMM95>0XOfONE80L=9nnVgj?Q$Lu@!{P+C4t0(ll?`No9mL&mS)Eo7?3H|*J z!;hCQ?~I-sOVay3b}jG9FX#ZFWr>(O>Y4NbnOk};lDDYgyr#IRUk4yBNi4seQ@w7# zuWp=HG8pIe{go>rp4?K{kTQ_dr7~f5rrl2d*;ZDi-HQF>6K8Av=ih>aaI+>4_Vu#B z@4vpMIi?;=C*d}Gv3T6wSZ2paU*Gb>EPKMc0H<6j@LE)kJU){uR>q+nfnyuNubNi) z76&PMs`^1J4eW1)ce_sBo2fKU1#QI!?K*_-DLA|c{g??%2YZu#M*@I0|4ZE<`?mjo z-r4d$_7(}{qZSf&>z9(&=BP*~O-BYh<{7|AK%@2Mmj?tmS9PA9*s$}5vIk$0c$^Z=*eQMzN(%zwb_6~vg+;Mdj&jnS8>RYD-5!K%J1!QenRiC9VL(!d9exHglHKBJRFJ|o z=_?M~>2)pV4Jhs6ivt_#krT7rkkn7ygD;a7$_V9b*LiQeul%aLy`Gip9mR36fGYqM z#a4^ap<08v`V-arNL;`|Rkp*wb2*;9y_ngYcD+U5!nty&;pYJJ5qfPqr>aXzW!c$u zeuj{vo`D*zP2NPKtmRG#_uG>X5>(H59_`xw)Tqm>VC_J;V+Z5*D1N1vh4Afcuxxc) zZ_{HdlWnoS82)4m81nUBj^TY?`45?V`u^SP%S6n@LM|gKSEWmry&h)DrLU{2WnVV} zP)_DE`Ux}k5F3{ued`2X2PeZ929{ElL+Q4=ee;{5v=$wuPWdN2OdY?<+BQYoO$-dP zt(V5Lk)O{^gU6M;494`S8p7{Q!u`E&I7aUB>70Wjy>KaxF`=I8X=dHNeU4{HtLxL3 z?S}#~f)*-=^P*!VytR;luJnZUlqP^oi0i+Tme2PRw%E#hPbPi2t52ebTAxZYAQ{1( zBe?n(U!%aF`qBxT3|3=J?n*r}Lbad~xrhaBq%ro7>@i^^I3c7JgT z)sHt2V(mtOv^Scw8==NQfj6x?0;*2?Pces%4(L9YlOrz`1c`Hdgos>ga?RR9UPuUl zGI63>z!PIt7}Qw61enPh!L#OcI5IzIVoOcJ{qtn!i&n*R$OmaF(e}RG6qs&f;m5$q zyI`}O&eW8FVK3PG9_YO!fwqkXI^oSj7V#BENnI&`QBdvNPmm2!{cHb0ji{VMy%h>huIKnb2v7~k7F#`C}|Mq)d^povE@Ym<7t zTF77j(qRKyxq=WC9&BoJgxV&CuTKm)=Hq!-=Hj7yDO}y@5m*jowCu)CJ#{Zdd~xHY z>Q*U6Kq5>-|x7x zOOCQqySrK!7GpLmLW{lSwIy0^B-ma|nby;`U*wJ6G4yupHc$TW;5jt1!5xTx*q#21 zHlJ;)cnScLWsLY0b>@_DRxrmDEU%CR8*O2Me({xSiI;n8=$X$5@vW_*>@?LMcvo?@ zc<~c_M?Tu_`{(O)7BDy9eN|WN@8uprv&OGA=*Gy|EjC=X**!5+_8?=2Q*uLwY7Okp znRWkXoNJ%rCwOycf$B~7O#o#$e_ZoLwTOR7d1$HIZnE?dU7>XohMj@NIC#x_ZSp~} z3(uOW^g^ve5}%|kiQHT)Cv97M%+}DR06I5#sZYDH5|dd`!N^7`y&UNQ)w{hAI?T3q^F=2> z`7r3eN5kf5pX29-&UYr9Z$|cBb_B(IH`U_tP(Pe~`6jR|9WYvWF{7G?Ej}wlDE8Y& z71XE@S?Hw+bdom))jgi3LgY0!Zb$h{(?)7nSdW$i5;8 zxSa5@Qj?9>;4fCk3Lvjrc%QMRA?(mw_W+Bwrqui3A`qopyY@5Gwokj4%!7XbVUmv` z4P&ny38!-bar~Yx4C|Z-SngSwc=m23nr|+ZH%^!Hp}Mc7eU>Si)aP4XUMiB{ohsp8 zo;wYZ&sG##<&K@GEvL&-#F|{lE+qAVhro=W%lv>cGP|l!ldic~>o1RkroCAg7_+;b zW*e8XxRh(an!V|-`&{>uf|U^=bwnfUaV6@hk#e-w#-76WbzaGq+PI-DHOWu$D;dC4 zqP6E|Ui^NS&)>a6e;xRb?o?Vof(2)A54Th0ydqF~*|Yz12o7nA8`%a7``f%SM=s={ zPK@Y-_v~g4_s~bcwIuM}=b%W@90nnYt)6>L(~91?(_cl#1lpO;s&h@4&MEZCTmW#x zF0YQYVa2@;|GvbBXFY4nAHth1e$^gf%8)VTV$<6Wg!$>u75*VM!{SNuH9{OEh%Z`q z208(@2BbZZ$7E{%J)l^^K|S-Dl>dTb;mlQ_uirAP|HZB+*uj=sx;fGupC~6I&snK` zxpWz^q#n6_MVXH$X5UhN@qj5_T#B9Q<~Cj*L#R?3Z=@J%3xI29d|Ms@1~g#To`Kw5 z-hD?1(7CxmQE`sAs3m&_t2t1W)Z7`*jl+)tb^aSMIdN$PI`Fa*`njDn%(i{=h4rN) zoG>jKYzg zfoxoWp+bdlQEe92@nif7S+S(1&6Jqbaqjkui@H3uJ$h`L)m1)lUhB!Mq!V0&RcaDJ z6l*rJpJrsBxaVE|zJh3n~v5?cooL1YEYm{99E6mk~pM1~`Eq|F`3S!0sRa|55zE zjEU`c!|fkf%tP9h(iX8ljRKDU%L)5v133NU zZ(&D!1tLLlJHFCXH?5mPzzdZW{-yp-98_N-VIGxTx}%JswS$wI_OdiMS8MBnIqa9F z`Ab{Yxrzn*+eO6V*k(p@&X4T?m7*2@rJ-IP2o?sy4zDk`+RZHUki6%a#_Ctqz-Jb5 zppr8C0yK+tKdnriV@p`B0nRUNN`5E&TGFDoVt;S+Env4HMA2`0#iWPenJG<@LYq08 z$9eVTtTg4-#H4Eq(#pd7_uM-6(Z5RbYd0<540$N9&AH`b|o%KyMxU>16)U?nA^+ zDAN{3i;%V0RcTMZeBz{cVr6%vg>amvH{xH&QA`PuJ?dCsl`f6Mzp5l1lKEpr&2Gyq zqQYrPzSqCjD3+o21=2Ri>6<^@(}nhb+K;Da&o2%vOCm)O$r!(O(}rM<$Xg8yVL%3M z66?QtvxQ@xsuXSW95r1wNd;wg<8nEZ@z$2pjjXnb3Kz=Wf~D1 zfXlGDN;s*|-oozyAQ$8%K(mbqKr z>FL{J3YHVlQ#rK@mbm>h1*Ty^hi^JNgtLB!+|UZ&-EXYsUU8>yFt%hDWl!XmtP5Uk#6)@ za%Q8fsLJC^yE!10Qflv~KP==w-4YO|<42AsM1=U=UCe&%mbMsX!TZjKQrF$Giq~wy z3~dP(cgvO}N7b&=%G_BP-3DU_pHz?gtMwQz#h73Nd-ywlL!NHj6e2f>qszq+FZf^%d9O(~{0r5Fu75t<@JlmIEZVMe2SA#6H&5P}Vv zep8ek&pbek^BZ&9s|!BKwQ5*I4H9i>ymeO)UU5djp++L^ZEWLZ;*YYLuP=;$?HG$GBABU7F(T!V9aRkvA7H8n~gzOXJ(+bGq ze7@KiMp$yjfhoM$dvwyxIw-p=7tQB`Hvh!XO2==WJW`A2S?tv_9nB48xi=OyU`sxx z&o$$w7>6SCs9C>TSZSTRamWH!lUhm<56g?LP7^glBOPL-%=y64_d| zfHkuVyldYjoO=btj?}&&@2HH6`*&7ot;YY6`Zw@w^<`^N=<)djB?PTx%#3URyz6;ajnbe_Azut^zf%FPi}$kIizwq;-K z0+l>Bt8yUX=IYEBEJH3Dd+S?mF5|dkpEss!+6mG&VK$o^Woyt+gL<2C-1`znn`gnM z6RmPw5oi`?ME0k9E`1`ux>6`x@7zmik`sbx>zU(S z9fN)(RpF5GEvN_oOsc92p0WOwRrS%|@=VQs?wi{duZ^t@HUY%>0NTyoE%&b28N0<- z{e4fKwugwxvQ4=`D~C^+uz@n34lsP4FF1h2cY1D&oSUEI+oZh^c!P0OKFn!sFXC0I zwKzC!>fGS?n8Aq|@X4u;LQx|b+bHa288d0cyrg9Ec&|nKxnj&pW6<(PKx$r;E?v6X z;BRRg%{eqPDMuLW=pCyi@TSUJr6)sC8w>e7Y^%qm{m`||D360cJlHq=H%7+l{0HME z7)Y5P32{v>X_qUlF?`F{1hb^tVR1iVq|4ixio3LXqb!3GnMjJYZao~4Qw|q-rRlkj zcdINhekii2`#}$GaQ@Um5}8c)>K*m5lTV1(dg9#sh|mDYBf@RGX(%RNd~^7lo4Fg`Xj8Iy_U1b&!IZ3>S@(({IF_?%A6k8Fi#! zB%ao8KPbI)oF9m*j=mrlwp=G;MAgU~U|P*;2Nxl$mnbs5=W{$}GBcS@YqUfeeT=dB zxhYB6;AJPUqP#La0=ctPvQDqPU8T+6SYegC(3p*?-+b*4#eglVhE8}M^@Ohaf><1^ zkX!oCplORJGXtunpBCt`eux;bXu0Q3aqYK;y;p>uV9)7>Vcst~(?t7jgrJcq+OXY~ zRO0IOnb-fBEgJh0FBzS8TWt!5-4XP?Acc=bXr8k^<3JcwkoDM$DM>iP?^}N}ndZjz*>6|{&P84Q zqLUp2EQMhs4O^l-;;hVaO^O>k-#gwzv~TPlf~KUi1mNXoicR+e@{30Vdi9B@&)Cr| zUmBXS-jpwUl;F1C=v1OPu{D{*qz1z6%NP*?VN*w{T$B=RhvtCT)9P@Sg2P?n`lr z#oR3DT2jxU&m*s-REgNjwpZlcBVFz`X80J5VYh5Pl;8L}2yoDu7>NZHvd^mlQi| zM>Z+5=T#iuTta=u4fcy+Z3AWlaka1@-i0lX64>#pi!nCf&}mi?i2qgDSMbTO7GOU* zIxmHU`-(L03?0&L?k8E(q~FnHzfSW`N#i`QJg&#OEXO;YX|}q(ka~~9x90JECdBF; zGou7IAIe48SB5(CZIXzqXP3VP3(%JuMbvS!roQ|+=s{TEz=9p&l zzU)LMn(VkS-jn;GO&Y$~Av#7Ho;RnCEQu^$3v?G8A5HOiJ$!wOWGx0;Ge0OAgu&$X z1w7re7i2SOuz35<%j>)C=r? z&#ULfcJnf;HKDGtAMuu5*)BS&BeHCJ#h$Tc?(RkF^pyApM zv}c^iwm)Xl5YRA3Z{wb6)?P91L*-^~{u@!sbE{@7og28pzS;IBp{Wu?TNtY2{RDZn zCBv6GmC~0Gc@mLL}VU(fS7Wg%|pB1ye6C)iNQPCYej8Cwr2W+_Q_Y zIgltn*YADxbDM`{T;F~1wNQ~*ytXx**0unw^)r`cPKG?;3GA>`r(i=iJ@-d+#IhbgzXaXnU|RagfMQrx3-yh?IJbB zp!#*hs9suhb~!0%4dORG&f39^=fYLpT)}X+tDsu>vgTlN+|jqnxxPT~%KdewS&!#q z#Rw#GAZ}&v+P*iuE0acE+eu9ENV)Ta5u`yUsb*<%rB!xgdm8d@iA(QGWT}I5W!s~< zv(Hive;-AnOA^T&3nN>FsE6yDOKuRR=2r!)^4!Vrg&@;;Pp6d0&ga`ViUgS7)9%wL zFL8Z&!4BrRa&{7JA5}N~H5$@H5E%#Pwb=Y+XFY7W>Qt>FZttwB*-0`+iF3TTcAu&&TxXwH;g2^_Df3hyr0bw&T zvc1#caZ3_sC&N~GnAn+d@Ni}otPq}1x3@A;XZ%Fr(NLqSDq%?$J|LuJghrf6T_LO! zrdG=4$|Kjqw58gkIFW7*wUSh4_Ebv4q^&5nTRHSb!dHyE``w}*vV32hb&6|I_;b1H zPH1Yt>{@uaADW-hee?eIyX|?nW7Bk{WQD3`tC8E2>AgJ1>&%=9V{?H7$920KqP7!> zJZ06{-z*y%AZ8WP-1VQTM7G-BCXHQ3jt~O8DFHpJ3uxMbYq2`u0+`WSXmU@Jp4PGn z(XxTq{mQt~^VY7z=-BqGr^}PVu%^OVIyZ%cM}W4~|EIRqIsfSCjfCX7=^8QKphggN zkQ=;YXUyD3Acx2Fi{ZnPXP4V&DIQ)@CDGIx9^0l&FG8*)Z1m&D>u2B0?-Ox8M@MX> zD|+q@ND@}$VI;_%$}QaWLD8bp#OIUfeMCaZGplTAt_Oqs2w? z8uH#eA-Hr)`$p8mtcM*Fk(A-Oa(l4g*G6p-Y+Wa}1+!$Ws|!Z0b4J?w?v49b*v}zt zw?7y+%sgUh{-C(I;Unqla-8X>3k=yt)**L7XW35 z3LS}R)-&U}{sXlNmgLSCPnuuymu+X&T~8yczf}%l@{SlrhG`bNJ?`8{^daZXdf3*M zTwwQHy7tgr(A0{31&pj2ZzpZrEll1bGgT=XRQE;@B#ov>Iu+my%}6(=)&XBq)fA+( zXjqc(++ho0SMe{hR&GY}nv_%3kG%4mkE}`WVab}? z69c_AvNB_bOn9BgXs3l&(HHlxJ6lVn7DpsCrghr73P;C_{jCZ^Bcpq+Y0MnDniOOR;Dp7`WNB;owV(liug=N_bI%COe%Ti+zlk(&g+6@U_x6{+&iB!`Iz|U)ocm<7nX-Om1z`d~Thj`xg^=_83-S@V$>#LW|pFgjKYKj3I zdhzdrciZr^=hB7GfJ<8C-rq&?%^d&@J!SugpuQ=Z4Hl-JqBnGkz*yANxsVHteUr7{ zZfd0-c)Fpv68keX{hhkQ!NW8$2BrubV}o7dYO?#VI1Oi7XG|0G=fzmrgET5i|9V+= zB8@6_=p4=2KmM+epFRo}Za*YS%7p{v3f}x3)d1my?0>uzz;6S8HguRc`;3 z=3D5WYbJm=Im4feB>+0I2mcBZ0e>X@f_iY6^YV)TbsDbyhtzM~y;-7sKluLvx2@en diff --git a/content/en/hosting/3.x/ec2-setup-guide.md b/content/en/hosting/3.x/ec2-setup-guide.md deleted file mode 100644 index e29731019b..0000000000 --- a/content/en/hosting/3.x/ec2-setup-guide.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: "AWS Hosting in CHT 3.x" -linkTitle: "Production Hosting - AWS" -weight: 1 -description: > - Hosting the CHT on Amazon EC2 -relatedContent: > - hosting/3.x/self-hosting -aliases: - - /apps/guides/hosting/3.x/ec2-setup-guide - - /apps/guides/hosting/ec2-setup-guide ---- - -{{< callout type="warning" >}} - CHT 3.x is [End-of-Life]({{< relref "releases/#supported-versions" >}}) and no longer supported. -{{< /callout >}} - -Most production CHT instances are deployed on AWS EC2. Leveraging Elastic Compute Cloud (EC2) and Elastic Block Store (EBS), CHT instances can easily be scaled up with larger EC2 instances and have easy increased disk space, backup and restores with EBS. - -This guide will walk you through the process of creating an EC2 instance, mounting an EBS volume and provisioning Docker containers. - -## Create and Configure EC2 Instance - -1. Create EC2 (use security best practices) - - Review the [CHT hardware requirements]({{< relref "hosting/requirements#hardware-requirements" >}}) and start with an appropriately sized instance. After creating the instance and downloading the `.pem` file, change permissions to `0600` for it: - - ```shell - sudo chmod 0600 ~/Downloads/name_of_file.pem - ``` - - Create an [Elastic IP (EIP) and associate the EIP to your EC2 instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html). - - You should now be able to SSH into the EC2 instance using the EIP and the `.pem` file. - - `Goal`: SSH into instance - - -1. Create or Restore EBS Volume - - - Create or [Restore](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ebs-restoring-volume.html) your EBS Volume, tagging appropriately, so it can be found later. - - Attach volume to EC2 instance - - [Increase disk size](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html) (Optional) - - If you are using a newly created EBS Volume, you will have to format the disk appropriately: - 1) SSH into instance - 2) Follow the instructions here: [Using EBS Volumes](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-using-volumes.html) - 3) Use `sudo mkfs -t ext4 ` in step 4 - 4) Mount disk to `/srv` - - `Goal`: Mount EBS volume to `/srv` - -1. Provision Docker server - - Follow README & Run scripts in [cht-infrastructure repository](https://github.com/medic/cht-infrastructure/tree/master/self-hosting/prepare-system). - - `Goal`: CHT Application bootstraps and comes online - -1. DNS configuration - - Point DNS `A` record to EIP given to Docker server in the prior step. - -1. Review SSL certificates - - Location of certs is `/srv/settings/medic-core/nginx/private/` - - Name the key file is `default.key` and the certificate file is `default.crt` - - See [SSL Certificates]({{< relref "hosting/3.x/ssl-cert-install">}}) to install new certificates - -1. Configure CHT Sync - See the [CHT Sync configuration]({{< relref "hosting/analytics">}}). - -1. Setup postgres to work with CHT Sync - - Creating the database, setting up permissions, exploring the tables and what they store - -1. Debugging CHT Sync/postgres - - Understanding the log and what the entries mean - -## Troubleshooting - -1. Restarting processes - ```shell - /boot/svc- - ``` - - Also see [MedicOS service management scripts](https://github.com/medic/medic-os#user-content-service-management-scripts) -2. Investigating logs inside Medic OS - * To view logs, first run this to access a shell in the medic-os container: `docker exec -it medic-os /bin/bash` - * View CouchDB logs: `less /srv/storage/medic-core/couchdb/logs/startup.log` - * View medic-api logs: `less /srv/storage/medic-api/logs/medic-api.log` - * View medic-sentinel logs: `less /srv/storage/medic-sentinel/logs/medic-sentinel.log` - -3. Investigating docker stderr/stdout logs - ```shell - sudo docker logs medic-os - sudo docker logs haproxy - ``` - -4. Upgrading the container - - Backup all data (EBS) - - Log into container and stop all services - - To prepare for the upgrade, delete all other files in `/srv` EXCEPT for `/srv/storage/medic-core/` - - The `medic-core` directory is where the CHT stores user data. Of key importance is `./couchdb/local.in` and `./medic-core/couchdb/local.d/` where custom CouchDB configuration is stored. - - Change the image tag to the final Medic OS image release version (`cht-3.9.0-rc.2`) in the docker compose file: - ```yaml - services: - medic-os: - image: medicmobile/medic-os:cht-3.9.0-rc.2 - ``` - - Launch new containers with appropriate `COUCHDB_ADMIN_PASSWORD` & `HA_PASSWORD` environment variables - -5. Upgrading the webapp - - Use Admin GUI page - - [CLI via horticulturalist]({{< ref "hosting/3.x/self-hosting#links-to-medic-documentation-for-horticulturalist-for-upgrades" >}}) - -6. RDS help - - - [Amazon user guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html) - -## Backups - -1. Configure backups - - [EBS Snapshot Lifecycle Manager](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snapshot-lifecycle.html) - -1. Restoring from backup - - Create volume from snapshot - - Tag appropriately for backups - - Mount volume to docker server - -## Process supervision -- `supvisorctl` -- `/boot/supervisor-inspect` - -## Increasing disk size - -Monitor disk usage so alerts are sent before all disk spaces is used up. If free disk space falls below 40%, increase the disk space as follows: - -* Stop medic: `sudo supervisorctl stop medic` -* Go to EBS in AWS and take a snapshot of the volume. -* Modify the volume size (Increase it by 2x preferably). Wait until the modification succeeds. -* [Make the instance recognize the additional space](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html) -* Turn medic back on: `sudo supervisorctl start medic` - -## Monitoring & Backup -* AWS CloudWatch and monitoring tab. Enable detailed monitoring (This costs more money) -* Set up [Lifecycle Management for EBS snapshots](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snapshot-lifecycle.html#snapshot-lifecycle-console) -* Steps to mounting a backup snapshot to the instance and restarting the application -* See the second-half of "Increasing disk size" reference above -* Setup a TLS cert & DNS registration diff --git a/content/en/hosting/3.x/offline.md b/content/en/hosting/3.x/offline.md deleted file mode 100644 index 7bc9b58daa..0000000000 --- a/content/en/hosting/3.x/offline.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "Offline Hosting of CHT 3.x Server" -linkTitle: "Offline Hosting" -weight: 5 -description: > - Deploy and host CHT Core server instances without Internet connectivity -aliases: - - /apps/guides/hosting/3.x/offline - - /apps/guides/hosting/offline ---- - -{{< callout type="warning" >}} - CHT 3.x is [End-of-Life]({{< relref "releases/#supported-versions" >}}) and no longer supported. -{{< /callout >}} - -{{< callout type="error" >}} - This guide is not meant for a production CHT instance. Support may be added in the future an offline CHT server in a production environment. See the "Considerations" section below. - Proceed only if you have staff familiar with DNS, TLS Certs, DHCP, LAN topology and Linux in general. This is a complex deployment where mistakes are easy to make unless proper training is in place. -{{< /callout >}} - -{{< callout >}} - This guide only applies to CHT 3.x. -{{< /callout >}} - -## Introduction - -The CHT is built as an [Offline-First]({{< ref "technical-overview/concepts/offline-first" >}}) application. This applies to clients, either browsers or Android applications, connecting to the CHT server. The server itself assumes it has Internet connectivity to provide services such as DNS, software updates and general use connectivity. This document explores what it looks like when the CHT server is offline without these services available. - -Running a CHT server offline requires no modifications to the CHT itself. Instead, supporting services normally found online are replicated locally. - -## Considerations - -An offline CHT server is most appropriate for a development environment. There are serious implications to consider before deploying an offline instance per our [existing requirements]({{< relref "requirements#considerations" >}}). - -Additionally, if users are going to migrate between offline locations with the same domain name, always ensure different login and passwords are used for all users across instances. This will prevent a client from another CHT instance trying to synchronize with a CHT instance it shouldn't synchronize with, possibly causing data corruption or privacy issues through unintended data access. - - -## Requirements - -A CHT instance is accessible offline when you can resolve the domain to an IP address, and a TLS certificate is on the CHT server with a common name (CN) that matches the domain name. On top of the [existing requirements]({{< relref "requirements" >}}), the following aspects must also be considered. - -### Static IP - -The CHT server needs to be given a static IP so that DNS will always resolve to the correct host. - -### TLS Certificate - -Browsers might allow you to connect to a server with an invalid TLS certificate after you [bypass the warning](https://www.ssl.com/guide/troubleshooting-ssl-tls-browser-errors-and-warnings/). Android apps however, like [CHT Android App](https://github.com/medic/cht-android), require a valid TLS certificate to work correctly, therefore you would need to acquire a valid TLS certificate from a certificate authority (CA) and install it on your CHT server. - -It is common to use [Let's Encrypt](https://en.wikipedia.org/wiki/Let%27s_encrypt) to acquire certificates because they provide free certificates. Let's Encrypt certificates expire after 90 days, so the server will need to be constantly updated with a new certificate. Other CAs provide certificates that expire after a year, so this concern will always apply. - -After acquiring the certificate, if you are running a Docker-based CHT deployment, see [TLS instructions for Docker]({{< relref "/hosting/3.x/ssl-cert-install" >}}) to install the certificate. - -### Domain Name Server - -In order to match the static IP of the web server to the CN in the certificate, a Domain Name Server (DNS) must be used. This will allow any client on the LAN to easily connect to your CHT server without needing anything more than the domain name. - -Most LANs will defer to the Internet Service Provider (ISP) to provide DNS, but there is no ISP in an offline scenario. Instead, one must be provided. This DNS server will then be configured to have an `A` record (or `AAAA` in the case of IPv6) to point to the CHT server. - -### Dynamic Host Configuration Protocol - -Any new client that connects to a network will get an IP address from a Dynamic Host Configuration Protocol (DHCP) server. It is critical that the DHCP server for the LAN the CHT is on instructs all clients to use the DNS server configured above. - - -### Wi-Fi AP - -A Wi-FI Access Point (AP) needs to be deployed on the LAN so Android devices can connect to the CHT. This can be an AP included with the router or a standalone AP. If the AP is standalone, check that any DHCP or DNS servers that could conflict with the one above are disabled. - -## Benefits Over Other Solutions - -An offline deployment may consider substituting some requirements above with these other solutions. Note that ngrok and local-ip.co require Internet connectivity, so are not an offline solution. - -### ngrok - -When an offline solution is deployed, traffic stays 100% local, whereas when using either [your own reverse proxy]({{< relref "building/guides/debugging/secure-sharing-of-developer-instance" >}}) or a third party provider like [ngrok](https://ngrok.com/), traffic may traverse 100s or 1,000s of kilometers to ultimately reach the CHT server which is 10 meters away. This can help when Internet connectivity is very slow, very expensive per megabyte, or both. - -### local-ip.co - -[local-ip.co](http://local-ip.co/), and [related services](https://local-ip.medicmobile.org/), offer both the TLS certificates and private keys for `*.my.local-ip.co`. Additionally, the service has a DNS server that dynamically maps any IP you pass in the sub-sub-domain to the real world IP such that `192-168-0-1.my.local-ip.co` would resolve to `192.168.0.1`. This can make it very handy to deploy a development instance where all HTTP traffic remains local (unlike `ngrok` above). - -As the DNS traffic still needs to leave your network and return, it is not a viable solution for a truly offline CHT deployment. - -### Self-Signed Certificates - -Another option to consider is to [self-sign the certificates](https://gist.github.com/fntlnz/cf14feb5a46b2eda428e000157447309) and then either bypass the warnings in browsers or install the new CA root certificate on your devices. While this may work for a development environment with a single developer, it will be hard to scale to an environment where you'd like to easily provision many Android devices. The work will be much more than just installing an APK form the Play Store (or the slightly harder side load process). - -This may only work on certain, older version of Android as well. - -### No DHCP or DNS Server - -To avoid installing both the DHCP and DNS servers, an Android app that enables custom DNS entries, like [DNS Changer](https://play.google.com/store/apps/details?id=com.burakgon.dnschanger) could be used. As [seen here](https://stackoverflow.com/questions/6370017/mapping-a-hostname-to-an-ip-address-on-android), on each Android device you could install this and add custom DNS entries to reach the TLS certificate on the CHT. - -Like the self-signed certificate solution, this is hard to scale and would need to be complimented by editing `/etc/hosts` files on desktop browsers. diff --git a/content/en/hosting/3.x/self-hosting.md b/content/en/hosting/3.x/self-hosting.md deleted file mode 100644 index d32af17a33..0000000000 --- a/content/en/hosting/3.x/self-hosting.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -title: "Production Hosting in CHT 3.x" -linkTitle: "Production Hosting - Docker" -weight: 2 -description: > - Hosting the CHT on self run infrastructure -relatedContent: > - hosting/3.x/ec2-setup-guide -aliases: - - /apps/guides/hosting/3.x/self-hosting - - /apps/guides/hosting/self-hosting - - /technical-overview/docker-setup ---- - -{{< callout type="warning" >}} - CHT 3.x is [End-of-Life]({{< relref "releases/#supported-versions" >}}) and no longer supported. -{{< /callout >}} - - -Whether run on bare-metal or in a cloud provider, the Community Health Toolkit (CHT) core framework has been packaged into a docker container to make it portable and easy to install. It is available from [dockerhub](https://hub.docker.com/r/medicmobile/medic-os). To learn more how to work with docker you could follow the tutorial [here](https://docker-curriculum.com/#getting-started) and the cheat sheet [here](https://docs.docker.com/get-started/docker_cheatsheet.pdf). - -{{< callout type="warning" >}} - Before continuing, ensure all [requirements]({{< relref "hosting/requirements" >}}) are met. -{{< /callout >}} - -## Installing with a compose file - -The CHT containers are installed using [docker compose](https://docs.docker.com/compose/) so that you can run multiple containers as a single service. - -Start by choosing the location where you would like to save your compose configuration file. Then create the `docker-compose.yml` file by `cd`ing into the correct directory and running: - -```bash -curl -s -o docker-compose.yml https://raw.githubusercontent.com/medic/cht-core/master/scripts/docker-helper/docker-compose-developer-3.x-only.yml -``` - - -The install requires an admin password that it will configure in the database. You need to provide this externally as an environment variable. Before you run the compose file, you need to export this variable as shown below. - -`export DOCKER_COUCHDB_ADMIN_PASSWORD=myAwesomeCHTAdminPassword` - -You can then run `docker compose` in the folder where you put your compose `docker-compose.yml` file. To start, run it interactively to see all the logs on screen and be able to stop the containers with `ctrl` + `c`: - -```bash -sudo docker compose up -``` - -If there are no errors, stop the containers with `ctrl` + `c` and then run it detached with `-d`: - -```bash -sudo docker compose up -d -``` - -Note In certain shells, `docker compose` may not interpolate the admin password that was exported in `DOCKER_COUCHDB_ADMIN_PASSWORD`. Check if this is the case by searching the logs in the medic-os dockers instance. If the `docker logs medic-os` command below returns a user and password, then the export above failed, and you should use this user and password to complete the installation: - -```bash -docker logs medic-os |grep 'New CouchDB Admin' -Info: New CouchDB Administrative User: medic -Info: New CouchDB Administrative Password: password -``` - -Monitor the logs until you get the `Setting up software (100% complete)` message. At this stage all containers are fully set up. - -Once containers are setup, run the following command from your host terminal: - -```bash -sudo docker exec -it medic-os /bin/bash -c "sed -i 's/--install=3.9.0/--complete-install/g' /srv/scripts/horticulturalist/postrun/horticulturalist" -sudo docker exec -it medic-os /bin/bash -c "/boot/svc-disable medic-core openssh && /boot/svc-disable medic-rdbms && /boot/svc-disable medic-couch2pg" -``` - -The first command fixes a postrun script for horticulturalist to prevent unique scenarios of re-install. The second command removes extra services that you will not need. - -### Visit your project - -If you're running this on your local machine, then open a browser to [https://localhost](https://localhost). Otherwise open a browser to the public IP of the host if it's running remotely. - -You will have to click to through the SSL Security warning. Click "Advanced" -> "Continue to site". - - -### Clean up and re-install - -If some instructions were missed and there's a broken CHT deployment, use the commands below to start afresh: - -1. Stop containers: `docker stop medic-os && docker stop haproxy` -1. Remove containers: `docker rm medic-os && docker rm haproxy` -1. Clean data volume:`docker volume rm medic-data` - - Note: Running `docker compose down -v` would do all the above 3 steps -1. Prune system: `docker system prune` - -After following the above commands, you can re-run `docker compose` up and create a clean install: `docker compose up -d` - -### Port Conflicts - -In case you are already running services on HTTP(80) and HTTPS(443),you will have to either remap ports to the medic-os container or stop the services using those ports. - -To find out which service is using a conflicting port: On Linux: - -`sudo netstat -plnt | grep ':'` - -On Mac (10.10 and above): - -`sudo lsof -iTCP -sTCP:LISTEN -n -P | grep ':'` - -You can either kill the service which is occupying HTTP/HTTPS ports, or run the container with forwarded ports that are free. In your compose file, change the ports under medic-os: - -```yaml -services: - medic-os: - container_name: medic-os - image: medicmobile/medic-os:cht-3.7.0-rc.1 - volumes: - - medic-data:/srv - ports: - - 8080:80 - - 444:443 -``` - -Turn off and remove all existing containers that were started: - - `sudo docker compose down` - -Bring Up the containers in detached mode with the new forwarded ports. - - `sudo docker compose up -d` - -Note: You can substitute 8080, 444 with whichever ports are free on your host. You would now visit https://localhost:444 to visit your project. - -## Data storage & persistence - -{{< callout type="warning" >}} - Containers that are already set up will lose all data when following the steps below to remap the `/srv` directory. -{{< /callout >}} - -Docker containers are [stateless](https://www.redhat.com/en/topics/cloud-native-apps/stateful-vs-stateless) by design. In order to persist your data when a container restarts you need to specify the volumes that the container can use to store data. The CHT app stores all its data in the `/srv` folder. This is the folder that you need to map to your volume before you spin up your containers. - -Ideally you should map this folder to a volume that is backed up regularly by your cloud hosting provider. - -The example below shows how to map this folder in Ubuntu: - -1. Create the `/srv` folder: `sudo mkdir /srv` -1. Mount your volume to this folder: `sudo mount /dev/xvdg /srv` . The attached volume number varies. Find your volume by running `lsblk`. -1. Update your compose file so that the containers store data to this folder - - ```yaml - services: - medic-os: - container_name: medic-os - image: medicmobile/medic-os:cht-3.9.0-rc.2 - volumes: - - /srv:/srv - - ---- - haproxy: - container_name: haproxy - image: medicmobile/haproxy:rc-1.17 - volumes: - - /srv:/srv - ``` - -Alternatively, can create the `/srv` folder on any drive with enough space that is regularly backed up. Then map the path to the folder in the compose file like this. - -```yaml -volumes: - - /path/to/srv:/srv -``` - -Be sure to check the available storage space regularly and expand your volume when needed - -## Backup - -Regular backups should be made of the `/srv` directory to have holistic and easy to restore copies of all important data and the current CHT version installed. To backup just the data and not the CHT, make copies of `/srv/storage/medic-core/`. This directory includes 4 key sub-directies: - -{{< filetree/container >}} - {{< filetree/folder name="srv" >}} - {{< filetree/folder name="couchdb" >}} - {{< /filetree/folder >}} - {{< filetree/folder name="openssh" >}} - {{< /filetree/folder >}} - {{< filetree/folder name="nginx" >}} - {{< /filetree/folder >}} - {{< filetree/folder name="passwd" >}} - {{< /filetree/folder >}} - {{< /filetree/folder >}} -{{< /filetree/container >}} - -To make backups of just CouchDB data outside of the CHT docker infrastructure, see [CouchDB's Backup docs for 2.3.1](https://web.archive.org/web/20220527070753/https://docs.couchdb.org/en/2.3.1/maintenance/backups.html). Note: -* CouchDB data files are in `/srv/storage/medic-core/couchdb/data` in the `medic-os` container. -* Backing up via replication is discouraged as restored DBs can cause offline users to restart replication from zero. Use file backups instead. diff --git a/content/en/hosting/3.x/ssl-cert-install.md b/content/en/hosting/3.x/ssl-cert-install.md deleted file mode 100644 index e5ca3ec3b8..0000000000 --- a/content/en/hosting/3.x/ssl-cert-install.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "SSL Cert Install in CHT 3.x" -linkTitle: "SSL Cert Install" -weight: 4 -description: > - SSL Cert Installation for Self-Hosting Setups using Medic OS/3.x -relatedContent: > - hosting/3.x/self-hosting -aliases: - - /apps/guides/hosting/3.x/ssl-cert-install - - /apps/guides/hosting/ssl-cert-install ---- - -{{< callout type="warning" >}} - CHT 3.x is [End-of-Life]({{< relref "releases/#supported-versions" >}}) and no longer supported. -{{< /callout >}} - - -## Requirements -- Installed CHT-Core 3.x via either [Self Hosted]({{< relref "hosting/3.x/self-hosting" >}}), [EC2]({{< relref "hosting/3.x/ec2-setup-guide" >}}) or [Local Setup]({{< relref "building/local-setup" >}}), but must use `docker compose`. -- Your own SSL certifications like Let's Encrypt. - -## Copy certs into medic-os container - -On your server copy the `.crt` and `.key` files to the `medic-os` container. The existing self signed `.crt` and `.key` files will be overwritten: - -```bash -sudo docker cp /path/to/ssl.crt medic-os:/srv/settings/medic-core/nginx/private/default.crt -sudo docker cp /path/to/ssl.key medic-os:/srv/settings/medic-core/nginx/private/default.key -``` - -## Restart services - -Now that the `.crt` and `.key` files are in place, restart `nginx` in the `medic-os` container with: - -```bash -docker exec -it medic-os /boot/svc-restart medic-core nginx -``` - -## View Nginx Logs - -To troubleshoot any problems with the new certificates, after running `docker exec -it medic-os bash`, the `nginx` log files can be found in `/srv/storage/medic-core/nginx/logs/`, including: -* access.log -* error-ssl.log -* error.log -* startup.log diff --git a/content/en/hosting/4.x/_index.md b/content/en/hosting/4.x/_index.md deleted file mode 100644 index 5fdd2d8b1e..0000000000 --- a/content/en/hosting/4.x/_index.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: 4.x -weight: 6 -description: > - Guides for hosting CHT 4.x applications -relatedContent: > - building/guides/updates/preparing-for-4/ -aliases: - - /apps/guides/hosting/4.x ---- - -> [!TIP] -> To get an overview on how these hosting solutions use `docker` and other key CHT concepts, be sure to read the [guide on a Local Setup]({{< relref "building/local-setup" >}}). - -Before beginning any of these guides, be sure to meet all of the [CHT hosting requirements]({{< relref "hosting/requirements" >}}) first. For example, [backups](/hosting/4.x/docker/backups) are required for any successful CHT deployment. - -To host a production instance of CHT, use the [Production Hosting in CHT 4.x]({{< relref "hosting/4.x/docker" >}}) guide. To do app development, see our [App Developer]({{< relref "hosting/4.x/app-developer" >}}) hosting guide. - -To view 3.x hosting options, see the [3.x hosting section]({{< relref "hosting/3.x" >}}). - -{{< cards >}} - {{< card link="app-developer" title="App Developer Hosting" subtitle="Learn how to host the CHT when developing apps" icon="server" >}} - {{< card link="migration/" title="Migration Guides" icon="arrow-circle-right" subtitle="Guides for migrating CHT applications" >}} - {{< card link="/hosting/4.x/docker/" title="Production Docker" subtitle="Details for hosting the CHT on Docker" icon="docker" >}} - {{< card link="/hosting/4.x/kubernetes/" title="Production Kubernetes" subtitle="Details for hosting the CHT on Kubernetes" icon="kubernetes" >}} - {{< card link="upgrade-troubleshooting" title="Troubleshooting upgrades" subtitle="What to do when CHT 4.x upgrades don't work as planned" icon="search-circle" >}} -{{< /cards >}} diff --git a/content/en/hosting/4.x/docker/_index.md b/content/en/hosting/4.x/docker/_index.md deleted file mode 100644 index 681274f0bb..0000000000 --- a/content/en/hosting/4.x/docker/_index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: "Docker Production Hosting CHT 4.x" -linkTitle: "Production Docker" -weight: 15 -description: "Production hosting CHT 4.x in Docker on a single CouchDB node" -aliases: ---- - -{{< callout >}} -Read the [Docker vs Kubernetes]({{< relref "/hosting/kubernetes-vs-docker/" >}}) documentation to select a style of hosting that best fits your CHT deployment. -{{< /callout >}} - -{{< cards >}} -{{< card link="/hosting/4.x/docker/installation" title="Installation" subtitle="Installing the CHT on Docker" icon="docker" >}} -{{< card link="/hosting/4.x/docker/adding-tls-certificates" title="Adding TLS Certificates" subtitle="Ensuring all traffic is encrypted" icon="key" >}} -{{< card link="/hosting/4.x/docker/logs" title="Logs" subtitle="How to view logs" icon="code" >}} -{{< card link="/hosting/4.x/docker/backups" title="Backups" subtitle="Backing up your production data" icon="server" >}} -{{< /cards >}} diff --git a/content/en/hosting/4.x/kubernetes/_index.md b/content/en/hosting/4.x/kubernetes/_index.md deleted file mode 100644 index 8fabe708fa..0000000000 --- a/content/en/hosting/4.x/kubernetes/_index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: "Kubernetes Production Hosting in CHT 4.x" -linkTitle: "Production Kubernetes" -description: "Production hosting the CHT with Kubernetes" -weight: 20 ---- - -{{< callout >}} -Read the [Docker vs Kubernetes]({{< relref "/hosting/kubernetes-vs-docker/" >}}) documentation to select a style of hosting that best fits your CHT deployment. -{{< /callout >}} - -{{< subpages >}} - diff --git a/content/en/hosting/SSO/entra.md b/content/en/hosting/SSO/entra.md index f82a666ec5..7c1e8b9eaf 100644 --- a/content/en/hosting/SSO/entra.md +++ b/content/en/hosting/SSO/entra.md @@ -16,7 +16,7 @@ These steps document how to configure Microsoft Entra as the Single Sign On (SSO ## Prerequisites * [Microsoft Entra](https://entra.microsoft.com) business account with credit card added. Free trial accounts work, but require a credit card. -* CHT server - ensure you are running version `4.20.0` or later. This can be an instance of [Docker Helper](/hosting/4.x/app-developer/#cht-docker-helper-for-4x). +* CHT server - ensure you are running version `4.20.0` or later. This can be an instance of [Docker Helper](/hosting/cht/app-developer/#cht-docker-helper-for-4x). * DNS Entries and TLS enabled on CHT diff --git a/content/en/hosting/SSO/keycloak.md b/content/en/hosting/SSO/keycloak.md index c0c574deee..2b6c78efdd 100644 --- a/content/en/hosting/SSO/keycloak.md +++ b/content/en/hosting/SSO/keycloak.md @@ -53,7 +53,7 @@ docker compose up -d The Keycloak instance is accessible on your Docker Helper URL, but on port `8443`. For example `https://192-168-68-26.local-ip.medicmobile.org:8443`. The username is `medic` and the password is `password`. -Now create an instance of [Docker Helper](/hosting/4.x/app-developer/#cht-docker-helper-for-4x). +Now create an instance of [Docker Helper](/hosting/cht/app-developer/#cht-docker-helper-for-4x). {{< /tab >}} {{< /tabs >}} diff --git a/content/en/hosting/SSO/technical.md b/content/en/hosting/SSO/technical.md index dec4f211f6..4195e1bebf 100644 --- a/content/en/hosting/SSO/technical.md +++ b/content/en/hosting/SSO/technical.md @@ -12,7 +12,7 @@ CHT `4.20.0` introduced the single sign on (SSO) feature allowing deployments to ## Setup -Follow the [setup steps]({{< ref "hosting/sso" >}}) to [configure your CHT instance]({{< ref "building/reference/app-settings/oidc_provider" >}}) for SSO Login. Once the server has been properly configured, the "Login with SSO" button will be visible on the CHT Login page. CHT users with the [`oidc_username` property]({{< ref "building/reference/api/#login-by-oidc" >}}) will be able to log in with their SSO credentials. The "SSO Email Address" field will be also be visible in the create/update users modal in the [App Management interface]({{< ref "building/admin/admin-overview" >}}). +Follow the [setup steps]({{< ref "/hosting/sso" >}}) to [configure your CHT instance]({{< ref "building/reference/app-settings/oidc_provider" >}}) for SSO Login. Once the server has been properly configured, the "Login with SSO" button will be visible on the CHT Login page. CHT users with the [`oidc_username` property]({{< ref "building/reference/api/#login-by-oidc" >}}) will be able to log in with their SSO credentials. The "SSO Email Address" field will be also be visible in the create/update users modal in the [App Management interface]({{< ref "building/admin/admin-overview" >}}). ## User Mapping diff --git a/content/en/hosting/_index.md b/content/en/hosting/_index.md index 153d3cb8a7..63e6ab4204 100644 --- a/content/en/hosting/_index.md +++ b/content/en/hosting/_index.md @@ -10,24 +10,15 @@ aliases: This section has instructions on how to host the CHT Core starting with the most basic Application Development setup on your laptop for just one developer all the way up to large deployments which include multi-node CouchDB cluster hosted in a Cloud based deployment. -{{< callout type="warning" >}} - All CHT 3.x deployments have been end of life since November 2023 and are not longer supported. They are [documented]({{< relref "hosting/3.x" >}}) to support deployments that are yet to upgrade to 4.x. -{{< /callout >}} +New developers to the CHT should start with the [Application Developer Hosting]({{< relref "/hosting/cht/app-developer" >}}). -New developers to the CHT should start on CHT 4.x with the [Application Developer Hosting]({{< relref "hosting/4.x/app-developer" >}}). - -System administrators looking to deploy CHT into production should understand [the requirements to host the CHT]({{< relref "/hosting/requirements/" >}}) first, then read the [Docker or Kubernetes]({{< relref "/hosting/kubernetes-vs-docker/" >}}) to select a style of hosting that best fits them. +System administrators looking to deploy CHT into production should understand [the requirements to host the CHT]({{< relref "/hosting/cht/requirements/" >}}) first, then read the [Docker or Kubernetes]({{< relref "/hosting/cht/kubernetes-vs-docker/" >}}) to select a style of hosting that best fits them. {{< cards >}} - {{< card link="considerations" title="Considerations" subtitle="Considerations when hosting the CHT" icon="book-open" >}} - {{< card link="requirements" title="Requirements" icon="shield-exclamation" subtitle="Requirements for hosting CHT applications" >}} - {{< card link="costs" title="Costs" subtitle="A guide for calculating CHT hosting costs" icon="banknotes" >}} - {{< card link="kubernetes-vs-docker" title="Kubernetes vs Docker" icon="kubernetes" subtitle="Options for installing CHT applications" >}} - {{< card link="4.x/" title="4.x" icon="template" subtitle="Guides for hosting CHT 4.x applications" >}} - {{< card link="3.x/" title="3.x" icon="archive" subtitle="Guides for hosting CHT 3.x applications" tag="archive" tagType="error">}} - {{< card link="monitoring/" title="Monitoring & Alerting" subtitle="Using CHT Watchdog to Monitor and Alert on CHT 3.x and 4.x Applications" icon="bell" >}} - {{< card link="analytics/" title="Data Synchronization & Analytics" subtitle="Using CHT Sync for data synchronization and analytics" icon="chart-pie" >}} - {{< card link="sso" title="SSO" subtitle="Setting up Single Sign On" icon="key" >}} + {{< card link="cht/" title="CHT Core" icon="template" subtitle="Guides for hosting CHT applications" >}} + {{< card link="monitoring/" title="Monitoring & Alerting" subtitle="Using CHT Watchdog to Monitor and Alert on CHT Applications" icon="bell" >}} + {{< card link="analytics/" title="Data Synchronization & Analytics" subtitle="Using CHT Sync for data synchronization and analytics" icon="chart-pie" >}} {{< card link="couch2pg/" title="couch2pg" subtitle="Guides for using couch2pg" icon="presentation-chart-line" tag="deprecated" tagType="warning" >}} + {{< card link="sso" title="SSO" subtitle="Setting up Single Sign On" icon="key" >}} {{< card link="medic" title="At Medic" subtitle="Guidelines internal to Medic-hosted CHT instances " icon="briefcase" tag="medic-internal" >}} {{< /cards >}} diff --git a/content/en/hosting/analytics/_index.md b/content/en/hosting/analytics/_index.md index c0bafaa617..9115742dc2 100644 --- a/content/en/hosting/analytics/_index.md +++ b/content/en/hosting/analytics/_index.md @@ -14,12 +14,8 @@ aliases: - /building/guides/data/analytics/introduction --- -{{< callout >}} - The pages in this section apply to both CHT 3.x (beyond 3.12) and CHT 4.x. -{{< /callout >}} - Most CHT deployments require some sort of analytics so that stakeholders can make data driven decisions. CouchDB, which is the database used by the CHT, is not designed for analytics. It is a document database, which means that it is optimized for storing and retrieving documents, and not for aggregating data. For example, if you wanted to know how many patients were registered in a particular area, you would have to query the database for all the patients in that area, and then count them. This is not a very efficient process. It is much more efficient to store the number of patients in a particular area in a separate database, and update that number whenever a patient is registered or unregistered. This is what CHT Sync is designed to do. -[CHT Sync]({{< relref "technical-overview/architecture/cht-sync" >}}) is an integrated solution designed to enable data synchronization between CouchDB and PostgreSQL for the purpose of analytics. It has been designed to work in both local development environments for testing models or workflows, and in production environments. It can be deployed using [Docker or Kubernetes]({{< relref "hosting/kubernetes-vs-docker" >}}). It is supported on CHT 3.12 and later, including CHT 4.x. By using CHT Sync, a CHT deployment can easily get analytics by using a [data visualization tool]({{< relref "hosting/analytics/dashboards" >}}), such as [Superset](https://superset.apache.org/). CHT Sync is open-source and has no licensing fees. +[CHT Sync]({{< relref "technical-overview/architecture/cht-sync" >}}) is an integrated solution designed to enable data synchronization between CouchDB and PostgreSQL for the purpose of analytics. It has been designed to work in both local development environments for testing models or workflows, and in production environments. It can be deployed using [Docker or Kubernetes]({{< relref "/hosting/cht/kubernetes-vs-docker" >}}). It is supported on CHT 3.12 and later, including CHT 4.x. By using CHT Sync, a CHT deployment can easily get analytics by using a [data visualization tool]({{< relref "/hosting/analytics/dashboards" >}}), such as [Superset](https://superset.apache.org/). CHT Sync is open-source and has no licensing fees. {{< subpages >}} diff --git a/content/en/hosting/analytics/building-dbt-models.md b/content/en/hosting/analytics/building-dbt-models.md index 237492614f..af205242c7 100644 --- a/content/en/hosting/analytics/building-dbt-models.md +++ b/content/en/hosting/analytics/building-dbt-models.md @@ -25,7 +25,7 @@ If using the [configurable contact hierarchy]({{< ref "building/reference/app-se ## Prerequisites -- An existing install of CHT Sync via [Docker]({{< relref "hosting/analytics/setup-docker-compose" >}}) or [Kubernetes]({{< relref "hosting/analytics/setup-kubernetes" >}}) +- An existing install of CHT Sync via [Docker]({{< relref "/hosting/analytics/setup-docker-compose" >}}) or [Kubernetes]({{< relref "/hosting/analytics/setup-kubernetes" >}}) - [cht-pipeline](https://github.com/medic/cht-pipeline) GitHub repository (can be cloned via `git clone https://github.com/medic/cht-pipeline`). ## Setup @@ -39,14 +39,14 @@ packages: ``` To avoid breaking changes in downstream models, include `revision` in the dependency, which should be a version tag for `cht-pipeline`. -In the CHT Sync config, set the URL of the dbt GitHub repository to the `CHT_PIPELINE_BRANCH_URL` [environment variable]({{< relref "hosting/analytics/environment-variables" >}}), either in `.env` if using Docker compose, or in `values.yaml` if using Kubernetes. +In the CHT Sync config, set the URL of the dbt GitHub repository to the `CHT_PIPELINE_BRANCH_URL` [environment variable]({{< relref "/hosting/analytics/environment-variables" >}}), either in `.env` if using Docker compose, or in `values.yaml` if using Kubernetes. > [!IMPORTANT] > If `CHT_PIPELINE_BRANCH_URL` is pointing to a private GitHub repository, you'll need an access token in the URL. Assuming your repository is `medic/cht-pipeline`, you would replace `` with an access token: `https://@github.com/medic/cht-pipeline.git#main`. See [GitHub's instructions](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) on how to generate a token. If you create a fine-grained access token you need to provide read and write access to the [contents](https://docs.github.com/en/rest/authentication/permissions-required-for-fine-grained-personal-access-tokens?apiVersion=2022-11-28#repository-permissions-for-contents) of the repository. ### Local development -When creating/modifying models, you can use the Docker [local profile]({{< relref "hosting/analytics/setup-docker-compose#local" >}}) to run a local test instance of CHT Sync that can reference your model configuration directly on your local machine (without needing to commit/push the changes remotely). +When creating/modifying models, you can use the Docker [local profile]({{< relref "/hosting/analytics/setup-docker-compose#local" >}}) to run a local test instance of CHT Sync that can reference your model configuration directly on your local machine (without needing to commit/push the changes remotely). ### Deploying models @@ -64,7 +64,7 @@ When it is necessary to update the base models, update the version tag in the de ### Testing models and dashboards -It is highly encouraged to write [dbt tests]({{< ref "hosting/analytics/testing-dbt-models" >}}) for application-specific models to ensure that they are accurate and to avoid releasing broken models. Examples can be found in the [cht-pipeline repository](https://github.com/medic/cht-pipeline/tree/main/tests). +It is highly encouraged to write [dbt tests]({{< ref "/hosting/analytics/testing-dbt-models" >}}) for application-specific models to ensure that they are accurate and to avoid releasing broken models. Examples can be found in the [cht-pipeline repository](https://github.com/medic/cht-pipeline/tree/main/tests). ## Base Models @@ -395,7 +395,7 @@ Examples of changes that are not considered breaking: - 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: +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 SELECT pg_size_pretty(pg_database_size('your_database_name')); ``` @@ -410,7 +410,7 @@ To get the percentage of documents that have synced you can run the following qu SELECT (COUNT(*) * 100 / (COUNT(*) + (SELECT SUM(pending) FROM v1.couchdb_progress))) AS sync_percentage FROM v1.couchdb; ``` -This query selects the total number of documents that have been synced to the `v1.couchdb` table and divides it by the total number of documents that have been synced and the number of documents that are pending to be synced. This will give you the percentage of documents that have been synced. Note that the schema and table name could differ according to the [environment variables]({{< relref "hosting/analytics/environment-variables" >}}) you set so update them accordingly. Run this query periodically to monitor the progress of the sync and stop the sync process once you get to the desired percentage. It's okay if it is not exactly 10% as long as it is close enough to give you an idea of the disk space required. +This query selects the total number of documents that have been synced to the `v1.couchdb` table and divides it by the total number of documents that have been synced and the number of documents that are pending to be synced. This will give you the percentage of documents that have been synced. Note that the schema and table name could differ according to the [environment variables]({{< relref "/hosting/analytics/environment-variables" >}}) you set so update them accordingly. Run this query periodically to monitor the progress of the sync and stop the sync process once you get to the desired percentage. It's okay if it is not exactly 10% as long as it is close enough to give you an idea of the disk space required. You can then multiply this figure by 10 to get an estimate of the disk space required for the full dataset and then add some extra space for indexes and other overhead as well as future growth. diff --git a/content/en/hosting/analytics/couch2pg-to-cht-sync-migration.md b/content/en/hosting/analytics/couch2pg-to-cht-sync-migration.md index 4b37c74cc9..ea3d70d3ce 100644 --- a/content/en/hosting/analytics/couch2pg-to-cht-sync-migration.md +++ b/content/en/hosting/analytics/couch2pg-to-cht-sync-migration.md @@ -12,22 +12,22 @@ aliases: - /building/guides/data/analytics/couch2pg-to-cht-sync-migration --- -This page outlines guidelines for migrating from [couch2pg](https://github.com/medic/cht-couch2pg) to the data pipeline based on [CHT Sync](https://github.com/medic/cht-sync). One of the main changes in this flow is separating the syncing process from the data transformation, with dbt now handling the latter in [cht-pipeline](https://github.com/medic/cht-pipeline/). This migration requires dbt models in the cht-pipeline repository instead of SQL views and tables. One thing to note is that the schema for CHT Sync differs from cht-couch2pg, so dbt models will not directly replace the SQL views and tables. For instructions on how to get started with dbt models, refer to the [dbt models guide]({{< relref "hosting/analytics/testing-dbt-models" >}}). +This page outlines guidelines for migrating from [couch2pg](https://github.com/medic/cht-couch2pg) to the data pipeline based on [CHT Sync](https://github.com/medic/cht-sync). One of the main changes in this flow is separating the syncing process from the data transformation, with dbt now handling the latter in [cht-pipeline](https://github.com/medic/cht-pipeline/). This migration requires dbt models in the cht-pipeline repository instead of SQL views and tables. One thing to note is that the schema for CHT Sync differs from cht-couch2pg, so dbt models will not directly replace the SQL views and tables. For instructions on how to get started with dbt models, refer to the [dbt models guide]({{< relref "/hosting/analytics/testing-dbt-models" >}}). ## Key Considerations -- **Kubernetes vs Docker Compose**: CHT Sync provides configurations to support deployment to test and production environments with Docker Compose or Kubernetes. You can read more about the CHT hosting options in the [dedicated page]({{< relref "hosting/kubernetes-vs-docker" >}}). -- **Server resources**: To minimize downtime, running both couch2pg and CHT Sync in parallel during the migration process is recommended. With this in mind, ensure that the server and [database resources]({{< relref "hosting/analytics/building-dbt-models#database-disk-space-requirements" >}}) are sufficient to handle the load. +- **Kubernetes vs Docker Compose**: CHT Sync provides configurations to support deployment to test and production environments with Docker Compose or Kubernetes. You can read more about the CHT hosting options in the [dedicated page]({{< relref "/hosting/cht/kubernetes-vs-docker" >}}). +- **Server resources**: To minimize downtime, running both couch2pg and CHT Sync in parallel during the migration process is recommended. With this in mind, ensure that the server and [database resources]({{< relref "/hosting/analytics/building-dbt-models#database-disk-space-requirements" >}}) are sufficient to handle the load. - **dbt modelling**: Avoid the temptation to model new dbt models after existing SQL views and tables. Instead, take the opportunity to re-evaluate the data needs and design new models that are more efficient and effective. Think of what data needs to be shown and how it should be shown in data visualization tools and use that to guide the design of the new models. -- **Testing**: After migrating, thoroughly test the new dbt models to ensure that they work as expected. Refer to the [testing dbt models guide]({{< relref "hosting/analytics/building-dbt-models" >}}) for guidelines on testing. +- **Testing**: After migrating, thoroughly test the new dbt models to ensure that they work as expected. Refer to the [testing dbt models guide]({{< relref "/hosting/analytics/building-dbt-models" >}}) for guidelines on testing. - **Feedback**: Provide any feedback and create issues for errors or bugs encountered in the [cht-sync](https://github.com/medic/cht-sync) and [cht-pipeline](https://github.com/medic/cht-pipeline/) repositories to improve the tools. ## Migration Steps 1. **Plan the migration**: Determine the scope of the migration, including the data sources, the data models, and the data transformations. Identify the existing SQL views, tables, and dashboards and assess what data you want to visualize. -1. **Set up CHT Sync**: Follow the instructions to setup CHT Sync with [Docker Compose]({{< relref "hosting/analytics/setup-docker-compose" >}}) or [Kubernetes]({{< relref "hosting/analytics/setup-kubernetes" >}}) -1. **Build dbt models**: Use the [dedicated guidelines]({{< relref "hosting/analytics/building-dbt-models" >}}) to build dbt models for the data you want to visualize. +1. **Set up CHT Sync**: Follow the instructions to setup CHT Sync with [Docker Compose]({{< relref "/hosting/analytics/setup-docker-compose" >}}) or [Kubernetes]({{< relref "/hosting/analytics/setup-kubernetes" >}}) +1. **Build dbt models**: Use the [dedicated guidelines]({{< relref "/hosting/analytics/building-dbt-models" >}}) to build dbt models for the data you want to visualize. 1. **Deploy CHT Sync**: Once the dbt models are tested locally or in a test environment and working as expected, deploy CHT Sync in a production environment. It is recommended that CHT Sync be run in parallel with couch2pg during the migration process. This minimises disruption to users of the existing dashboards because they can continue to use the existing data while the new pipeline is being set up. It also makes it easier to compare the data from couch2pg when testing the new pipeline. 1. **Create replica dashboards**: In the data visualization tool of your choice, create replica dashboards of your current setup and compare the data from the old and new pipelines. 1. **Test and adjust the dbt models**: Test the dbt models to ensure they are working as expected and that the replica and initial dashboards match. Adjust the models to ensure they are accurate. -1. **Optimize**: Once the dbt models are working as expected and the dashboards display the expected data, optimize the models to improve performance. This may involve restructuring the models, adding indexes, or making other adjustments to improve the speed and efficiency of the models. Having a look at the [dbt models guide]({{< relref "hosting/analytics/building-dbt-models" >}}) will help you understand how to optimize the models. -1. **Set up monitoring and alerting**: [Set up CHT Watchdog]({{< relref "hosting/monitoring/setup" >}}) to monitor the running of CHT Sync and set up alerts for any failures. +1. **Optimize**: Once the dbt models are working as expected and the dashboards display the expected data, optimize the models to improve performance. This may involve restructuring the models, adding indexes, or making other adjustments to improve the speed and efficiency of the models. Having a look at the [dbt models guide]({{< relref "/hosting/analytics/building-dbt-models" >}}) will help you understand how to optimize the models. +1. **Set up monitoring and alerting**: [Set up CHT Watchdog]({{< relref "/hosting/monitoring/setup" >}}) to monitor the running of CHT Sync and set up alerts for any failures. 1. **Remove couch2pg and the duplicate database**: Once the new pipeline runs as expected, you can remove couch2pg and the duplicate database. Ensure that all data is being synced correctly, that the dbt models are working as expected, and that the dashboards display the expected data before switching them off and removing couch2pg. diff --git a/content/en/hosting/analytics/dashboards.md b/content/en/hosting/analytics/dashboards.md index 4e2f1058fe..1e63e53201 100644 --- a/content/en/hosting/analytics/dashboards.md +++ b/content/en/hosting/analytics/dashboards.md @@ -10,7 +10,7 @@ relatedContent: > --- {{< callout >}} - These instructions assume you are running CHT Sync, CHT Core and PostgreSQL either with [Kubernetes]({{< relref "hosting/analytics/setup-kubernetes" >}}) or [Docker]({{< relref "hosting/analytics/setup-docker-compose" >}}). + These instructions assume you are running CHT Sync, CHT Core and PostgreSQL either with [Kubernetes]({{< relref "/hosting/analytics/setup-kubernetes" >}}) or [Docker]({{< relref "/hosting/analytics/setup-docker-compose" >}}). {{< /callout >}} ## Superset diff --git a/content/en/hosting/analytics/environment-variables.md b/content/en/hosting/analytics/environment-variables.md index 29c9db0edc..ca5972b481 100644 --- a/content/en/hosting/analytics/environment-variables.md +++ b/content/en/hosting/analytics/environment-variables.md @@ -32,8 +32,8 @@ There are three groups of environment variables. One for Postgres, one for Couch | `COUCHDB_HOST` | `couchdb` | Host of the CouchDB instance | | `COUCHDB_PORT` | `5984` | Port of the CouchDB instance | | `COUCHDB_SECURE` | `false` | Does the connection to CouchDB use HTTPS? | -| `DBT_THREAD_COUNT` | 1 | [Number of threads]({{< relref "hosting/analytics/tuning-dbt#threads" >}}) per DBT process | -| `DBT_BATCH_SIZE` | 0 | [Batch size]({{< relref "hosting/analytics/tuning-dbt#batching" >}}) for batched incremental runs | +| `DBT_THREAD_COUNT` | 1 | [Number of threads]({{< relref "/hosting/analytics/tuning-dbt#threads" >}}) per DBT process | +| `DBT_BATCH_SIZE` | 0 | [Batch size]({{< relref "/hosting/analytics/tuning-dbt#batching" >}}) for batched incremental runs | | `DBT_LOCAL_PATH` | | When running DBT locally for development, the path to the models directory on the host | -| `DBT_SELECTOR` | '' | If using separate DBT processes, the [select condition]({{< relref "hosting/analytics/tuning-dbt#multiple-dbt-containers" >}}) to select a subset of the models for a single dbt process. | +| `DBT_SELECTOR` | '' | If using separate DBT processes, the [select condition]({{< relref "/hosting/analytics/tuning-dbt#multiple-dbt-containers" >}}) to select a subset of the models for a single dbt process. | diff --git a/content/en/hosting/analytics/setup-docker-compose.md b/content/en/hosting/analytics/setup-docker-compose.md index 8836ced05b..c8e51259d4 100644 --- a/content/en/hosting/analytics/setup-docker-compose.md +++ b/content/en/hosting/analytics/setup-docker-compose.md @@ -12,20 +12,20 @@ aliases: - /building/guides/data/analytics/setup --- -This guide will walk you through setting up a deployment of CHT Sync with the CHT using Docker. This path is recommended if you host the [CHT with Docker]({{< relref "hosting/4.x/docker" >}}). +This guide will walk you through setting up a deployment of CHT Sync with the CHT using Docker. This path is recommended if you host the [CHT with Docker]({{< relref "/hosting/cht/docker" >}}). ## Prerequisites - [Current version](https://docs.docker.com/engine/install/) of `docker` or current version of [Docker Desktop](https://www.docker.com/products/docker-desktop/) both of which include `docker compose`. Note that the older `docker-compose` is [no longer supported](https://www.docker.com/blog/announcing-compose-v2-general-availability/). - [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) - [cht-sync](https://github.com/medic/cht-sync) GitHub repository (can be cloned via `git clone https://github.com/medic/cht-sync`). -- [A dbt project]({{< relref "hosting/analytics/building-dbt-models" >}}). +- [A dbt project]({{< relref "/hosting/analytics/building-dbt-models" >}}). ## Setup -In the `cht-sync` folder, copy the values from the `env.template` file to a `.env` file. For more information, see the references on the [Environment variables page]({{< relref "hosting/analytics/environment-variables" >}}). +In the `cht-sync` folder, copy the values from the `env.template` file to a `.env` file. For more information, see the references on the [Environment variables page]({{< relref "/hosting/analytics/environment-variables" >}}). -Configure the `COUCHDB_*` environment variables to connect to your CouchDB instance. For production CHT Core deployments, the port will most likely need to be set to `443` like this: `COUCHDB_PORT=443`. This is because CHT Core uses an `nginx` [reverse proxy]({{< relref "technical-overview/architecture#overview" >}}) on port `443`, instead of the default `5984` port used in a stand-alone CouchDB instance which the `env.template` [has]({{< relref "hosting/analytics/environment-variables" >}}). +Configure the `COUCHDB_*` environment variables to connect to your CouchDB instance. For production CHT Core deployments, the port will most likely need to be set to `443` like this: `COUCHDB_PORT=443`. This is because CHT Core uses an `nginx` [reverse proxy]({{< relref "technical-overview/architecture#overview" >}}) on port `443`, instead of the default `5984` port used in a stand-alone CouchDB instance which the `env.template` [has]({{< relref "/hosting/analytics/environment-variables" >}}). > [!IMPORTANT] > The first time you run the commands from any of the sections below it will need to download many Docker images and will take a while. You'll know it's done when you see `#8 DONE 0.0s` and you are returned to the command line. Be patient! @@ -43,7 +43,7 @@ The following profiles are available: This setup involves starting couch2pg, PostgreSQL, pgAdmin and dbt. It assumes you have a CouchDB instance running, and you updated the `.env` CouchDB variables accordingly. -The dbt container needs a project to run. To develop and test models locally, [set up a dbt project]({{< relref "hosting/analytics/building-dbt-models#setup" >}}) and set the path to the project to the `DBT_LOCAL_PATH` [environment variable]({{< relref "hosting/analytics/environment-variables" >}}) in `.env`. You must set this to a valid directory where you have your CHT Pipeline models. You can not use `--local` profile without setting this. +The dbt container needs a project to run. To develop and test models locally, [set up a dbt project]({{< relref "/hosting/analytics/building-dbt-models#setup" >}}) and set the path to the project to the `DBT_LOCAL_PATH` [environment variable]({{< relref "/hosting/analytics/environment-variables" >}}) in `.env`. You must set this to a valid directory where you have your CHT Pipeline models. You can not use `--local` profile without setting this. When running, the dbt container then will use the local models in the path specified in `DBT_LOCAL_PATH` with out needing to query a remote git repository. @@ -68,7 +68,7 @@ The dbt container will run the models in the path specified in `DBT_LOCAL_PATH`. #### Production -This setup involves starting couch2pg and one dbt container. It assumes you have an external CouchDB instance and Postgres DB. The credentials and settings for these databases are configured in [.env]({{< relref "hosting/analytics/environment-variables" >}}). +This setup involves starting couch2pg and one dbt container. It assumes you have an external CouchDB instance and Postgres DB. The credentials and settings for these databases are configured in [.env]({{< relref "/hosting/analytics/environment-variables" >}}). Run the Docker containers with profile `production` and wait for every container to be up and running: ```sh @@ -79,7 +79,7 @@ You can verify this command worked by running `docker ps`. It should show three ### Tuning dbt -In production setups with large tables, it can be helpful to [tune how dbt runs]({{< relref "hosting/analytics/tuning-dbt" >}}). +In production setups with large tables, it can be helpful to [tune how dbt runs]({{< relref "/hosting/analytics/tuning-dbt" >}}). To use threads or batching, set the corresponding environment variables in `.env`. ```conf @@ -178,4 +178,4 @@ To add these columns log in to the database and run this sql. In V2, the commands for running CHT sync have changed; a profile is required as described above. When testinging locally and using the `local` profile, the environment variable `DBT_LOCAL_PATH` must be set. -V2 adds new features for [tuning dbt]({{< relref "hosting/analytics/tuning-dbt" >}}); to use batching, threads, or separate dbt processes, set the corresponding [environment_variables]({{< relref "hosting/analytics/environment-variables" >}}) in `.env` as described above. +V2 adds new features for [tuning dbt]({{< relref "/hosting/analytics/tuning-dbt" >}}); to use batching, threads, or separate dbt processes, set the corresponding [environment_variables]({{< relref "/hosting/analytics/environment-variables" >}}) in `.env` as described above. diff --git a/content/en/hosting/analytics/setup-kubernetes.md b/content/en/hosting/analytics/setup-kubernetes.md index 5ffe980eea..80e2d7e3f1 100644 --- a/content/en/hosting/analytics/setup-kubernetes.md +++ b/content/en/hosting/analytics/setup-kubernetes.md @@ -12,7 +12,7 @@ aliases: - /building/guides/data/analytics/production --- -This guide will walk you through setting up a deployment of CHT Sync with the CHT using Kubernetes. This path is recommended if you already have a Kubernetes cluster [hosting the CHT]({{< relref "hosting/4.x/kubernetes" >}}). +This guide will walk you through setting up a deployment of CHT Sync with the CHT using Kubernetes. This path is recommended if you already have a Kubernetes cluster [hosting the CHT]({{< relref "/hosting/cht/kubernetes" >}}). ## Prerequisites @@ -87,13 +87,13 @@ If an instance has a different port, user or different CouchDB databases to be s password: "password3" ``` -Set the [cht-pipeline branch URL]({{< relref "hosting/analytics/building-dbt-models#setup" >}}) in the `values.yaml` file. +Set the [cht-pipeline branch URL]({{< relref "/hosting/analytics/building-dbt-models#setup" >}}) in the `values.yaml` file. ```yaml cht_pipeline_branch_url: "https://github.com/medic/cht-pipeline.git#main" ``` -(Optional) You can also configure a Metrics Exporter. If enabled, this will create a sql exporter that queries the database for couch2pg status, number of changes pending, and current sequence and exposes these metrics in Prometheus format at a service with name `metrics` at port 9399, for use with [CHT Watchdog]({{< relref "hosting/monitoring/setup" >}}) or any other monitoring service. +(Optional) You can also configure a Metrics Exporter. If enabled, this will create a sql exporter that queries the database for couch2pg status, number of changes pending, and current sequence and exposes these metrics in Prometheus format at a service with name `metrics` at port 9399, for use with [CHT Watchdog]({{< relref "/hosting/monitoring/setup" >}}) or any other monitoring service. An HTTP ingress needs to be created to allow access from outside the cluster. @@ -126,7 +126,7 @@ kubectl logs -f cht-sync- ### Tuning dbt -In production setups with large tables, it can be helpful to [tune how dbt runs]({{< relref "hosting/analytics/tuning-dbt" >}}). +In production setups with large tables, it can be helpful to [tune how dbt runs]({{< relref "/hosting/analytics/tuning-dbt" >}}). To use threads or batching, set the corresponding values in the `values.yaml` file. ```yaml @@ -168,4 +168,4 @@ To add these columns log in to the database and run this sql. CREATE INDEX IF NOT EXISTS source ON couchdb(source); ``` -V2 adds new features for [tuning dbt]({{< relref "hosting/analytics/tuning-dbt" >}}); to use batching, threads, or separate dbt processes, set the corresponding [environment_variables]({{< relref "hosting/analytics/environment-variables" >}}) in `values.yml` as described above. +V2 adds new features for [tuning dbt]({{< relref "/hosting/analytics/tuning-dbt" >}}); to use batching, threads, or separate dbt processes, set the corresponding [environment_variables]({{< relref "/hosting/analytics/environment-variables" >}}) in `values.yml` as described above. diff --git a/content/en/hosting/analytics/tuning-dbt.md b/content/en/hosting/analytics/tuning-dbt.md index 84f64053e0..be8a775741 100644 --- a/content/en/hosting/analytics/tuning-dbt.md +++ b/content/en/hosting/analytics/tuning-dbt.md @@ -39,10 +39,10 @@ Each dbt container is passed an environment variable `DBT_SELECTOR` that is used One dbt container should be set up to run the base models. This can be done by using the selector `package:cht_pipeline_base` or, to separate telemetry models from base models, use `tag:base` and `tag:users`. -To run custom models in separate containers, either use a package select with your dbt package name (`package:[YOUR_PACKAGE_NAME]`), or for more fine-grained control, add [tags]({{< relref "hosting/analytics/tuning-dbt#dbt-tags" >}}) to your models and use tag selectors (`tag:[YOUR_TAG]`). +To run custom models in separate containers, either use a package select with your dbt package name (`package:[YOUR_PACKAGE_NAME]`), or for more fine-grained control, add [tags]({{< relref "/hosting/analytics/tuning-dbt#dbt-tags" >}}) to your models and use tag selectors (`tag:[YOUR_TAG]`). Although it is possible to use any condition, using tags is the simplest way to separate models. -How to configure the different dbt containers to use these selectors depends on whether CHT Sync is running in [docker-compose]({{< relref "hosting/analytics/setup-docker-compose#tuning-dbt" >}}) or [kubernetes]({{< relref "hosting/analytics/setup-kubernetes#tuning-dbt" >}}). +How to configure the different dbt containers to use these selectors depends on whether CHT Sync is running in [docker-compose]({{< relref "/hosting/analytics/setup-docker-compose#tuning-dbt" >}}) or [kubernetes]({{< relref "/hosting/analytics/setup-kubernetes#tuning-dbt" >}}). In Kubernetes, add the selectors to the `values.yaml` file as a list called `dbt_selectors` ```yaml diff --git a/content/en/hosting/cht/_index.md b/content/en/hosting/cht/_index.md new file mode 100644 index 0000000000..609ac5d5fa --- /dev/null +++ b/content/en/hosting/cht/_index.md @@ -0,0 +1,38 @@ +--- +title: CHT Core +weight: 6 +description: > + Guides for hosting CHT applications +relatedContent: > + building/guides/updates/preparing-for-4/ +aliases: + - /apps/guides/hosting/4.x + - /hosting/4.x/ +--- + +> [!TIP] +> To get an overview on how these hosting solutions use `docker` and other key CHT concepts, be sure to read the [guide on a Local Setup]({{< relref "building/local-setup" >}}). + +Before beginning any of these guides, be sure to meet all of the [CHT hosting requirements]({{< relref "/hosting/cht/requirements" >}}) first. For example, [backups](/hosting/cht/docker/backups) are required for any successful CHT deployment. + +To host a production instance of CHT, use the [Production Hosting in CHT]({{< relref "/hosting/cht/docker" >}}) guide. To do app development, see our [App Developer]({{< relref "/hosting/cht/app-developer" >}}) hosting guide. + +{{< cards >}} + {{< card link="considerations" title="Considerations" subtitle="Considerations when hosting the CHT" icon="book-open" >}} + {{< card link="requirements" title="Requirements" icon="shield-exclamation" subtitle="Requirements for hosting CHT applications" >}} + {{< card link="costs" title="Costs" subtitle="A guide for calculating CHT hosting costs" icon="banknotes" >}} + {{< card link="kubernetes-vs-docker" title="Kubernetes vs Docker" icon="kubernetes" subtitle="Options for installing CHT applications" >}} + {{< card link="app-developer" title="App Developer Hosting" subtitle="Learn how to host the CHT when developing apps" icon="server" >}} + {{< card link="migration/" title="Migration Guides" icon="arrow-circle-right" subtitle="Guides for migrating CHT applications" >}} + {{< card link="/hosting/cht/docker/" title="Production Docker" subtitle="Details for hosting the CHT on Docker" icon="docker" >}} + {{< card link="/hosting/cht/kubernetes/" title="Production Kubernetes" subtitle="Details for hosting the CHT on Kubernetes" icon="kubernetes" >}} + {{< card link="upgrade-troubleshooting" title="Troubleshooting upgrades" subtitle="What to do when CHT upgrades don't work as planned" icon="search-circle" >}} +{{< /cards >}} + +{{< callout emoji="🔍" >}} +All of the above documentation applies to CHT 4.x and CHT 5.x. + +Looking CHT 3.x hosting information? This content [has been removed](https://forum.communityhealthtoolkit.org/t/proposal-remove-cht-3-x-hosting-documentation/5133), but is still available on the [Old Docs site](https://old-docs.dev.medicmobile.org/hosting/3.x/). + +In the coming year (2026), this old docs site will be removed as well. +{{< /callout >}} diff --git a/content/en/hosting/4.x/app-developer.md b/content/en/hosting/cht/app-developer.md similarity index 95% rename from content/en/hosting/4.x/app-developer.md rename to content/en/hosting/cht/app-developer.md index 1dbeb659a7..23134c849a 100644 --- a/content/en/hosting/4.x/app-developer.md +++ b/content/en/hosting/cht/app-developer.md @@ -1,28 +1,26 @@ --- -title: "App Developer Hosting in CHT 4.x" -linkTitle: "App Developer Hosting" +title: "App Developer" +linkTitle: "App Developer" weight: 10 description: > Host the CHT when developing apps aliases: - - /apps/guides/hosting/4.x/app-developer + - /apps/guides/hosting/cht/app-developer - /apps/guides/hosting/app-developer + - /hosting/4.x/app-developer/ --- {{< callout >}} This guide assumes you are a CHT app developer wanting to either run concurrent instances of the CHT, or easily be able to switch between different instances without losing any data while doing so. To do development on the CHT Core Framework itself, see the [development guide]({{< relref "community/contributing/code/core/dev-environment" >}}). -To deploy the CHT 3.x in production, see either [AWS hosting]({{< relref "hosting/3.x/ec2-setup-guide.md" >}}) or [Self hosting]({{< relref "hosting/3.x/self-hosting.md" >}}). To deploy 4.x in production see the [4.x documentation]({{< relref "hosting/4.x/docker" >}}). +To deploy the CHT in production, see see the [production]({{< relref "/hosting/cht/docker" >}}) documentation. {{< /callout >}} ## Getting started First, decide which way to run the CHT: Docker Helper or manually it via `docker compose`. Since they both achieve the same result, **it is recommended to use Docker Helper** as shown in the next section as it's very easy to run. Alternately, the manual process is covered at the [bottom of the page](#manual-docker-compose-method). -## CHT Docker Helper for 4.x - -> [!IMPORTANT] -> This section is for CHT 4.x. To use a CHT 3.x version, see the earlier [CHT Docker Helper page]({{< relref "hosting/3.x/app-developer#cht-docker-helper" >}}). +## CHT Docker Helper The `cht-docker-compose.sh` scripts downloads 3 compose files and builds an `.env` file. This greatly eases starting your first CHT instance with a simple text based GUI which works on Windows (WSL2), macOS (both x86 and Apple Silicon) and Linux. @@ -40,7 +38,7 @@ This script brings a lot of benefits with it: ### Installing To get started using it: -1. Meet all [CHT hosting requirements]({{< relref "hosting/requirements" >}}) +1. Meet all [CHT hosting requirements]({{< relref "/hosting/cht/requirements" >}}) 2. Clone the [CHT Core](https://github.com/medic/cht-core/) repo 3. When you want to check for updates, just run `git pull origin` in the `cht-core` directory. @@ -99,7 +97,7 @@ Stop and keep project: Stop and destroy all project data: ./cht-docker-compose.sh ENV-FILE.env destroy -https://docs.communityhealthtoolkit.org/apps/guides/hosting/4.x/app-developer/ +https://docs.communityhealthtoolkit.org/apps/guides/hosting/cht/app-developer/ Have a great day! @@ -197,7 +195,7 @@ Here is a video of the helper being run on 1 Dec 2022. The video references `laz ## Manual `docker compose` method -This process achieves the same result as Docker Helper, but is a more manual process. Be sure the [CHT hosting requirements]({{< relref "hosting/requirements" >}}) are all met first. +This process achieves the same result as Docker Helper, but is a more manual process. Be sure the [CHT hosting requirements]({{< relref "/hosting/cht/requirements" >}}) are all met first. To avoid conflicts, ensure that all other CHT 4.x instances are stopped. To stop ALL containers, you can use diff --git a/content/en/hosting/4.x/app-developer/cht-docker-helper.png b/content/en/hosting/cht/app-developer/cht-docker-helper.png similarity index 100% rename from content/en/hosting/4.x/app-developer/cht-docker-helper.png rename to content/en/hosting/cht/app-developer/cht-docker-helper.png diff --git a/content/en/hosting/considerations.md b/content/en/hosting/cht/considerations.md similarity index 85% rename from content/en/hosting/considerations.md rename to content/en/hosting/cht/considerations.md index 35a3bcbf69..f2e4522dda 100644 --- a/content/en/hosting/considerations.md +++ b/content/en/hosting/cht/considerations.md @@ -6,12 +6,13 @@ dscription: > Considerations when hosting the CHT aliases: - /apps/guides/hosting/ + - /hosting/considerations/ --- Some important questions to consider when setting up hosting for the CHT: -* **Alerting** - How will alerts be sent in the case of downtime or degraded service? While [Watchdog]({{< relref "hosting/monitoring/introduction" >}}) can be set up to monitor CHT Core instances - which monitoring system will be used to alert on OS level warnings? +* **Alerting** - How will alerts be sent in the case of downtime or degraded service? While [Watchdog]({{< relref "/hosting/monitoring/introduction" >}}) can be set up to monitor CHT Core instances - which monitoring system will be used to alert on OS level warnings? * **Power failures and unplanned restarts** - Will the server cleanly restart such that the CHT resumes service correctly? -* **Backups** - What happens to the CHT data if there's a hard drive failure? Are there provisions for a [3-2-1 backup strategy](https://en.wikipedia.org/wiki/Backup#Storage)? See the [backup docs]({{< relref "hosting/4.x/docker/backups" >}}) for more information. +* **Backups** - What happens to the CHT data if there's a hard drive failure? Are there provisions for a [3-2-1 backup strategy](https://en.wikipedia.org/wiki/Backup#Storage)? See the [backup docs]({{< relref "/hosting/cht/docker/backups" >}}) for more information. * **Disaster Recovery** - What happens if there is a flood at the facility and on-site active and backup data are destroyed? * **Scale** - What happens when the hardware deployed needs to be upgraded to increase capacity? * **Updates** - CHT Core updates happen many times throughout the year - do you have a maintenance schedule for these and staff who are trained to do the upgrade? diff --git a/content/en/hosting/costs.md b/content/en/hosting/cht/costs.md similarity index 99% rename from content/en/hosting/costs.md rename to content/en/hosting/cht/costs.md index 1b769b4699..ebb26986ef 100644 --- a/content/en/hosting/costs.md +++ b/content/en/hosting/cht/costs.md @@ -5,7 +5,7 @@ weight: 3 description: > A guide for calculating CHT hosting costs aliases: - - hosting/costs/ + - /hosting/costs/ --- ## Cost per CHT per Month @@ -60,7 +60,7 @@ A production deployment means the CHT is hosted either at a cloud provider or in When analyzing the hosting total cost of ownership (TCO), only production instances were looked at. > [!NOTE] -> A [development environment](/hosting/4.x/app-developer) can be no cost (or very low cost). Assuming a developer already has a laptop, this is all that is needed to host a development instance. +> A [development environment](/hosting/cht/app-developer) can be no cost (or very low cost). Assuming a developer already has a laptop, this is all that is needed to host a development instance. ## Small deployment example costs diff --git a/content/en/hosting/cht/docker/_index.md b/content/en/hosting/cht/docker/_index.md new file mode 100644 index 0000000000..1e526ad020 --- /dev/null +++ b/content/en/hosting/cht/docker/_index.md @@ -0,0 +1,19 @@ +--- +title: "Docker Production Hosting CHT" +linkTitle: "Production Docker" +weight: 15 +description: "Production hosting CHT in Docker on a single CouchDB node" +aliases: + - /hosting/4.x/docker/ +--- + +{{< callout >}} +Read the [Docker vs Kubernetes]({{< relref "/hosting/cht/kubernetes-vs-docker/" >}}) documentation to select a style of hosting that best fits your CHT deployment. +{{< /callout >}} + +{{< cards >}} +{{< card link="/hosting/cht/docker/installation" title="Installation" subtitle="Installing the CHT on Docker" icon="docker" >}} +{{< card link="/hosting/cht/docker/adding-tls-certificates" title="Adding TLS Certificates" subtitle="Ensuring all traffic is encrypted" icon="key" >}} +{{< card link="/hosting/cht/docker/logs" title="Logs" subtitle="How to view logs" icon="code" >}} +{{< card link="/hosting/cht/docker/backups" title="Backups" subtitle="Backing up your production data" icon="server" >}} +{{< /cards >}} diff --git a/content/en/hosting/4.x/docker/adding-tls-certificates.md b/content/en/hosting/cht/docker/adding-tls-certificates.md similarity index 89% rename from content/en/hosting/4.x/docker/adding-tls-certificates.md rename to content/en/hosting/cht/docker/adding-tls-certificates.md index 1bae221158..6100f2dd2c 100644 --- a/content/en/hosting/4.x/docker/adding-tls-certificates.md +++ b/content/en/hosting/cht/docker/adding-tls-certificates.md @@ -1,18 +1,19 @@ --- -title: "Adding TLS certificates in CHT 4.x" +title: "Adding TLS certificates in CHT" linkTitle: "TLS Certificates" weight: 2 description: > - How to add TLS certificates to a Docker hosted CHT 4.x instance + How to add TLS certificates to a Docker hosted CHT instance aliases: - - /apps/guides/hosting/4.x/adding-tls-certificates - - /hosting/4.x/adding-tls-certificates - - /hosting/4.x/production/docker/adding-tls-certificates/ + - /apps/guides/hosting/cht/adding-tls-certificates + - /hosting/cht/adding-tls-certificates + - /hosting/cht/production/docker/adding-tls-certificates/ + - /hosting/4.x/docker/adding-tls-certificates/ --- -By default, CHT 4.x will create a self-signed certificate for every deployment. These instructions are for changing to either a pre-existing certificate or automatically creating and renewing a [Certbot](https://certbot.eff.org/) based certificate using [ACME](https://acmeclients.com/), like [Let's Encrypt](https://letsencrypt.org/). +By default, CHT will create a self-signed certificate for every deployment. These instructions are for changing to either a pre-existing certificate or automatically creating and renewing a [Certbot](https://certbot.eff.org/) based certificate using [ACME](https://acmeclients.com/), like [Let's Encrypt](https://letsencrypt.org/). -This guide assumes you've already met the [hosting requirements]({{< relref "hosting/requirements" >}}), specifically around Docker being installed. +This guide assumes you've already met the [hosting requirements]({{< relref "/hosting/cht/requirements" >}}), specifically around Docker being installed. ## Pre-existing certificate diff --git a/content/en/hosting/4.x/docker/backups.md b/content/en/hosting/cht/docker/backups.md similarity index 91% rename from content/en/hosting/4.x/docker/backups.md rename to content/en/hosting/cht/docker/backups.md index 1fd92ecbb7..f97a5ba8e0 100644 --- a/content/en/hosting/4.x/docker/backups.md +++ b/content/en/hosting/cht/docker/backups.md @@ -1,19 +1,16 @@ --- -title: "Backups in CHT 4.x" +title: "Backups in CHT" linkTitle: "Backups" weight: 4 description: > - Which data to backup when hosting the CHT 4.x + Which data to backup when hosting the CHT aliases: - - /apps/guides/hosting/4.x/backups - - /hosting/4.x/backups - - /hosting/4.x/production/docker/backups/ + - /apps/guides/hosting/cht/backups + - /hosting/cht/backups + - /hosting/cht/production/docker/backups/ + - /hosting/4.x/docker/backups/ --- -{{< callout >}} - This guide is about backups in CHT 4.x - there's the [self hosted guide for 3.x]({{< relref "hosting/3.x/self-hosting#backup" >}}) which includes backups for 3.x. -{{< /callout >}} - ## Introduction As CHT 4.x uses a container per service, the only data that needs to be backed up is: @@ -38,7 +35,7 @@ Therefore, you do **not** need to back up the docker images for: ## Assumptions -This guide assumes you have an Ubuntu server running CHT 4.x in Docker as described in our [Self Hosting in CHT 4.x - Single CouchDB Node]({{< relref "hosting/4.x/docker" >}}) guide. If you run `docker ps --format '{{.Names}}'` you should see something like this: +This guide assumes you have an Ubuntu server running CHT 4.x in Docker as described in our [Self Hosting in CHT 4.x - Single CouchDB Node]({{< relref "/hosting/cht/docker" >}}) guide. If you run `docker ps --format '{{.Names}}'` you should see something like this: ``` cht_nginx_1 diff --git a/content/en/hosting/4.x/docker/installation.md b/content/en/hosting/cht/docker/installation.md similarity index 92% rename from content/en/hosting/4.x/docker/installation.md rename to content/en/hosting/cht/docker/installation.md index 845baeaa58..ea151641be 100644 --- a/content/en/hosting/4.x/docker/installation.md +++ b/content/en/hosting/cht/docker/installation.md @@ -5,18 +5,19 @@ weight: 1 description: > Prerequisites for hosting CHT with Docker aliases: - - /apps/guides/hosting/4.x/docker/ - - /hosting/4.x/docker/prerequisites/ - - /apps/guides/hosting/4.x/self-hosting/single-node/ - - /hosting/4.x/self-hosting/single-node/ + - /apps/guides/hosting/cht/docker/ + - /hosting/cht/docker/prerequisites/ + - /apps/guides/hosting/cht/self-hosting/single-node/ + - /hosting/cht/self-hosting/single-node/ - ../self-hosting-single-node - - /hosting/4.x/docker/single-node/ - - /hosting/4.x/production/docker/ + - /hosting/cht/docker/single-node/ + - /hosting/cht/production/docker/ + - /hosting/4.x/docker/installation/ --- ## Prerequisites -Be sure you have followed [the requirements document]({{< relref "hosting/requirements" >}}) including installing Docker. This guide assumes you're using the `ubuntu` user and that it [has `sudo-less` access to Docker](https://askubuntu.com/a/477554). +Be sure you have followed [the requirements document]({{< relref "/hosting/cht/requirements" >}}) including installing Docker. This guide assumes you're using the `ubuntu` user and that it [has `sudo-less` access to Docker](https://askubuntu.com/a/477554). ## Directory Structure @@ -88,7 +89,7 @@ Note that secure passwords and UUIDs were generated on the first four calls and ## Launch containers > [!IMPORTANT] -> This section has the first use of `docker compose`. If you get an error calling this, double check [hosting requirements]({{< relref "hosting/requirements" >}}). +> This section has the first use of `docker compose`. If you get an error calling this, double check [hosting requirements]({{< relref "/hosting/cht/requirements" >}}). To start your CHT instance, run the following @@ -137,7 +138,7 @@ grep COUCHDB_PASSWORD /home/ubuntu/cht/upgrade-service/.env | cut -d'=' -f2 ## TLS Certificates -See the [TLS Certificates page]({{< relref "hosting/4.x/docker/adding-tls-certificates" >}}) for how to import your certificates. +See the [TLS Certificates page]({{< relref "/hosting/cht/docker/adding-tls-certificates" >}}) for how to import your certificates. ## Upgrades diff --git a/content/en/hosting/4.x/docker/logs.md b/content/en/hosting/cht/docker/logs.md similarity index 94% rename from content/en/hosting/4.x/docker/logs.md rename to content/en/hosting/cht/docker/logs.md index e1261a45e3..7e0d2f5f65 100644 --- a/content/en/hosting/4.x/docker/logs.md +++ b/content/en/hosting/cht/docker/logs.md @@ -1,19 +1,20 @@ --- -title: "Viewing server logs in CHT 4.x" +title: "Viewing server logs in CHT" linkTitle: "Logs" weight: 3 description: > - What to do when you need to find server side errors in CHT 4.x + What to do when you need to find server side errors in CHT relatedContent: > building/guides/debugging/sharing-4x-logs building/guides/debugging/obtaining-logs aliases: - - /apps/guides/hosting/4.x/logs - - /hosting/4.x/logs - - /hosting/4.x/production/docker/logs/ + - /apps/guides/hosting/cht/logs + - /hosting/cht/logs + - /hosting/cht/production/docker/logs/ + - /hosting/4.x/docker/logs/ --- -CHT 4.x has the following services running via Docker and each can have its logs queried: +CHT has the following services running via Docker and each can have its logs queried: * nginx * sentinel diff --git a/content/en/hosting/kubernetes-vs-docker.md b/content/en/hosting/cht/kubernetes-vs-docker.md similarity index 94% rename from content/en/hosting/kubernetes-vs-docker.md rename to content/en/hosting/cht/kubernetes-vs-docker.md index 7c6b77eaef..f60ad47c0b 100644 --- a/content/en/hosting/kubernetes-vs-docker.md +++ b/content/en/hosting/cht/kubernetes-vs-docker.md @@ -6,18 +6,19 @@ description: > Options for installing CHT applications aliases: - /hosting/vertical-vs-horizontal + - /hosting/kubernetes-vs-docker --- To deploy the CHT, you should use the technology you are most familiar and comfortable with. It is possible to deploy 20 CHT instances without using Kubernetes. Conversely, if a hosting organisation uses Kubernetes and intends to deploy a single instance of the CHT, that's also fine. > [!TIP] -> Application development for both [CHT 3.x]({{< relref "hosting/3.x/app-developer" >}}) and [CHT 4.x]({{< relref "hosting/4.x/app-developer" >}}) is more straightforward to setup with Docker. +> [Application development]({{< relref "/hosting/cht/app-developer" >}}) is more straightforward to setup with Docker. ## Which one to choose? There is no one-size-fits-all solution for all deployments, and every solution comes with its advantages and disadvantages. -[Docker](/hosting/4.x/docker/) is suitable for most CHT deployments use cases. Use [Kubernetes](/hosting/4.x/kubernetes/) for multi-tenant or specific hardware constrained deployments, such as bare-metal servers with a low core-count. +[Docker](/hosting/cht/docker/) is suitable for most CHT deployments use cases. Use [Kubernetes](/hosting/cht/kubernetes/) for multi-tenant or specific hardware constrained deployments, such as bare-metal servers with a low core-count. For more details on the research behind why Docker and single-node CouchDB are preferable for CHT deployments, see [this forum post](https://forum.communityhealthtoolkit.org/t/investigate-adding-more-shards-as-a-potential-avenue-for-improved-performance/4831?u=mrjones). Results from this experiment show no clear advantage for CouchDB clustering, as the performance for view indexing and replication is the same when using a CouchDB cluster vs using a single machine with the same number of cores. @@ -70,7 +71,7 @@ Below are examples from real world large-scale CHT deployments which have been a ### CHT Deployment Example 1 -This deployment hosts 47 production instances in a data center running [Docker](/hosting/4.x/docker/). It trades ease and simplicity of Docker Compose deployment for a bit of fragility: if a VM fails, there is no automatic failover, and a restore from backup is needed. +This deployment hosts 47 production instances in a data center running [Docker](/hosting/cht/docker/). It trades ease and simplicity of Docker Compose deployment for a bit of fragility: if a VM fails, there is no automatic failover, and a restore from backup is needed. | | | |------------------:|:---------------------------| diff --git a/content/en/hosting/cht/kubernetes/_index.md b/content/en/hosting/cht/kubernetes/_index.md new file mode 100644 index 0000000000..d1f3dd704f --- /dev/null +++ b/content/en/hosting/cht/kubernetes/_index.md @@ -0,0 +1,15 @@ +--- +title: "Kubernetes Production Hosting in CHT" +linkTitle: "Production Kubernetes" +description: "Production hosting the CHT with Kubernetes" +weight: 20 +aliases: + - /hosting/4.x/kubernetes/ +--- + +{{< callout >}} +Read the [Docker vs Kubernetes]({{< relref "/hosting/cht/kubernetes-vs-docker/" >}}) documentation to select a style of hosting that best fits your CHT deployment. +{{< /callout >}} + +{{< subpages >}} + diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode.md b/content/en/hosting/cht/kubernetes/gcp-multinode.md similarity index 99% rename from content/en/hosting/4.x/kubernetes/gcp-multinode.md rename to content/en/hosting/cht/kubernetes/gcp-multinode.md index 61c6616a9a..c202acc0b6 100644 --- a/content/en/hosting/4.x/kubernetes/gcp-multinode.md +++ b/content/en/hosting/cht/kubernetes/gcp-multinode.md @@ -1,12 +1,13 @@ --- -title: "Production Hosting CHT 4.x - Google Cloud Platform" +title: "Production Hosting CHT - Google Cloud Platform" linkTitle: "GCP + GKS Multi Node" weight: 10 description: > - How to deploy the CHT 4.x on Google Cloud Platform + How to deploy the CHT on Google Cloud Platform aliases: - - /hosting/4.x/docker/google-cloud/ - - /hosting/4.x/production/kubernetes/gcp-multinode/ + - /hosting/cht/docker/google-cloud/ + - /hosting/cht/production/kubernetes/gcp-multinode/ + - /hosting/4.x/kubernetes/gcp-multinode/ --- ## Audience diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/add_people_to_project.png b/content/en/hosting/cht/kubernetes/gcp-multinode/add_people_to_project.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/add_people_to_project.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/add_people_to_project.png diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/add_user_details.png b/content/en/hosting/cht/kubernetes/gcp-multinode/add_user_details.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/add_user_details.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/add_user_details.png diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/cluster_networking_options.png b/content/en/hosting/cht/kubernetes/gcp-multinode/cluster_networking_options.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/cluster_networking_options.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/cluster_networking_options.png diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/gke_connect_command.png b/content/en/hosting/cht/kubernetes/gcp-multinode/gke_connect_command.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/gke_connect_command.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/gke_connect_command.png diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/gke_dashboard.png b/content/en/hosting/cht/kubernetes/gcp-multinode/gke_dashboard.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/gke_dashboard.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/gke_dashboard.png diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/nodepool_base_image_machine_size.png b/content/en/hosting/cht/kubernetes/gcp-multinode/nodepool_base_image_machine_size.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/nodepool_base_image_machine_size.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/nodepool_base_image_machine_size.png diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/nodepool_chtcore_add.png b/content/en/hosting/cht/kubernetes/gcp-multinode/nodepool_chtcore_add.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/nodepool_chtcore_add.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/nodepool_chtcore_add.png diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/nodepool_couchdb_3_nodes.png b/content/en/hosting/cht/kubernetes/gcp-multinode/nodepool_couchdb_3_nodes.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/nodepool_couchdb_3_nodes.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/nodepool_couchdb_3_nodes.png diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/nodepool_labels.png b/content/en/hosting/cht/kubernetes/gcp-multinode/nodepool_labels.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/nodepool_labels.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/nodepool_labels.png diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/nodepool_networking_internal_access.png b/content/en/hosting/cht/kubernetes/gcp-multinode/nodepool_networking_internal_access.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/nodepool_networking_internal_access.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/nodepool_networking_internal_access.png diff --git a/content/en/hosting/4.x/kubernetes/gcp-multinode/welcome_project_id_dashboard.png b/content/en/hosting/cht/kubernetes/gcp-multinode/welcome_project_id_dashboard.png similarity index 100% rename from content/en/hosting/4.x/kubernetes/gcp-multinode/welcome_project_id_dashboard.png rename to content/en/hosting/cht/kubernetes/gcp-multinode/welcome_project_id_dashboard.png diff --git a/content/en/hosting/4.x/kubernetes/self-hosting-k3s-multinode.md b/content/en/hosting/cht/kubernetes/self-hosting-k3s-multinode.md similarity index 98% rename from content/en/hosting/4.x/kubernetes/self-hosting-k3s-multinode.md rename to content/en/hosting/cht/kubernetes/self-hosting-k3s-multinode.md index 5d527bf05c..1ce682fd6f 100644 --- a/content/en/hosting/4.x/kubernetes/self-hosting-k3s-multinode.md +++ b/content/en/hosting/cht/kubernetes/self-hosting-k3s-multinode.md @@ -1,14 +1,15 @@ --- -title: "Production Hosting in CHT 4.x - Multiple CouchDB Nodes on k3s on VMWare" +title: "Production Hosting in CHT - Multiple CouchDB Nodes on k3s on VMWare" linkTitle: "VMWare + k3s Multiple Node" weight: 20 description: > Hosting the CHT on self run VMware infrastructure for multiple CHT-Core projects that utilize horizontally scaled CouchDB nodes aliases: - - /apps/guides/hosting/4.x/self-hosting/self-hosting-k3s-multinode - - /hosting/4.x/self-hosting/self-hosting-k3s-multinode + - /apps/guides/hosting/cht/self-hosting/self-hosting-k3s-multinode + - /hosting/cht/self-hosting/self-hosting-k3s-multinode - ../self-hosting-k3s-multinode - - /hosting/4.x/production/kubernetes/self-hosting-k3s-multinode/ + - /hosting/cht/production/kubernetes/self-hosting-k3s-multinode/ + - /hosting/4.x/kubernetes/self-hosting-k3s-multinode/ --- {{< callout >}} diff --git a/content/en/hosting/4.x/migration/_index.md b/content/en/hosting/cht/migration/_index.md similarity index 96% rename from content/en/hosting/4.x/migration/_index.md rename to content/en/hosting/cht/migration/_index.md index ce6b46d904..e4c9c28c0f 100644 --- a/content/en/hosting/4.x/migration/_index.md +++ b/content/en/hosting/cht/migration/_index.md @@ -4,6 +4,8 @@ linkTitle: Migration Guides weight: 30 description: > Guides for migrating CHT applications +aliases: + - /hosting/4.x/migration/ --- {{< cards >}} diff --git a/content/en/hosting/4.x/migration/data-migration-3x-docker-to-4x-k3s-multi.md b/content/en/hosting/cht/migration/data-migration-3x-docker-to-4x-k3s-multi.md similarity index 98% rename from content/en/hosting/4.x/migration/data-migration-3x-docker-to-4x-k3s-multi.md rename to content/en/hosting/cht/migration/data-migration-3x-docker-to-4x-k3s-multi.md index c9a7c62bbf..7fa2d2f7b9 100644 --- a/content/en/hosting/4.x/migration/data-migration-3x-docker-to-4x-k3s-multi.md +++ b/content/en/hosting/cht/migration/data-migration-3x-docker-to-4x-k3s-multi.md @@ -5,7 +5,8 @@ weight: 1 description: > Guide to migrate existing data from CHT 3.x Docker Compose deployment to CHT 4.x clustered K3s deployment with 3 CouchDB nodes aliases: - - /hosting/4.x/migration/_partial_migration_3x_docker_to_4x_k3s + - /hosting/cht/migration/_partial_migration_3x_docker_to_4x_k3s + - /hosting/4.x/migration/data-migration-3x-docker-to-4x-k3s-multi/ --- The hosting architecture differs entirely between CHT Core 3.x and CHT Core 4.x. When migrating from Docker Compose to K3s, specific steps are required using the [couchdb-migration](https://github.com/medic/couchdb-migration) tool. This tool interfaces with CouchDB to update shard maps and database metadata. diff --git a/content/en/hosting/4.x/migration/data-migration-3x-docker-to-4x-k3s-single.md b/content/en/hosting/cht/migration/data-migration-3x-docker-to-4x-k3s-single.md similarity index 97% rename from content/en/hosting/4.x/migration/data-migration-3x-docker-to-4x-k3s-single.md rename to content/en/hosting/cht/migration/data-migration-3x-docker-to-4x-k3s-single.md index d491c839d6..f2c612efd5 100644 --- a/content/en/hosting/4.x/migration/data-migration-3x-docker-to-4x-k3s-single.md +++ b/content/en/hosting/cht/migration/data-migration-3x-docker-to-4x-k3s-single.md @@ -5,7 +5,8 @@ weight: 2 description: > Guide on how to migrate existing data from CHT 3.x Docker Compose deployment to CHT 4.x single-node K3s deployment aliases: - - /hosting/4.x/migration/_partial_migration_3x_docker_to_4x_k3s + - /hosting/cht/migration/_partial_migration_3x_docker_to_4x_k3s + - /hosting/4.x/migration/data-migration-3x-docker-to-4x-k3s-single/ --- The hosting architecture differs entirely between CHT Core 3.x and CHT Core 4.x. When migrating from Docker Compose to K3s, specific steps are required using the [couchdb-migration](https://github.com/medic/couchdb-migration) tool. This tool interfaces with CouchDB to update shard maps and database metadata. diff --git a/content/en/hosting/4.x/migration/migration-to-4x-docker.md b/content/en/hosting/cht/migration/migration-to-4x-docker.md similarity index 97% rename from content/en/hosting/4.x/migration/migration-to-4x-docker.md rename to content/en/hosting/cht/migration/migration-to-4x-docker.md index 396321f30b..ce3d66b4dd 100644 --- a/content/en/hosting/4.x/migration/migration-to-4x-docker.md +++ b/content/en/hosting/cht/migration/migration-to-4x-docker.md @@ -5,7 +5,8 @@ weight: 3 description: > Guide to migrate existent data from CHT 3.x to CHT 4.x aliases: - - /apps/guides/hosting/4.x/data-migration + - /apps/guides/hosting/cht/data-migration + - /hosting/4.x/migration/migration-to-4x-docker/ --- The hosting architecture differs entirely between CHT-Core 3.x and CHT-Core 4.x. Migrating data from an existing instance running CHT 3.x requires a few manual steps. @@ -44,7 +45,7 @@ EOF ### 2. Prepare CHT-Core 3.x installation for upgrading Backup your data! If you encounter any problems executing the instructions of this guide, you should be able to restore your CHT 3X instance using the backup data. -[Consult information about backups for details]({{< relref "hosting/3.x/self-hosting#backup" >}}). +Double check your backups are up to date. Ensure no changes happen to your CouchDB data in your CHT 3.x server after you have begun the migration process. To minimize downtime when upgrading, it's advised to prepare the 3.x installation for the 4.x upgrade, and pre-index all views that are required by 4.x. @@ -76,7 +77,7 @@ Used in encrypting all CouchDb passwords and session tokens. Used in generating replication checkpointer documents, which track where replication progress between every client and the server, and ensure that clients don't re-download or re-upload documents. ### 4. Locate and make a copy of your CouchDb Data folder -a) If running in MedicOS, [CouchDb data folder]({{< relref "hosting/3.x/self-hosting#backup" >}}) can be found at `/srv/storage/medic-core/couchdb/data`. +a) If running in MedicOS, CouchDB data folder can be found at `/srv/storage/medic-core/couchdb/data`. b) If running a custom installation of CouchDb, data would be typically stored at `/opt/couchdb/data`. diff --git a/content/en/hosting/requirements.md b/content/en/hosting/cht/requirements.md similarity index 78% rename from content/en/hosting/requirements.md rename to content/en/hosting/cht/requirements.md index 4fdd9d64ad..55cfdd1129 100644 --- a/content/en/hosting/requirements.md +++ b/content/en/hosting/cht/requirements.md @@ -5,22 +5,17 @@ weight: 2 description: > Requirements for hosting CHT applications relatedContent: > - hosting/4.x - hosting/3.x/self-hosting - hosting/3.x/ec2-setup-guide + hosting/cht aliases: - /apps/guides/hosting/requirements + - /hosting/requirements/ --- {{< callout >}} For production CHT deployments, Linux is recommended, with [Ubuntu](https://ubuntu.com/server) the most commonly used. For App Developer Hosting, Linux or macOS may be used. Windows can be used for either, but without recommendation. {{< /callout >}} -Per the [Kubernetes vs Docker]({{< relref "hosting/kubernetes-vs-docker" >}}) page, CHT Core can be deployed with either Docker or Kubernetes. - -{{< callout type="warning" >}} - CHT 3.x is [End-of-Life]({{< relref "releases/#supported-versions" >}}) and no longer supported. All requirements below apply to CHT 4.x. -{{< /callout >}} +Per the [Kubernetes vs Docker]({{< relref "/hosting/cht/kubernetes-vs-docker" >}}) page, CHT Core can be deployed with either Docker or Kubernetes. ## App Developer Hosting @@ -28,7 +23,7 @@ This leverages Docker and requires: * 4 GB RAM / 2 CPU / 8 GB SSD * Root Access -* TLS certificates - Docker Helper for [3.x]({{< relref "hosting/3.x/app-developer#cht-docker-helper" >}}) or [4.x]({{< relref "hosting/4.x/app-developer#cht-docker-helper-for-4x" >}}) provides these for you. +* TLS certificates - if using [Docker Helper]({{< relref "/hosting/cht/app-developer#cht-docker-helper-for-4x" >}}) these are provided for you. * [Current version](https://docs.docker.com/engine/install/) of `docker` or current version of [Docker Desktop](https://www.docker.com/products/docker-desktop/) both of which include `docker compose`. Note that the older `docker-compose` is [no longer supported](https://www.docker.com/blog/announcing-compose-v2-general-availability/). ## Production Hosting @@ -42,7 +37,7 @@ This leverages Docker and requires: ### Kubernetes -This guide refers to "Kubernetes", and a lightweight orchestrator called [K3s](https://docs.k3s.io/) can be used for bare-metal hosts. The requirements below refer to K3s deployments but can be translated to other Kubernetes hosting. For example, for cloud hosting, CHT is widely deployed with Amazon [Elastic Kubernetes Service](https://aws.amazon.com/eks/) (EKS). Additionally, the CHT is succesfully deployed in a [large K3s deployment based on VMWare]({{< relref "4.x/kubernetes/self-hosting-k3s-multinode" >}}). +This guide refers to "Kubernetes", and a lightweight orchestrator called [K3s](https://docs.k3s.io/) can be used for bare-metal hosts. The requirements below refer to K3s deployments but can be translated to other Kubernetes hosting. For example, for cloud hosting, CHT is widely deployed with Amazon [Elastic Kubernetes Service](https://aws.amazon.com/eks/) (EKS). Additionally, the CHT is succesfully deployed in a [large K3s deployment based on VMWare]({{< relref "/hosting/cht/kubernetes/self-hosting-k3s-multinode" >}}). Be sure to see the `cht-deploy` [script](https://github.com/medic/cht-core/tree/master/scripts/deploy) that leverage the `helm` [application](https://helm.sh/docs/intro/install/). @@ -56,7 +51,7 @@ Be sure to see the `cht-deploy` [script](https://github.com/medic/cht-core/tree/ * [Current version](https://docs.docker.com/engine/install/) of `docker` (used to bootstrap K3s) {{< callout type="warning" >}} - During some upgrades, up to 3x current space used by CouchDB can be needed. + During some upgrades, up to 5x current space used by CouchDB can be needed. {{< /callout >}} diff --git a/content/en/hosting/4.x/upgrade-troubleshooting.md b/content/en/hosting/cht/upgrade-troubleshooting.md similarity index 95% rename from content/en/hosting/4.x/upgrade-troubleshooting.md rename to content/en/hosting/cht/upgrade-troubleshooting.md index b720de7061..7fa7c411a6 100644 --- a/content/en/hosting/4.x/upgrade-troubleshooting.md +++ b/content/en/hosting/cht/upgrade-troubleshooting.md @@ -1,21 +1,23 @@ --- -title: "Troubleshooting 4.x upgrades" +title: "Troubleshooting upgrades" linkTitle: "Troubleshooting upgrades" weight: 50 description: > - What to do when CHT 4.x upgrades don't work as planned + What to do when CHT upgrades don't work as planned relatedContent: > - hosting/4.x/migration/migration-to-4x-docker + hosting/cht/migration/migration-to-4x-docker +aliases: + - /hosting/4.x/upgrade-troubleshooting/ --- {{< callout >}} - 4.0.0 was released in November of 2022 so 4.x is mature and users have learned a number of important lessons on how to fix failed 4.x upgrades. Below are some specific tips as well as general practices on upgrading 4.x. + 4.0.0 was released in November of 2022 so 4.x is mature and users have learned a number of important lessons on how to fix failed upgrades. Below are some specific tips as well as general practices on upgrading. {{< /callout >}} There's a concept of upgrades "getting stuck" which mainly means that after many many hours an upgrade is not making any progress. Most likely, this will manifest as the progress bars in the upgrade admin web UI not increasing and "sticking" at a certain percentage. An alternate possibility is that the progress bars disappear altogether. > [!WARNING] -> All tips apply to both [Docker]({{< relref "hosting/4.x/docker" >}}) and [Kubernetes]({{< relref "hosting/4.x/kubernetes" >}}) based deployments unless otherwise specified. +> All tips apply to both [Docker]({{< relref "/hosting/cht/docker" >}}) and [Kubernetes]({{< relref "/hosting/cht/kubernetes" >}}) based deployments unless otherwise specified. > All upgrades are expected to succeed without issue. Do not attempt any fixes unless you actively have a problem upgrading. ## Considerations diff --git a/content/en/hosting/4.x/upgrade-troubleshooting/container-status-unknown.png b/content/en/hosting/cht/upgrade-troubleshooting/container-status-unknown.png similarity index 100% rename from content/en/hosting/4.x/upgrade-troubleshooting/container-status-unknown.png rename to content/en/hosting/cht/upgrade-troubleshooting/container-status-unknown.png diff --git a/content/en/hosting/4.x/upgrade-troubleshooting/retry.upgrade.png b/content/en/hosting/cht/upgrade-troubleshooting/retry.upgrade.png similarity index 100% rename from content/en/hosting/4.x/upgrade-troubleshooting/retry.upgrade.png rename to content/en/hosting/cht/upgrade-troubleshooting/retry.upgrade.png diff --git a/content/en/hosting/4.x/upgrade-troubleshooting/stalled-upgrade.png b/content/en/hosting/cht/upgrade-troubleshooting/stalled-upgrade.png similarity index 100% rename from content/en/hosting/4.x/upgrade-troubleshooting/stalled-upgrade.png rename to content/en/hosting/cht/upgrade-troubleshooting/stalled-upgrade.png diff --git a/content/en/hosting/couch2pg/_index.md b/content/en/hosting/couch2pg/_index.md index 692b5a2e7b..dff79897da 100644 --- a/content/en/hosting/couch2pg/_index.md +++ b/content/en/hosting/couch2pg/_index.md @@ -7,7 +7,7 @@ description: > --- {{< callout type="warning" >}} - CHT couch2pg is deprecated. For data synchronization, refer to [CHT Sync]({{< ref "hosting/analytics" >}}). + CHT couch2pg is deprecated. For data synchronization, refer to [CHT Sync]({{< ref "/hosting/analytics" >}}). {{< /callout >}} {{< subpages >}} \ No newline at end of file diff --git a/content/en/hosting/couch2pg/couch2pg-oom-errors.md b/content/en/hosting/couch2pg/couch2pg-oom-errors.md index b117a6409d..b5bc97bfa4 100644 --- a/content/en/hosting/couch2pg/couch2pg-oom-errors.md +++ b/content/en/hosting/couch2pg/couch2pg-oom-errors.md @@ -4,15 +4,13 @@ linkTitle: "Memory Errors" weight: 4 description: > Dealing with out-of-memory errors in couch2pg -relatedContent: > - hosting/3.x/ec2-setup-guide aliases: - /apps/guides/database/couch2pg-oom-errors - /building/guides/database/couch2pg-oom-errors --- {{< callout type="warning" >}} - CHT couch2pg is deprecated. For data synchronization, refer to [CHT Sync]({{< ref "hosting/analytics" >}}). + CHT couch2pg is deprecated. For data synchronization, refer to [CHT Sync]({{< ref "/hosting/analytics" >}}). {{< /callout >}} Some times when couch2pg is replicating documents to postgres, it encounters very large info docs that are larger than the memory allocation of the document sync array and causes out-of-memory errors. diff --git a/content/en/hosting/couch2pg/couch2pg-setup.md b/content/en/hosting/couch2pg/couch2pg-setup.md index 4d6d83962d..8793b87422 100644 --- a/content/en/hosting/couch2pg/couch2pg-setup.md +++ b/content/en/hosting/couch2pg/couch2pg-setup.md @@ -12,7 +12,7 @@ aliases: --- {{< callout type="warning" >}} - CHT couch2pg is deprecated. For data synchronization, refer to [CHT Sync]({{< ref "hosting/analytics" >}}). + CHT couch2pg is deprecated. For data synchronization, refer to [CHT Sync]({{< ref "/hosting/analytics" >}}). {{< /callout >}} This tutorial will take you through setting up a couch2pg service. diff --git a/content/en/hosting/couch2pg/migration.md b/content/en/hosting/couch2pg/migration.md index a56e897b17..7d1081e012 100644 --- a/content/en/hosting/couch2pg/migration.md +++ b/content/en/hosting/couch2pg/migration.md @@ -7,7 +7,7 @@ description: > --- {{< callout type="warning" >}} - CHT couch2pg is deprecated. For data synchronization, refer to [CHT Sync]({{< ref "hosting/analytics" >}}). + CHT couch2pg is deprecated. For data synchronization, refer to [CHT Sync]({{< ref "/hosting/analytics" >}}). {{< /callout >}} ## Assumptions & Prerequisites @@ -24,7 +24,7 @@ Further, be sure you meet the following prerequisites: * Have access to couch2pg instance, including the CHT Core credentials it's using * Have 3x the disk space as your data on both the old and new server - see below -**Note:** If you don't mind waiting and don't want to deal with the trouble of copying large data files around as documented on this page, it will be easier to set up a clean [install of couch2pg]({{< ref "hosting/couch2pg/setup-and-devlopment" >}}) +**Note:** If you don't mind waiting and don't want to deal with the trouble of copying large data files around as documented on this page, it will be easier to set up a clean [install of couch2pg]({{< ref "/hosting/couch2pg/setup-and-devlopment" >}}) ### Time to copy diff --git a/content/en/hosting/couch2pg/setup-and-devlopment.md b/content/en/hosting/couch2pg/setup-and-devlopment.md index 24d143974f..8fc8fbba36 100644 --- a/content/en/hosting/couch2pg/setup-and-devlopment.md +++ b/content/en/hosting/couch2pg/setup-and-devlopment.md @@ -7,7 +7,7 @@ description: > --- {{< callout type="warning" >}} - CHT couch2pg is deprecated. For data synchronization, refer to [CHT Sync]({{< ref "hosting/analytics" >}}). + CHT couch2pg is deprecated. For data synchronization, refer to [CHT Sync]({{< ref "/hosting/analytics" >}}). {{< /callout >}} Create read-only replicas of CouchDB data inside PostgresSQL. diff --git a/content/en/hosting/medic/data-migration-3x-eks-to-4x-eks.md b/content/en/hosting/medic/data-migration-3x-eks-to-4x-eks.md index 4c3d83525f..2fb0367296 100644 --- a/content/en/hosting/medic/data-migration-3x-eks-to-4x-eks.md +++ b/content/en/hosting/medic/data-migration-3x-eks-to-4x-eks.md @@ -9,7 +9,7 @@ aliases: - /contribute/medic/data-migration-3x-eks-to-4x-eks --- -Like the [Deploy to EKS guide]({{< relref "hosting/medic/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. +Like the [Deploy to EKS guide]({{< relref "/hosting/medic/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. diff --git a/content/en/hosting/monitoring/_index.md b/content/en/hosting/monitoring/_index.md index 28ac09bc3e..534684b24d 100644 --- a/content/en/hosting/monitoring/_index.md +++ b/content/en/hosting/monitoring/_index.md @@ -3,7 +3,7 @@ title: Monitoring and Alerting with CHT Watchdog linkTitle: Monitoring and Alerting weight: 8 description: > - Using CHT Watchdog to Monitor and Alert on CHT 3.x and 4.x Applications + Using CHT Watchdog to Monitor and Alert on CHT Applications aliases: - apps/guides/hosting/monitoring --- diff --git a/content/en/hosting/monitoring/dashboards.md b/content/en/hosting/monitoring/dashboards.md index 01a3ae2724..4de558a46b 100644 --- a/content/en/hosting/monitoring/dashboards.md +++ b/content/en/hosting/monitoring/dashboards.md @@ -7,10 +7,6 @@ description: > --- -{{< callout >}} -These instructions apply to both CHT 3.x (beyond 3.12) and CHT 4.x. -{{< /callout >}} - ## Overview This is the main dashboard for Watchdog. It gives you high level details on your CHT instance. Starting from the upper left and going from right to left you have: @@ -30,8 +26,6 @@ This is the main dashboard for Watchdog. It gives you high level details on you 13. Client Feedback/Error Rate: Number of feedback docs created usually indicative of client side errors. 14. Alerts: Alerts that need attention. In this screenshot, you can see that the Client Feedback/Error Rate is too high and should be investigated. See [alerts](/hosting/monitoring/setup/#alerts) for more information. - - ![overview.png](dashboards/overview.png) ## Details diff --git a/content/en/hosting/monitoring/integration.md b/content/en/hosting/monitoring/integration.md index d700fc5880..fef7260078 100644 --- a/content/en/hosting/monitoring/integration.md +++ b/content/en/hosting/monitoring/integration.md @@ -8,13 +8,9 @@ aliases: - /apps/guides/hosting/monitoring/integration --- -{{< callout >}} - These instructions apply to both CHT 3.x (beyond 3.12) and CHT 4.x. -{{< /callout >}} - ## Going beyond basic setup -After you have done the [setup of CHT Watchdog]({{< relref "hosting/monitoring/setup.md" >}}) and configured it to run [with TLS and have backups enabled]({{< relref "hosting/monitoring/production.md" >}}), you may want to extend it to scrape other Prometheus data sources so that Grafana can send alerts on non-CHT Core metrics. +After you have done the [setup of CHT Watchdog]({{< relref "/hosting/monitoring/setup.md" >}}) and configured it to run [with TLS and have backups enabled]({{< relref "/hosting/monitoring/production.md" >}}), you may want to extend it to scrape other Prometheus data sources so that Grafana can send alerts on non-CHT Core metrics. This guide uses example instances of CHT Core (`cht.example.com`) and CHT Watchdog (`watchdog.example.com`). When deploying, be sure to replace with your own hostnames. @@ -116,7 +112,7 @@ services: #### Caddy Config and Compose files -Like we did in the [TLS section]({{< relref "hosting/monitoring/production#accessing-grafana-over-tls" >}}), we'll add both a `/home/ubuntu/Caddyfile` and a `/home/ubuntu/cht/compose/caddy-compose.yml`. +Like we did in the [TLS section]({{< relref "/hosting/monitoring/production#accessing-grafana-over-tls" >}}), we'll add both a `/home/ubuntu/Caddyfile` and a `/home/ubuntu/cht/compose/caddy-compose.yml`. Starting with the `Caddyfile`, let's assume your server's DNS entry is `cht.example.com`. We can expose cAdvisor's service running on localhost port `8443` with this compose file. This tells Caddy to reverse proxy requests to the public interface to the private Docker network interface on port `8080` where cAdvisor is running: @@ -146,7 +142,7 @@ services: Now that we have all the config files in place, you need to have Docker start everything together. This is so that the containers can see each other on the same `CHT Net` Docker network. You will need to specify each of the compose files every time you start, stop or restart CHT instance so all the services stay running and connected. -Assuming you followed the [production steps]({{< relref "hosting/4.x/docker" >}}) to install the CHT, you use this Compose call to first stop all containers and then start them all up, including the new services: +Assuming you followed the [production steps]({{< relref "/hosting/cht/docker" >}}) to install the CHT, you use this Compose call to first stop all containers and then start them all up, including the new services: ```shell cd /home/ubuntu/cht/upgrade-service @@ -183,7 +179,7 @@ services: #### Load new Compose files with existing ones -Now that you've added the new configuration files, we can load it alongside the existing ones. Assuming you've followed the [Watchdog Setup]({{< relref "hosting/monitoring/setup" >}}), this would be: +Now that you've added the new configuration files, we can load it alongside the existing ones. Assuming you've followed the [Watchdog Setup]({{< relref "/hosting/monitoring/setup" >}}), this would be: ```shell cd ~/cht-monitoring diff --git a/content/en/hosting/monitoring/introduction.md b/content/en/hosting/monitoring/introduction.md index 8a20d356d2..cc938366df 100644 --- a/content/en/hosting/monitoring/introduction.md +++ b/content/en/hosting/monitoring/introduction.md @@ -10,8 +10,7 @@ aliases: --- {{< callout >}} -This guide applies to all production instances of the CHT for both 3.x (beyond 3.9) and 4.x. -Be sure to see how to deploy a solution to [monitor and alert on production CHT instances]({{< relref "hosting/monitoring/setup.md" >}}). +Be sure to see how to deploy a solution to [monitor and alert on production CHT instances]({{< relref "/hosting/monitoring/setup.md" >}}). {{< /callout >}} Each deployment will experience different stresses on its resources. Be sure to tune any alerting levels in the case of a false positive so that you may avoid them in the future. Any thresholds for alerts, and even what is alerted on, is just a guideline, not a guarantee of uptime. diff --git a/content/en/hosting/monitoring/postgres-ingest.md b/content/en/hosting/monitoring/postgres-ingest.md index 53562ee31e..29760591a4 100644 --- a/content/en/hosting/monitoring/postgres-ingest.md +++ b/content/en/hosting/monitoring/postgres-ingest.md @@ -8,13 +8,9 @@ aliases: - /apps/guides/hosting/monitoring/postgres-ingest --- -{{< callout >}} - These instructions apply to both CHT 3.x (beyond 3.12) and CHT 4.x. -{{< /callout >}} - ## Introduction -After [setting up]({{< relref "hosting/monitoring/setup.md" >}}) your Watchdog instance and [making it production ready]({{< relref "hosting/monitoring/production.md" >}}), you can include additional custom metrics from your deployment. These metrics should be ingested by Prometheus and then can be used to create new Grafana dashboards and alerts. Example use cases include monitoring and alerting on health metrics like CHW visits per county or household registration rates, etc. +After [setting up]({{< relref "/hosting/monitoring/setup.md" >}}) your Watchdog instance and [making it production ready]({{< relref "/hosting/monitoring/production.md" >}}), you can include additional custom metrics from your deployment. These metrics should be ingested by Prometheus and then can be used to create new Grafana dashboards and alerts. Example use cases include monitoring and alerting on health metrics like CHW visits per county or household registration rates, etc. This guide will walk you through adding a custom metric from Postgres _data_. The following naming convention is used throughout to reference the relevant server instances: CHT Core (`cht.example.com`), CHT Watchdog (`watchdog.example.com`) and a Postgres server (`db.example.com`). @@ -156,7 +152,7 @@ services: Launch Watchdog with the new compose file -Now that you've added the new configuration files, we can load it alongside the existing ones. Assuming you've followed the [Watchdog Setup]({{< relref "hosting/monitoring/setup" >}}), this would be: +Now that you've added the new configuration files, we can load it alongside the existing ones. Assuming you've followed the [Watchdog Setup]({{< relref "/hosting/monitoring/setup" >}}), this would be: ```shell cd ~/cht-watchdog diff --git a/content/en/hosting/monitoring/production.md b/content/en/hosting/monitoring/production.md index 02ad70ea82..4fd4f9bd43 100644 --- a/content/en/hosting/monitoring/production.md +++ b/content/en/hosting/monitoring/production.md @@ -17,7 +17,7 @@ When you run CHT Watchdog in production, and it is publicly accessible on the In * ensuring if the server were to fail, you can recover the data -This guide assumes you have already [set up TLS]({{< relref "hosting/4.x/docker/adding-tls-certificates" >}}) on your CHT instance and have gone through [the Setup steps]({{< relref "hosting/monitoring/setup" >}}) to deploy an instance of CHT Watchdog on server with a static IP and DNS entry, `monitor.example.com` for example. +This guide assumes you have already [set up TLS]({{< relref "/hosting/cht/docker/adding-tls-certificates" >}}) on your CHT instance and have gone through [the Setup steps]({{< relref "/hosting/monitoring/setup" >}}) to deploy an instance of CHT Watchdog on server with a static IP and DNS entry, `monitor.example.com` for example. > [!WARNING] > Always run Watchdog on a different server than the CHT Core. This ensures Watchdog doesn't fail if the CHT Core server fails and alerts will always be sent. The instructions assume you're connecting over the public Internet and no special VPN or routing is required. diff --git a/content/en/hosting/monitoring/setup.md b/content/en/hosting/monitoring/setup.md index 0ccdca832d..f134e1ec70 100644 --- a/content/en/hosting/monitoring/setup.md +++ b/content/en/hosting/monitoring/setup.md @@ -12,10 +12,6 @@ aliases: - /apps/guides/hosting/monitoring/setup --- -{{< callout >}} - These instructions apply to both CHT 3.x (beyond 3.12) and CHT 4.x. -{{< /callout >}} - Medic maintains CHT Watchdog which is an opinionated configuration of [Prometheus](https://prometheus.io/) (including [json_exporter](https://github.com/prometheus-community/json_exporter)) and [Grafana](https://grafana.com/grafana/) which can easily be deployed using Docker. It is supported on CHT 3.12 and later, including CHT 4.x. By using this solution a CHT deployment can easily get longitudinal monitoring and push alerts using Email, Slack or other mechanisms. All tools are open source and have no licensing fees. The solution provides both an overview dashboard as well as a detail dashboard. Here is a portion of the overview dashboard: @@ -119,7 +115,7 @@ docker compose up -d #### CHT Sync Data (Local) -With the [release of 1.1.0](https://github.com/medic/cht-watchdog/releases/tag/1.1.0), Watchdog now supports easily ingesting [CHT Sync]({{< relref "hosting/analytics" >}}) data read in from a Postgres database (supports Postgres `>= 9.x`). +With the [release of 1.1.0](https://github.com/medic/cht-watchdog/releases/tag/1.1.0), Watchdog now supports easily ingesting [CHT Sync]({{< relref "/hosting/analytics" >}}) data read in from a Postgres database (supports Postgres `>= 9.x`). 1. Copy the example config file, so you can add the correct contents in them: ```shell diff --git a/content/en/releases/4_0_0.md b/content/en/releases/4_0_0.md index 3cc5d2261f..f629705430 100644 --- a/content/en/releases/4_0_0.md +++ b/content/en/releases/4_0_0.md @@ -21,7 +21,7 @@ Check the repository for the [latest known issues](https://github.com/medic/cht- To prepare for this release, read through our [Preparing to Upgrade documentation]({{< ref "building/guides/updates/preparing-for-4" >}}). {{< callout type="warning" >}} - Be aware that as this is a major upgrade some manual steps are required - following the usual upgrade process will not work. [Data migration documentation is coming soon]({{< ref "hosting/4.x" >}}), but in the meantime reach out on [the forum](https://forum.communityhealthtoolkit.org/) for direct support in upgrading. New projects should start on 4.0.0 to make the following upgrades easier. + Be aware that as this is a major upgrade some manual steps are required - following the usual upgrade process will not work. [Data migration documentation is coming soon]({{< ref "/hosting/cht" >}}), but in the meantime reach out on [the forum](https://forum.communityhealthtoolkit.org/) for direct support in upgrading. New projects should start on 4.0.0 to make the following upgrades easier. {{< /callout >}} #### New architecture diff --git a/content/en/releases/4_20_0.md b/content/en/releases/4_20_0.md index 3391ab218e..9909dd3be5 100644 --- a/content/en/releases/4_20_0.md +++ b/content/en/releases/4_20_0.md @@ -42,7 +42,7 @@ Single Sign-On (SSO) enables users connecting to a CHT instance to authenticate SSO authentication is implemented with the industry standard [OpenID Connect](https://openid.net/) (OIDC) protocol. Any OIDC-compliant authentication server can be integrated with the CHT. -See [the documentation]({{< ref "hosting/sso" >}}) for more details on configuration and functionality. +See [the documentation]({{< ref "/hosting/sso" >}}) for more details on configuration and functionality. [#9735](https://github.com/medic/cht-core/issues/9735): Single sign on (SSO) using identity provider diff --git a/content/en/releases/_index.md b/content/en/releases/_index.md index 594d23521c..bbb55d14c6 100644 --- a/content/en/releases/_index.md +++ b/content/en/releases/_index.md @@ -62,7 +62,7 @@ The following table shows the dependencies for deploying the CHT. | **2.x** | 6+ | 1.6+ | Chrome 30+, Firefox latest | cht-gateway | 4.4+ | Any | N/A | | **0.4** | 0.12+ | 1.6+ | Chrome 30+, Firefox latest | SMSSync | N/A | N/A | N/A | -{{< see-also page="hosting/requirements" title="Hosting Requirements" >}} +{{< see-also page="/hosting/cht/requirements" title="/hosting Requirements" >}} ### Client Devices diff --git a/content/en/technical-overview/architecture/cht-sync.md b/content/en/technical-overview/architecture/cht-sync.md index 9e49134b9a..eea1123e9a 100644 --- a/content/en/technical-overview/architecture/cht-sync.md +++ b/content/en/technical-overview/architecture/cht-sync.md @@ -16,7 +16,7 @@ aliases: CHT Sync is an integrated solution designed to enable data synchronization between CouchDB and PostgreSQL for the purpose of analytics. It combines several technologies to achieve this synchronization and provides an efficient workflow for data processing and visualization. The synchronization occurs in near real-time, ensuring that the data displayed on dashboards is up-to-date. -Read more about setting up [CHT Sync]({{< relref "hosting/analytics" >}}). +Read more about setting up [CHT Sync]({{< relref "/hosting/analytics" >}}). diff --git a/content/en/technical-overview/architecture/cht-watchdog.md b/content/en/technical-overview/architecture/cht-watchdog.md index e671960a45..0a608009bc 100644 --- a/content/en/technical-overview/architecture/cht-watchdog.md +++ b/content/en/technical-overview/architecture/cht-watchdog.md @@ -12,7 +12,7 @@ aliases: - /technical-overview/cht-watchdog/ --- -CHT Watchdog is deployed on a separate server so that you can watch for, and alert on, any critical issues with the CHT Core. Read more about [setting up CHT Watchdog]({{< relref "hosting/monitoring/setup" >}}). +CHT Watchdog is deployed on a separate server so that you can watch for, and alert on, any critical issues with the CHT Core. Read more about [setting up CHT Watchdog]({{< relref "/hosting/monitoring/setup" >}}). diff --git a/content/en/technical-overview/concepts/data-flows-for-analytics.md b/content/en/technical-overview/concepts/data-flows-for-analytics.md index 47dc9e6ce2..94c903d9f5 100644 --- a/content/en/technical-overview/concepts/data-flows-for-analytics.md +++ b/content/en/technical-overview/concepts/data-flows-for-analytics.md @@ -50,7 +50,7 @@ Ultimately all the data ends up in a CouchDB instance deployed in the cloud whet #### 2. Data Transformation -[CHT Sync]({{< relref "technical-overview/architecture/cht-sync" >}}) is used to move data from CouchDB to a relational database, PostgreSQL in this case. The choice of PostgreSQL for analytics dashboard data sources is to allow use of the more familiar SQL querying. It is an open source tool that can be [easily deployed]({{< ref "hosting/analytics" >}}). When deployed the service uses [CouchDB's changes feed](https://docs.couchdb.org/en/stable/api/database/changes.html) which allows capturing of everything happening in CouchDB in incremental updates. It is run and monitored by the operating system where it is configured to fetch data at a configurable interval. +[CHT Sync]({{< relref "technical-overview/architecture/cht-sync" >}}) is used to move data from CouchDB to a relational database, PostgreSQL in this case. The choice of PostgreSQL for analytics dashboard data sources is to allow use of the more familiar SQL querying. It is an open source tool that can be [easily deployed]({{< ref "/hosting/analytics" >}}). When deployed the service uses [CouchDB's changes feed](https://docs.couchdb.org/en/stable/api/database/changes.html) which allows capturing of everything happening in CouchDB in incremental updates. It is run and monitored by the operating system where it is configured to fetch data at a configurable interval. Data copied over to PostgreSQL is first stored as raw json (document) making use of PostgreSQL's jsonb data type to create an exact replica of a CouchDB database. From this, default views are created at deployment of the service and refreshed during every subsequent run. Additional custom materialized views created later are also refreshed at this time. From ca11c6ccfcf251c908b95ed791fe38cd35cd3058 Mon Sep 17 00:00:00 2001 From: mrjones <8253488+mrjones-plip@users.noreply.github.com> Date: Mon, 4 Aug 2025 13:56:37 -0700 Subject: [PATCH 11/16] chore(na): squad closeout steps (#1946) * chore(na): squad closeout steps * Update squads.md * Update squads.md --------- Co-authored-by: Phil Mwago <41321750+Phil-Mwago@users.noreply.github.com> --- content/en/community/squads.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/content/en/community/squads.md b/content/en/community/squads.md index 58791084a2..50389ba4d0 100644 --- a/content/en/community/squads.md +++ b/content/en/community/squads.md @@ -125,6 +125,13 @@ The functionality is released and ready to create an impact in the real world. F ### 8. ✅ Done Mission accomplished. The project meets all goals and the related tasks are marked complete. +To close out the squad, undo all the set up that was done in [Kick Off](#kick-off): +- Remove the meeting from the shared Google calendar so it does not show up on the [public Events Calendar](/community/events/) +- Archive the dedicated Slack channel - Stewardship team can help with this +- Clean up GitHub tickets - make sure all releated tickets are closed and up to date +- Hold a final meeting to thank everyone and have a retrospective to ask "What worked?", "What didn't work? and "What could be changed/improved?" + + ## When can you join a squad? See the active squads on the [CHT roadmap](https://github.com/orgs/medic/projects/112/views/24) and subscribe to the [CHT calendar](https://docs.communityhealthtoolkit.org/community/events/) to stay up to date with all the CHT events, including the regular squad meetings. From e5097c86b24ce5eae0301cfffb32a865b2505056 Mon Sep 17 00:00:00 2001 From: Andra Blaj Date: Tue, 5 Aug 2025 12:25:25 +0300 Subject: [PATCH 12/16] chore: remove extra bullet point (#1947) --- content/en/building/tasks/tasks-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/building/tasks/tasks-overview.md b/content/en/building/tasks/tasks-overview.md index 2dd9aa10e0..d6932cb786 100644 --- a/content/en/building/tasks/tasks-overview.md +++ b/content/en/building/tasks/tasks-overview.md @@ -46,7 +46,7 @@ Tasks are now sorted using the following logic: - Tasks with higher priority scores appear first. - When scores tie, tasks are sorted by due date. - Tasks without or invalid priority scores appear last, sorted by due date. -- + {{< callout >}} Older configurations that do not implement the new priority score will continue sorting tasks by due date. {{< /callout >}} From 0c49ec4095271373cbace999314ade2a5a584cec Mon Sep 17 00:00:00 2001 From: Binod Adhikary Date: Wed, 6 Aug 2025 18:39:08 -0700 Subject: [PATCH 13/16] chore(#1948): Add notes on global variable naming restrictions (#1951) --- content/en/building/messaging/gateways/rapidpro.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/content/en/building/messaging/gateways/rapidpro.md b/content/en/building/messaging/gateways/rapidpro.md index d98d4e20c4..a0c4c35d60 100644 --- a/content/en/building/messaging/gateways/rapidpro.md +++ b/content/en/building/messaging/gateways/rapidpro.md @@ -27,12 +27,16 @@ Generate a long unique key to use as the `cht_api_key`. Log in to your RapidPro dashboard, go to the globals page (`/global/`) and create two globals with the following data: -- name: `cht_url`, value: `https:///api/v2/sms/rapidpro/incoming-messages`. For security the instance host **must not** include basic authentication. (NB: This endpoint was added in CHT 4.1.0. If integrating with an earlier version you will need to use the earlier version with a typo in the URL: `https:///api/v1/sms/radpidpro/incoming-messages`) -- name: `cht_api_key`, value: `` +- name: `cht url`, value: `https:///api/v2/sms/rapidpro/incoming-messages`. For security the instance host **must not** include basic authentication. (NB: This endpoint was added in CHT 4.1.0. If integrating with an earlier version you will need to use the earlier version with a typo in the URL: `https:///api/v1/sms/radpidpro/incoming-messages`) +- name: `cht api key`, value: `` -The names of these two global variables are arbitrary, but in this document we will keep referring to the names defined above. +> [!Note] +> Please note that only letters, numbers, and hyphens are accepted when naming a global variable in RapidPro. However, any space(s) in the name will be replaced with underscore(s) when saved. +> For example, `cht url` will be saved as `cht_url`. +> +> The names of these two global variables are arbitrary, but in this document we will keep referring to the names defined above. -Then visit the RapidPro workspace settings page (`/org/home/`) and check your RapidPro API token (we'll refer to this as the `rapidpro_api_key`). +Now visit the RapidPro workspace settings page (`/org/home/`) and check your RapidPro API token (we'll refer to this as the `rapidpro_api_key`). We will use it later. ### Create a new flow From c7ea8da5a0f8ec5864203ef4726df40733dddbc8 Mon Sep 17 00:00:00 2001 From: mrjones <8253488+mrjones-plip@users.noreply.github.com> Date: Thu, 7 Aug 2025 17:10:03 -0700 Subject: [PATCH 14/16] chore(na): wsl2 docker desktop switch, how to add and access data (#1952) * chore(na): wsl2 docker desktop switch, how to add and access data * Update content/en/community/contributing/code/core/dev-environment.md Co-authored-by: Binod Adhikary --------- Co-authored-by: Binod Adhikary --- .../tutorials/_partial_docker_setup.md | 40 +++++++++++------- .../windows.docker.desktop.png | Bin 0 -> 209324 bytes .../contributing/code/core/dev-environment.md | 16 +++++++ 3 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 content/en/building/tutorials/_partial_docker_setup/windows.docker.desktop.png diff --git a/content/en/building/tutorials/_partial_docker_setup.md b/content/en/building/tutorials/_partial_docker_setup.md index 30e12ecfba..cd27fd26c9 100644 --- a/content/en/building/tutorials/_partial_docker_setup.md +++ b/content/en/building/tutorials/_partial_docker_setup.md @@ -9,30 +9,38 @@ aliases: {{< tabs items="Linux (Ubuntu),macOS,Windows (WSL2)" >}} {{< tab >}} -Download and install [Docker Desktop](https://www.docker.com/products/docker-desktop). - -Alternatively, on Linux you can use the following commands to install [Docker Engine](https://docs.docker.com/engine/). (This will reduce the layers of technical abstraction for running containers, but will not include a GUI application for managing your Docker resources.) - -```shell -curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh -# OPTIONAL: Allow user to run Docker without sudo -dockerd-rootless-setuptool.sh install -echo "export PATH=/usr/bin:$PATH" >> ~/.$(basename $SHELL)rc -echo "export DOCKER_HOST=unix:///run/user/1000/docker.sock" >> ~/.$(basename $SHELL)rc -. ~/.$(basename $SHELL)rc -``` + Download and install [Docker Desktop](https://www.docker.com/products/docker-desktop). + + Alternatively, on Linux you can use the following commands to install [Docker Engine](https://docs.docker.com/engine/). (This will reduce the layers of technical abstraction for running containers, but will not include a GUI application for managing your Docker resources.) + + ```shell + curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh + # OPTIONAL: Allow user to run Docker without sudo + dockerd-rootless-setuptool.sh install + echo "export PATH=/usr/bin:$PATH" >> ~/.$(basename $SHELL)rc + echo "export DOCKER_HOST=unix:///run/user/1000/docker.sock" >> ~/.$(basename $SHELL)rc + . ~/.$(basename $SHELL)rc + ``` + + Restart your entire machine to finish initializing Docker. {{< /tab >}} {{< tab >}} -Download and install [Docker Desktop](https://www.docker.com/products/docker-desktop) or [Colima](https://github.com/abiosoft/colima#readme). + Download and install [Docker Desktop](https://www.docker.com/products/docker-desktop) or [Colima](https://github.com/abiosoft/colima#readme). + + Restart your entire machine to finish initializing Docker. {{< /tab >}} {{< tab >}} -Download and install [Docker Desktop](https://www.docker.com/products/docker-desktop). + Download and install [Docker Desktop](https://www.docker.com/products/docker-desktop). + + Restart your entire machine to finish initializing Docker. + + After you have restarted, ensure that "Enable integration with my default WSL distro" is checked in Docker Desktop along with intgration to other distros: + + ![windows.docker.desktop.png](/building/tutorials/_partial_docker_setup/windows.docker.desktop.png) {{< /tab >}} {{< /tabs >}} -Restart your entire machine to finish initializing Docker. - After restarting, verify Docker is running as expected. Run the simple `hello-world` Docker container. This should output "Hello from Docker!" as well as some other intro text: ```shell diff --git a/content/en/building/tutorials/_partial_docker_setup/windows.docker.desktop.png b/content/en/building/tutorials/_partial_docker_setup/windows.docker.desktop.png new file mode 100644 index 0000000000000000000000000000000000000000..577eeb8cc42852171f707bf6948332369d80771f GIT binary patch literal 209324 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 literal 0 HcmV?d00001 diff --git a/content/en/community/contributing/code/core/dev-environment.md b/content/en/community/contributing/code/core/dev-environment.md index 63c8f1e19e..bfbca900fc 100644 --- a/content/en/community/contributing/code/core/dev-environment.md +++ b/content/en/community/contributing/code/core/dev-environment.md @@ -165,6 +165,18 @@ That's it! Now when you edit code in your IDE, it will automatically reload. Y When you're done with development you can `ctrl + c` in the three terminals and stop the CouchDB container with `docker stop medic-couchdb`. When you want to resume development later, run `docker start medic-couchdb` and re-run the three terminal commands. +### Adding and accessing data + +When you first start your CHT instance, it has no data in it. If you would like to populate it with some sample data, you can check out the [Test Data Generator](https://github.com/medic/test-data-generator/) (TDG) which has a "[Quick Start](https://github.com/medic/test-data-generator/?tab=readme-ov-file#quick-start)" option to easily add data. After you have installed TDG, you can quickly add data with this call: + +```shell +COUCH_URL=http://medic:password@localhost:5984 tdg ./sample-designs/easy-mode.js +``` + +When you log into the CHT web front end in a browser at [http://localhost:5988/](http://localhost:5988/), you should now see newly added contacts and reports. + +If you would like to explore the raw data, be sure to check out [Fauxton](https://couchdb.apache.org/fauxton-visual-guide/). This is a pre-installed NoSQL web client that allows you to browse all raw documents and indexes in CouchDB. It is accessed at `/_utils`, so if you've just followed this guide you can go to [http://localhost:5984/_utils](http://localhost:5984/_utils) to use Fauxton. If you are prompted to log in, it is Username `medic` and Password `password`. + ## Other Path Troubleshooting If you weren't able to follow [the happy path above](#the-happy-path-installation), here are some details about the developer install that may help you troubleshoot what went wrong. @@ -180,6 +192,10 @@ If you had issues with following the above steps, check out these links for how * [CouchDB](https://docs.couchdb.org/en/stable/install/index.html) - OS package instead of in Docker - you **MUST** use CouchDB 2.x for CHT < 4.4! We still strongly recommend using Docker. * [bzip2])(https://sourceware.org/bzip2/downloads.html) - if you're on Ubuntu call: `sudo apt install bzip2` +### Windows WSL2 + +While this document covers the happy path to set up your environment, there's [a great forum post](https://forum.communityhealthtoolkit.org/t/help-needed-for-local-setup-of-the-project-using-docker/4900/18) which covers challenges developers running Windows with WSL2 may face. Be sure to read up on it if you're having WSL2 issue like `bash: docker: command not found` and others. + ### Ubuntu 18.04 Ubuntu 18.04's default `apt` repositories do not know about `python2`. This means when you go to install run the first `apt install` command above, you see an error: From 29b4d3c3d35cb713f57e08de1d048122ccb1d5d9 Mon Sep 17 00:00:00 2001 From: Diana Barsan <35681649+dianabarsan@users.noreply.github.com> Date: Fri, 8 Aug 2025 09:16:12 +0300 Subject: [PATCH 15/16] chore(#1936): shuffle quick guides part 1 (#1938) --- .github/scripts/check.urls.sh | 79 +++++++++++++++--- content/en/building/branding/android.md | 2 +- .../android => branding}/publishing.md | 21 +++-- .../contact-management/contact-and-users-1.md | 4 +- .../contact-management/contact-and-users-2.md | 4 +- .../building/contact-management/contacts.md | 2 +- .../user-management-tool.md | 2 +- .../contact-summary-templated.md | 2 +- .../building/forms/configuring/form-inputs.md | 2 +- content/en/building/guides/android/_index.md | 18 ---- content/en/building/guides/data/_index.md | 11 --- .../guides/debugging/obtaining-logs.md | 2 +- .../securely-onboarding-users-at-scale.md | 8 +- .../guides/security/securing-android.md | 6 +- .../guides/updates/preparing-for-4.md | 4 +- .../gateways/gateway/configuration.md | 2 +- content/en/building/navigation.md | 2 +- .../en/building/reference/_partial_cht_api.md | 2 +- content/en/building/reference/api.md | 8 +- .../reference/app-settings/transitions.md | 2 +- content/en/building/reports/_index.md | 2 +- .../en/building/reports/reports-overview.md | 2 +- .../en/building/targets/targets-overview.md | 2 +- .../tasks/managing-tasks/query-task-data.md | 14 ++-- .../managing-tasks/task-schema-parameters.md | 14 ++-- .../en/building/training/onboarding/_index.md | 4 +- .../training-cards-configuration.md | 2 +- .../data => training}/training-instance.md | 5 +- .../training-instance/create.view.png | Bin .../data => training}/users-bulk-load.md | 10 ++- .../users-bulk-load/access.denied.png | Bin .../adding-places-cht-new-site.png | Bin .../adding-places-existing-spreadsheet.png | Bin .../users-bulk-load/bad.type.png | Bin .../importing-users-download-status-file.png | Bin .../importing-users-entering-data.png | Bin .../importing-users-export-csv.png | Bin .../importing-users-fix-errors.png | Bin ...mporting-users-import-csv-confirmation.png | Bin .../importing-users-import-csv.png | Bin .../importing-users-import-fixed-csv.png | Bin .../importing-users-import-progress.png | Bin ...mporting-users-populate-parents-places.png | Bin .../importing-users-transfer-errors.png | Bin .../users-spreadsheet-warning.png | Bin .../users-bulk-load/users-spreadsheet.png | Bin .../users-bulk-load/valid.roles.png | Bin .../tutorials/application-settings.md | 6 +- .../building/tutorials/application-tests.md | 4 +- content/en/building/users.md | 4 +- .../contributing/code/android/releasing.md | 4 +- .../code/test-data}/csv-to-docs.md | 1 + .../code/test-data}/test-data-generator.md | 1 + .../code/troubleshooting}/invalid-reports.md | 2 + .../invalid-reports/invalid_report.png | Bin .../replicating-production-data-locally.md | 3 +- .../creating-good-first-issues.md | 4 +- content/en/hosting/analytics/_index.md | 2 +- .../hosting/analytics/building-dbt-models.md | 8 +- .../couch2pg-to-cht-sync-migration.md | 2 +- .../hosting/couch2pg/couch2pg-oom-errors.md | 2 +- content/en/hosting/monitoring/dashboards.md | 2 +- content/en/releases/3_10_0.md | 2 +- content/en/releases/3_14_0.md | 4 +- content/en/releases/3_17_0.md | 2 +- content/en/releases/3_7_0.md | 2 +- content/en/releases/3_8_0.md | 2 +- content/en/releases/4_18_0.md | 4 +- .../architecture/cht-sync.md | 2 +- .../concepts}/impact-metrics.md | 5 +- .../concepts/offline-first.md | 2 +- .../data}/_index.md | 11 +-- .../data/analytics/_index.md | 18 ++++ .../analytics}/data-flows-for-analytics.md | 7 +- .../data-flows-for-analytics/data-flows.png | Bin .../data/analytics}/muting_in_dashboards.md | 3 +- .../analytics}/querying_apdex_telemetry.md | 9 +- .../querying_training_card_telemetry.md | 11 +-- .../data/analytics}/rdbms-from-mac.md | 5 +- .../rdbms-from-mac/connection-settings.png | Bin .../rdbms-from-mac/ssh-commands.png | Bin .../analytics}/rdbms-from-mac/terminal.png | Bin .../data/analytics}/rdbms-from-windows.md | 5 +- .../rdbms-from-windows/putty-add-key.png | Bin .../putty-connect-final.png | Bin .../rdbms-from-windows/putty-connect.png | Bin .../rdbms-from-windows/putty-gen-import.png | Bin .../rdbms-from-windows/putty-save-key.png | Bin .../puttygen-run-key-generate.png | Bin .../rdbms-from-windows/rdbms_connect_1.png | Bin .../rdbms-from-windows/rdbms_connect_2.png | Bin .../data/audit.md | 8 +- .../data}/couchdb-authentication.md | 3 +- .../data}/database-conflicts.md | 3 +- .../{concepts => data}/db-schema.md | 12 ++- .../data/hydration.md | 5 +- .../data}/performance/_index.md | 3 +- .../data}/performance/purging.md | 3 +- .../data}/performance/replication.md | 3 +- .../data}/performance/telemetry.md | 4 +- 100 files changed, 251 insertions(+), 170 deletions(-) rename content/en/building/{guides/android => branding}/publishing.md (87%) delete mode 100644 content/en/building/guides/android/_index.md delete mode 100644 content/en/building/guides/data/_index.md rename content/en/building/{guides/data => training}/training-instance.md (98%) rename content/en/building/{guides/data => training}/training-instance/create.view.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load.md (98%) rename content/en/building/{guides/data => training}/users-bulk-load/access.denied.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/adding-places-cht-new-site.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/adding-places-existing-spreadsheet.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/bad.type.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/importing-users-download-status-file.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/importing-users-entering-data.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/importing-users-export-csv.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/importing-users-fix-errors.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/importing-users-import-csv-confirmation.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/importing-users-import-csv.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/importing-users-import-fixed-csv.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/importing-users-import-progress.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/importing-users-populate-parents-places.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/importing-users-transfer-errors.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/users-spreadsheet-warning.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/users-spreadsheet.png (100%) rename content/en/building/{guides/data => training}/users-bulk-load/valid.roles.png (100%) rename content/en/{building/guides/data => community/contributing/code/test-data}/csv-to-docs.md (99%) rename content/en/{building => community/contributing/code/test-data}/test-data-generator.md (99%) rename content/en/{building/guides/data => community/contributing/code/troubleshooting}/invalid-reports.md (94%) rename content/en/{building/guides/data => community/contributing/code/troubleshooting}/invalid-reports/invalid_report.png (100%) rename content/en/{building/guides/debugging => community/contributing/code/troubleshooting}/replicating-production-data-locally.md (98%) rename content/en/{building/guides/data => technical-overview/concepts}/impact-metrics.md (96%) rename content/en/{building/guides/database => technical-overview/data}/_index.md (88%) create mode 100644 content/en/technical-overview/data/analytics/_index.md rename content/en/technical-overview/{concepts => data/analytics}/data-flows-for-analytics.md (98%) rename content/en/technical-overview/{concepts => data/analytics}/data-flows-for-analytics/data-flows.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/muting_in_dashboards.md (97%) rename content/en/{building/guides/database => technical-overview/data/analytics}/querying_apdex_telemetry.md (88%) rename content/en/{building/guides/database => technical-overview/data/analytics}/querying_training_card_telemetry.md (85%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-mac.md (96%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-mac/connection-settings.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-mac/ssh-commands.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-mac/terminal.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-windows.md (95%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-windows/putty-add-key.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-windows/putty-connect-final.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-windows/putty-connect.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-windows/putty-gen-import.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-windows/putty-save-key.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-windows/puttygen-run-key-generate.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-windows/rdbms_connect_1.png (100%) rename content/en/{building/guides/database => technical-overview/data/analytics}/rdbms-from-windows/rdbms_connect_2.png (100%) rename content/en/{building/guides => technical-overview}/data/audit.md (99%) rename content/en/{building/guides/database => technical-overview/data}/couchdb-authentication.md (92%) rename content/en/{building/guides/database => technical-overview/data}/database-conflicts.md (99%) rename content/en/technical-overview/{concepts => data}/db-schema.md (96%) rename content/en/{building/guides => technical-overview}/data/hydration.md (96%) rename content/en/{building/guides => technical-overview/data}/performance/_index.md (85%) rename content/en/{building/guides => technical-overview/data}/performance/purging.md (99%) rename content/en/{building/guides => technical-overview/data}/performance/replication.md (99%) rename content/en/{building/guides => technical-overview/data}/performance/telemetry.md (99%) diff --git a/.github/scripts/check.urls.sh b/.github/scripts/check.urls.sh index a74e74092f..051569f803 100755 --- a/.github/scripts/check.urls.sh +++ b/.github/scripts/check.urls.sh @@ -11,37 +11,93 @@ get_response_code() { # Function to check for meta refresh tag in HTML content check_meta_refresh() { local html_content=$1 - url=$2 + local url=$2 if grep -q ' $redirect_url $redirect_response_code " + redirects+=("${url} Is redirected! Result is:") + redirects+=(" -> $redirect_url $redirect_response_code") fi } + run_checks(){ echo prod_urls=$1 local count=0 - # Loop through each URL in the file + local redirects=() + local not_found=() + local other_errors=() + + echo "Checking URLs, please wait..." + + # Loop through each URL in the file and collect results while IFS= read -r url; do [ -z "$url" ] && continue ((count++)) - # Get HTTP response code, if it's not 200, print it so they know - response_code=$(get_response_code "$url") - if [ "$response_code" -ne 200 ]; then - echo "$url $response_code" + + # Show progress every 10 URLs + if [ $((count % 10)) -eq 0 ]; then + echo "Checked: $count URLs..." fi - # If response code is 200, check for meta refresh tag + # Get HTTP response code + response_code=$(get_response_code "$url") + if [ "$response_code" -eq 200 ]; then + # Check for meta refresh tag (redirects) html_content=$(curl -s "$url") check_meta_refresh "$html_content" "$url" + elif [ "$response_code" -eq 404 ]; then + not_found+=("$url $response_code") + elif [ "$response_code" -ne 200 ]; then + other_errors+=("$url $response_code") fi + done <<< "$prod_urls" + + echo "Finished checking $count URLs." + echo + + # Output results in desired order + if [ ${#redirects[@]} -gt 0 ]; then + echo "=== REDIRECTS (200 with meta refresh) ===" + for redirect in "${redirects[@]}"; do + echo "$redirect" + done + echo + fi + + if [ ${#other_errors[@]} -gt 0 ]; then + echo "=== OTHER ERRORS ===" + for error in "${other_errors[@]}"; do + echo "$error" + done + echo + fi + + if [ ${#not_found[@]} -gt 0 ]; then + echo "=== 404 NOT FOUND ===" + for nf in "${not_found[@]}"; do + echo "$nf" + done + echo + fi + + # Summary + redirect_count=${#redirects[@]} + # Divide by 2 since each redirect has 2 lines + redirect_count=$((redirect_count / 2)) + other_error_count=${#other_errors[@]} + not_found_count=${#not_found[@]} + + echo "=== SUMMARY ===" + echo "Total URLs checked: $count" + echo "Redirects (200): $redirect_count" + echo "Other errors: $other_error_count" + echo "404 Not Found: $not_found_count" } get_urls_from_prod_site_map(){ @@ -52,15 +108,16 @@ get_urls_from_prod_site_map(){ echo "$urls" } -echo;echo "Are you on a test branch and is hugo running on http://localhost:1313 ?";echo +echo;echo "Are you on a test branch and you deleted your "'./public'" folder before running hugo on http://localhost:1313 ?";echo read -p "\"y\" to proceed, \"n\" to cancel " -n 1 -r echo # (optional) move to a new line if [[ ! $REPLY =~ ^[nN]$ ]] then +# clear_cache echo;echo "Fetching URLs from production." prod_urls=$(get_urls_from_prod_site_map) url_count=$(echo "$prod_urls" | tr -cd '\n' | wc -l | tr -d ' ') - echo "Found ${url_count} URLs to check, be patient. Any non 200 URLs will be listed here:" + echo "Found ${url_count} URLs to check, be patient." run_checks "$prod_urls" echo;echo "Successfully checked ${url_count} URLs!";echo; fi diff --git a/content/en/building/branding/android.md b/content/en/building/branding/android.md index 80f6936ca5..419278ed35 100644 --- a/content/en/building/branding/android.md +++ b/content/en/building/branding/android.md @@ -237,7 +237,7 @@ Releasing a new flavor requires the following steps: ### 6. Publish the app -The last step is to publish it in the Play Store, or whatever option best suit your needs. Checkout the [Publishing]({{< ref "building/guides/android/publishing" >}}) page to see all the options available and instructions. +The last step is to publish it in the Play Store, or whatever option best suit your needs. Checkout the [Publishing]({{< ref "building/branding/publishing" >}}) page to see all the options available and instructions. ## Android App Links verification *Supported for CHT Core 4.7.0+ and CHT Android 1.3.0+* diff --git a/content/en/building/guides/android/publishing.md b/content/en/building/branding/publishing.md similarity index 87% rename from content/en/building/guides/android/publishing.md rename to content/en/building/branding/publishing.md index d896eb13f9..f82ec47cc3 100644 --- a/content/en/building/guides/android/publishing.md +++ b/content/en/building/branding/publishing.md @@ -1,21 +1,24 @@ --- title: "Publishing" linkTitle: "Publishing" -weight: 4 +weight: 2 description: > - Instructions for publishing Android Apps + Instructions for releasing Android Apps relatedContent: > - community/contributing/code/android/releasing + building/branding/publishing building/branding/android - building/guides/security/securing-android aliases: > /apps/guides/hosting/android-app/ /core/guides/android/publishing /core/guides/android/ /apps/guides/android/publishing/ + /building/guides/android/publishing/ + /building/guides/android/ --- -Once the flavor is [built]({{< ref "building/branding/android" >}}) there are many different ways to publish the binaries for installation. +## Publishing + +Once the flavor is [bui````lt]({{< ref "building/branding/android" >}}) there are many different ways to publish the binaries for installation. ### Google Play Store @@ -26,10 +29,10 @@ One of the downsides is it can be more difficult to get your app published and i For this method you will need access to the organization's play store console with permission to publish the app. In the [Google Play Console](https://play.google.com/console), for each flavor to publish: - - Create a new `Production` release - - Upload the `arm64` app bundles (from the GitHub Release) for the flavor. If you plan on uploading multiple APKs, the APKs should have different version codes. Read more: [here](https://developer.android.com/google/play/publishing/multiple-apks#Rules). - - Use the new cht-android version as the Release name - - Add a one sentence summary of the CHANGELOG entry as the Release notes. +- Create a new `Production` release +- Upload the `arm64` app bundles (from the GitHub Release) for the flavor. If you plan on uploading multiple APKs, the APKs should have different version codes. Read more: [here](https://developer.android.com/google/play/publishing/multiple-apks#Rules). +- Use the new cht-android version as the Release name +- Add a one sentence summary of the CHANGELOG entry as the Release notes. For a more detailed explanation, follow this [doc](https://support.google.com/googleplay/android-developer/answer/9859751?hl=en). diff --git a/content/en/building/contact-management/contact-and-users-1.md b/content/en/building/contact-management/contact-and-users-1.md index 472251f1c5..8636fa1be3 100644 --- a/content/en/building/contact-management/contact-and-users-1.md +++ b/content/en/building/contact-management/contact-and-users-1.md @@ -6,8 +6,8 @@ description: > Create and edit contacts and users in the CHT UI relatedContent: > building/users - technical-overview/concepts/db-schema - building/guides/data/users-bulk-load + technical-overview/data/db-schema + building/training/users-bulk-load aliases: - /building/tutorials/contact-and-users-1/ - /apps/tutorials/contact-and-users-1 diff --git a/content/en/building/contact-management/contact-and-users-2.md b/content/en/building/contact-management/contact-and-users-2.md index 43dc61ddc6..9da477b900 100644 --- a/content/en/building/contact-management/contact-and-users-2.md +++ b/content/en/building/contact-management/contact-and-users-2.md @@ -6,8 +6,8 @@ description: > Create and edit contacts and users with cht-conf relatedContent: > building/contact-management/contact-and-users-1 - technical-overview/concepts/db-schema - building/guides/data/users-bulk-load + technical-overview/data/db-schema + building/training/users-bulk-load building/users aliases: - /building/tutorials/contact-and-users-2/ diff --git a/content/en/building/contact-management/contacts.md b/content/en/building/contact-management/contacts.md index 4a380e57e0..7c07fd2b59 100644 --- a/content/en/building/contact-management/contacts.md +++ b/content/en/building/contact-management/contacts.md @@ -21,7 +21,7 @@ aliases: “Places” is the generic name that represents a level in the [hierarchy]({{< ref "building/workflows/hierarchy" >}}). “People” belong to “places”, and “places” belong to other higher level “places” in the hierarchy. A “place” could be a geographic area, like a district with the "people" associated to it being health officers. A "place" could also be a structure in the health system, such as a health facility, and the "people" associated to it being nurses. In deployments with CHWs, the lowest "place" in the hierarchy often represents individual households or families, and the individual members of that household are the "people" associated to it. -Users can access their “people” and “places” from the **People** tab. The permissions set for your role and your placement in the hierarchy will determine which contacts you’re able to see. Advanced configuration options are available for a specific offline user role to manage what [level of contact data]({{< ref "building/guides/performance/replication#contact-depth" >}}) is downloaded and stored on their device. +Users can access their “people” and “places” from the **People** tab. The permissions set for your role and your placement in the hierarchy will determine which contacts you’re able to see. Advanced configuration options are available for a specific offline user role to manage what [level of contact data]({{< ref "technical-overview/data/performance/replication#contact-depth" >}}) is downloaded and stored on their device. {{< figure src="people-desktop.png" link="people-desktop.png" class="right col-6 col-lg-8 bordered-figure" >}} diff --git a/content/en/building/contact-management/user-management-tool.md b/content/en/building/contact-management/user-management-tool.md index a783638fc0..02a5e03d45 100644 --- a/content/en/building/contact-management/user-management-tool.md +++ b/content/en/building/contact-management/user-management-tool.md @@ -6,7 +6,7 @@ description: > How to use and configure a user management tool for a CHT project relatedContent: > building/contact-management/contact-and-users-1 - building/guides/data/users-bulk-load + building/training/users-bulk-load aliases: - /building/tutorials/user-management-tool/ - /apps/tutorials/user-management-tool diff --git a/content/en/building/contact-summary/contact-summary-templated.md b/content/en/building/contact-summary/contact-summary-templated.md index 8299372485..cffe68ab80 100644 --- a/content/en/building/contact-summary/contact-summary-templated.md +++ b/content/en/building/contact-summary/contact-summary-templated.md @@ -21,7 +21,7 @@ Helper variables and functions for the contact summary can be defined in `contac | `contact` | The currently selected contact. This has minimal stubs for the `contact.parent`, so if you want to refer to a property on the parent use `lineage` below.| | `reports` | An array of reports for the contact or for any of the contact's `person` children. Note that if the contact has more than 500 reports, only the 500 with the latest `reported_date` values will be provided. Prior to version `4.7.0`, only 50 reports were provided. | | `lineage` | An array of the contact's parents (2.13+), eg `lineage[0]` is the parent, `lineage[1]` is the grandparent, etc. Each lineage entry has full information for the contact, so you can use `lineage[1].contact.phone`. `lineage` will include only those contacts which are visible to the logged in profile | -| `targetDoc` | Doc with [`target`]({{< ref "technical-overview/concepts/db-schema#targets" >}} ) document of the contact, hydrated with the config information of every target it contains a value for. If there is no target document available (for example when viewing a contact that does not upload targets), this value will be `undefined`. This value might also be `undefined` if the contact has not yet synced the current target document. Added in `3.9.0`. | +| `targetDoc` | Doc with [`target`]({{< ref "technical-overview/data/db-schema#targets" >}} ) document of the contact, hydrated with the config information of every target it contains a value for. If there is no target document available (for example when viewing a contact that does not upload targets), this value will be `undefined`. This value might also be `undefined` if the contact has not yet synced the current target document. Added in `3.9.0`. | | `uhcStats` | Object containing UHC stats information. Added in `v3.12.0` | | `uhcStats.uhcInterval` | Object containing the start and end date of UHC reporting period, it is calculated from the `uhc.visit_count.month_start_date` defined in the [app settings]({{< ref "/building/reference/app-settings/#app_settingsjson" >}}). | | `uhcStats.uhcInterval.start` | Timestamp, start date of the UHC reporting period. | diff --git a/content/en/building/forms/configuring/form-inputs.md b/content/en/building/forms/configuring/form-inputs.md index 88ca2b1de0..095ad7791f 100644 --- a/content/en/building/forms/configuring/form-inputs.md +++ b/content/en/building/forms/configuring/form-inputs.md @@ -120,7 +120,7 @@ The following fields will also be available in the `inputs` group: ## `user` data -Both `app` and `contact` forms can access the current user's data at `inputs/user`. The data provided is simply the [`user-settings` doc for the user]({{< ref "technical-overview/concepts/db-schema#users" >}}) (e.g. `org.couchdb.user:username`) plus an additional `language` field that contains the user's currently selected language code. +Both `app` and `contact` forms can access the current user's data at `inputs/user`. The data provided is simply the [`user-settings` doc for the user]({{< ref "technical-overview/data/db-schema#users" >}}) (e.g. `org.couchdb.user:username`) plus an additional `language` field that contains the user's currently selected language code. {{< callout type="info" >}} The `user-settings` doc for the user is _NOT_ the same as the CHT _contact_ doc for the user. diff --git a/content/en/building/guides/android/_index.md b/content/en/building/guides/android/_index.md deleted file mode 100644 index 8ac0a87a1e..0000000000 --- a/content/en/building/guides/android/_index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: "Android app development" -linkTitle: "Android" - -weight: 150 -description: > - Guides for developing a CHT Android application -relatedContent: > - building/login/#accessing-on-mobile -aliases: > - /core/guides/android/ -aliases: - - /apps/guides/android/ ---- - -The Community Health Toolkit includes 2 apps that are currently supported: the **[CHT Android](https://github.com/medic/cht-android)** and the **[CHT Gateway](https://github.com/medic/cht-gateway)**. The following guides will help you setup a development environment in your local computer to improve, release, and brand the apps (branding only applies to CHT Android). - -**[Medic Collect](https://github.com/medic/medic-collect)** is currently in maintenance mode, although some of the guides here may apply if you need to work with it. diff --git a/content/en/building/guides/data/_index.md b/content/en/building/guides/data/_index.md deleted file mode 100644 index 14c2768243..0000000000 --- a/content/en/building/guides/data/_index.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: "Managing Data" -linkTitle: "Data" -weight: 100 -description: > - Creating and managing data in CHT applications -aliases: - - /apps/guides/data/ ---- - -{{< subpages >}} diff --git a/content/en/building/guides/debugging/obtaining-logs.md b/content/en/building/guides/debugging/obtaining-logs.md index 23824bfafc..e4ddc38664 100644 --- a/content/en/building/guides/debugging/obtaining-logs.md +++ b/content/en/building/guides/debugging/obtaining-logs.md @@ -83,4 +83,4 @@ adb logcat | grep MedicMobile > phone.log ## On the server -Some unexpected errors are caught and stored in `feedback` docs and stored on the phone and later synced to CouchDB on the server. To access these, look for docs in the `medic-user-{username}-meta` or `medic-users-meta` databases. This is particularly useful to debug issues where you do not have physical access to the device. More information is available under [Managing Databases]({{< relref "building/guides/database" >}}). +Some unexpected errors are caught and stored in `feedback` docs and stored on the phone and later synced to CouchDB on the server. To access these, look for docs in the `medic-user-{username}-meta` or `medic-users-meta` databases. This is particularly useful to debug issues where you do not have physical access to the device. More information is available under [Managing Databases]({{< relref "technical-overview/data" >}}). diff --git a/content/en/building/guides/security/securely-onboarding-users-at-scale.md b/content/en/building/guides/security/securely-onboarding-users-at-scale.md index 6cfb8adfbf..0f3508b5c1 100644 --- a/content/en/building/guides/security/securely-onboarding-users-at-scale.md +++ b/content/en/building/guides/security/securely-onboarding-users-at-scale.md @@ -6,9 +6,9 @@ description: > How to securely create users, handle password changes and password breaches relatedContent: > building/training/onboarding - building/guides/database/couchdb-authentication + technical-overview/data/couchdb-authentication building/contact-management/contact-and-users-1 - building/guides/data/users-bulk-load + building/training/users-bulk-load building/users building/login/#magic-links-for-logging-in-token-login @@ -26,7 +26,7 @@ When a CHT deployment will support hundreds of users or more, secure credential ### Secure devices -Firstly, ensure that the CHWs' devices are secure: they all employ disk encryption and require a password or PIN to unlock and use. See our [Securing Android Devices document]({{% ref "building/guides/security/securing-android" %}}) for more information. As well, an [MDM]({{% ref "building/guides/android/publishing#mobile-device-management" %}}) may be used to enforce disk encryption and device unlock protocols. +Firstly, ensure that the CHWs' devices are secure: they all employ disk encryption and require a password or PIN to unlock and use. See our [Securing Android Devices document]({{% ref "building/guides/security/securing-android" %}}) for more information. As well, an [MDM]({{% ref "building/branding/publishing#mobile-device-management" %}}) may be used to enforce disk encryption and device unlock protocols. ### Secure administrative users @@ -65,7 +65,7 @@ When it comes time get a username and password onto a device or to a remote user ### Ideal practice 1: Only Magic Links -Create a spreadsheet with all your users' data. Included is a username but NOT a password. When users are created in bulk via [the command line]({{% ref "building/guides/data/csv-to-docs#creating-csv-files-for-users" %}}) or [bulk user upload]({{% ref "building/guides/data/users-bulk-load" %}}), have a [token login]({{% ref "building/login#magic-links-for-logging-in-token-login" %}}) sent to the user via an SMS gateway. This avoids the problem of passwords being stored in clear text in the spreadsheet or on a printed version. The token login links can only be used once and are only valid for 24 hours. +Create a spreadsheet with all your users' data. Included is a username but NOT a password. When users are created in bulk via [the command line]({{% ref "/community/contributing/code/test-data/csv-to-docs#creating-csv-files-for-users" %}}) or [bulk user upload]({{% ref "building/training/users-bulk-load" %}}), have a [token login]({{% ref "building/login#magic-links-for-logging-in-token-login" %}}) sent to the user via an SMS gateway. This avoids the problem of passwords being stored in clear text in the spreadsheet or on a printed version. The token login links can only be used once and are only valid for 24 hours. ### Ideal practice 2: Unknown passwords, reset during provision diff --git a/content/en/building/guides/security/securing-android.md b/content/en/building/guides/security/securing-android.md index 5e24b7aa81..3391c40911 100644 --- a/content/en/building/guides/security/securing-android.md +++ b/content/en/building/guides/security/securing-android.md @@ -5,8 +5,8 @@ weight: description: > How to secure Android devices used in deployments relatedContent: > - building/guides/debugging/replicating-production-data-locally - building/guides/android/publishing + community/contributing/code/troubleshooting/replicating-production-data-locally + building/branding/publishing aliases: - /apps/guides/security/securing-android @@ -50,4 +50,4 @@ Android does not support disk encryption in versions earlier than 3.0 Using mobile device management (MDM) software allows administrators to remotely manage mobile devices, which often includes the option to delete apps and data from lost or stolen mobile devices. -{{< see-also page="building/guides/android/publishing" anchor="mobile-device-management" title="Publishing > Mobile Device Management" >}} +{{< see-also page="building/branding/publishing" anchor="mobile-device-management" title="Publishing > Mobile Device Management" >}} diff --git a/content/en/building/guides/updates/preparing-for-4.md b/content/en/building/guides/updates/preparing-for-4.md index 4db96df334..bb7d5654e9 100644 --- a/content/en/building/guides/updates/preparing-for-4.md +++ b/content/en/building/guides/updates/preparing-for-4.md @@ -21,11 +21,11 @@ Upgrading to CHT 4.0 can be quite time consuming, especially for large deployme ## CHT Android v1.0.0+ -This change is straightforward in that CHT 4.x no longer supports versions _before_ `1.0.0`, so deployments need to update their Play Store app. As of this writing, [CHT Android](https://github.com/medic/cht-android/) is at `1.0.4`. See the [Android docs]({{< relref "building/guides/android" >}}) on how to update your app and release it. Note that Google's Play Store can often have delays which deployments have no control over. Again, the sooner you start, the better. +This change is straightforward in that CHT 4.x no longer supports versions _before_ `1.0.0`, so deployments need to update their Play Store app. As of this writing, [CHT Android](https://github.com/medic/cht-android/) is at `1.0.4`. See the [Android docs]({{< relref "building/branding/android" >}}) on how to update your app and release it. Note that Google's Play Store can often have delays which deployments have no control over. Again, the sooner you start, the better. ### Versions in use -After you have published your app, you need to instruct your users to check the Play Store for upgrades. You can then check [CHT Telemetry]({{< relref "building/guides/performance/telemetry" >}}) to see what CHT Android versions are in use. Assuming you have [CHT Sync set up](https://github.com/medic/cht-sync) to pull in your CouchDB data to a PostgreSQL database, this query will list Android versions `count`s for the current year, broken out by `month`, `year` and `version`: +After you have published your app, you need to instruct your users to check the Play Store for upgrades. You can then check [CHT Telemetry]({{< relref "technical-overview/data/performance/telemetry" >}}) to see what CHT Android versions are in use. Assuming you have [CHT Sync set up](https://github.com/medic/cht-sync) to pull in your CouchDB data to a PostgreSQL database, this query will list Android versions `count`s for the current year, broken out by `month`, `year` and `version`: ```sql SELECT diff --git a/content/en/building/messaging/gateways/gateway/configuration.md b/content/en/building/messaging/gateways/gateway/configuration.md index 3fa0f4a709..c9c8d8f576 100644 --- a/content/en/building/messaging/gateways/gateway/configuration.md +++ b/content/en/building/messaging/gateways/gateway/configuration.md @@ -17,7 +17,7 @@ CHT gateway supports Android 4.1 and above. To have it up and fully working, fol ### Step 1 -Install the latest APK from the [releases page](https://github.com/medic/cht-gateway/releases) in the `cht-gateway` repo. This APK is not in the Play Store, you will need to side-load it [as is done with CHT Android]({{< ref "building/guides/android/publishing#side-loading" >}}). +Install the latest APK from the [releases page](https://github.com/medic/cht-gateway/releases) in the `cht-gateway` repo. This APK is not in the Play Store, you will need to side-load it [as is done with CHT Android]({{< ref "building/branding/publishing#side-loading" >}}). ### Step 2 diff --git a/content/en/building/navigation.md b/content/en/building/navigation.md index 988aa9c4d5..3804a3df80 100644 --- a/content/en/building/navigation.md +++ b/content/en/building/navigation.md @@ -50,7 +50,7 @@ Synchronization consists of upward replication and downward replication. The CHT application manages data synchronization across two types of databases: - **Main Application Database (`medic`)**: The main database that stores the primary data used by the application. It includes contacts, reports, messages, and other critical documents necessary for the core functionality of the application. This database is synchronized continuously to reflect changes to the application, such as new contact creations. Each user stores a subset of the main database which includes only the documents they're allowed to view. -- **User-Metadata Database(`medic-user-{username}-meta`)**: Each user has a dedicated database that stores operational metadata, including [telemetry data]({{< relref "building/guides/performance/telemetry" >}}) and error messages. Synchronization occurs at predefined intervals to ensure up-to-date monitoring and analysis. +- **User-Metadata Database(`medic-user-{username}-meta`)**: Each user has a dedicated database that stores operational metadata, including [telemetry data]({{< relref "technical-overview/data/performance/telemetry" >}}) and error messages. Synchronization occurs at predefined intervals to ensure up-to-date monitoring and analysis. #### Sync Status Notification diff --git a/content/en/building/reference/_partial_cht_api.md b/content/en/building/reference/_partial_cht_api.md index 08da62dbd4..f0bd8ed1b7 100644 --- a/content/en/building/reference/_partial_cht_api.md +++ b/content/en/building/reference/_partial_cht_api.md @@ -14,7 +14,7 @@ Provides CHT-Core Framework's functions to contact summary, targets and tasks. T | hasPermissions(permissions, userRoles, chtPermissionsSettings) | `permissions`: String or array of permission name(s).
`userRoles`: (Optional) Array of user roles. Default to the current logged in user.
`chtPermissionsSettings`: (Optional) Object of configured permissions in CHT-Core's settings. Default to the current instance's configured permissions. | Returns true if the user has the permission(s), otherwise returns false. | | hasAnyPermission(permissionsGroups, userRoles, chtPermissionsSettings) | `permissionsGroups`: Array of groups of permission name(s).
`userRoles`: (Optional) Array of user roles. Default to the current logged in user.
`chtPermissionsSettings`: (Optional) Object of configured permissions in CHT-Core's settings. Default to the current instance's configured permissions. | Returns true if the user has all the permissions of any of the provided groups, otherwise returns false. | | getExtensionLib(name) | `name`: String of script name | Returns an executable function identified by the given name configured as [extension-libs]({{< ref "extension-libs" >}}). -| analytics.getTargetDocs() | | Returns three [target]({{< ref "technical-overview/concepts/db-schema#targets" >}} ) documents of the contact, calculated for the last three reporting intervals, including the current one. When viewing one of the current logged in user's associated facilities, returns the target documents for the contact associated with the current logged in user. Returns an empty array if no target documents are found (for example when viewing a contact that does not upload targets). _Introduced in v4.11.0_ | +| analytics.getTargetDocs() | | Returns three [target]({{< ref "technical-overview/data/db-schema#targets" >}} ) documents of the contact, calculated for the last three reporting intervals, including the current one. When viewing one of the current logged in user's associated facilities, returns the target documents for the contact associated with the current logged in user. Returns an empty array if no target documents are found (for example when viewing a contact that does not upload targets). _Introduced in v4.11.0_ | ### CHT API's code samples diff --git a/content/en/building/reference/api.md b/content/en/building/reference/api.md index 8d76656588..7130c4fa00 100644 --- a/content/en/building/reference/api.md +++ b/content/en/building/reference/api.md @@ -14,7 +14,7 @@ aliases: } -This page covers the endpoints to use when integrating with the CHT server. If there isn't an endpoint that provides the function or data you need, direct access to the database is possible via the [CouchDB API](https://docs.couchdb.org/en/stable/api/index.html). Access to the [PostgreSQL database]({{< ref "technical-overview/concepts/data-flows-for-analytics" >}}) may also prove useful for data analysis. If additional endpoints would be helpful, make suggestions via a [GitHub issue](https://github.com/medic/cht-core/issues/new/choose). +This page covers the endpoints to use when integrating with the CHT server. If there isn't an endpoint that provides the function or data you need, direct access to the database is possible via the [CouchDB API](https://docs.couchdb.org/en/stable/api/index.html). Access to the [PostgreSQL database]({{< ref "technical-overview/data/analytics/data-flows-for-analytics" >}}) may also prove useful for data analysis. If additional endpoints would be helpful, make suggestions via a [GitHub issue](https://github.com/medic/cht-core/issues/new/choose). {{< toc >}} @@ -236,7 +236,7 @@ Returns a JSON array of CHT-related software versions for each user device. This |-----------------|------------------------------------------------------------------------------------------------------------------------------------------| | user | The user's name. | | deviceId | The unique key for the user's device. | -| date | The date the telemetry entry was taken in YYYY-MM-DD, see [relevant docs]({{< relref "building/guides/performance/telemetry" >}}). | +| date | The date the telemetry entry was taken in YYYY-MM-DD, see [relevant docs]({{< relref "technical-overview/data/performance/telemetry" >}}). | | browser.name | The name of the browser used. | | browser.version | The version of the browser used. | | apk | The Internal [version code](https://developer.android.com/reference/android/R.styleable#AndroidManifest_versionCode) of the Android app. | @@ -2613,14 +2613,14 @@ autocompletion on fields or dealing with names instead of long, unreadable ids. In order to facilitate this process, we have made available a spreadsheet compatible with the `default` configuration of the CHT. [Click here](https://docs.google.com/spreadsheets/d/1yUenFP-5deQ0I9c-OYDTpbKYrkl3juv9djXoLLPoQ7Y/copy) to make a copy of the spreadsheet in Google Sheets. -[A guide]({{< ref "building/guides/data/users-bulk-load" >}}) on how to import users with this spreadsheet from within the Admin Console is available +[A guide]({{< ref "building/training/users-bulk-load" >}}) on how to import users with this spreadsheet from within the Admin Console is available in case you don't want to interact with this API yourself. #### Logging A log entry is created with each bulk import that contains the import status for each user and the import progress status that gets updated throughout the import and finalized upon completion. -These entries are saved in the [`medic-logs`]({{< ref "building/guides/database#medic-logs" >}}) database and you can access them +These entries are saved in the [`medic-logs`]({{< ref "technical-overview/data#medic-logs" >}}) database and you can access them by querying documents with a key that starts with `bulk-user-upload-`. #### Headers diff --git a/content/en/building/reference/app-settings/transitions.md b/content/en/building/reference/app-settings/transitions.md index 4e57a1072a..63becd5b4d 100644 --- a/content/en/building/reference/app-settings/transitions.md +++ b/content/en/building/reference/app-settings/transitions.md @@ -482,7 +482,7 @@ Configuration is stored in the `muting` field of `app_settings.json`. | `messages` | List of tasks/errors that will be created, determined by `event_type`. Optional. | > [!IMPORTANT] -> Contact forms cannot trigger muting or unmuting, but any `data_record` that has a `form` property (typically a [Report]({{< ref "technical-overview/concepts/db-schema#reports" >}})) can. +> Contact forms cannot trigger muting or unmuting, but any `data_record` that has a `form` property (typically a [Report]({{< ref "technical-overview/data/db-schema#reports" >}})) can. Supported `events_types` are: diff --git a/content/en/building/reports/_index.md b/content/en/building/reports/_index.md index 71f9cd0a95..f1706b8954 100644 --- a/content/en/building/reports/_index.md +++ b/content/en/building/reports/_index.md @@ -5,7 +5,7 @@ description: > Data & report management in the CHT relatedContent: > building/reference/app-settings/patient_reports - building/guides/data/invalid-reports + community/contributing/code/troubleshooting/invalid-reports building/forms/configuring/report-titles aliases: - /apps/features/reports/ diff --git a/content/en/building/reports/reports-overview.md b/content/en/building/reports/reports-overview.md index ef86edfd7c..9b36031d26 100644 --- a/content/en/building/reports/reports-overview.md +++ b/content/en/building/reports/reports-overview.md @@ -9,7 +9,7 @@ description: > The Reports tab is where you can access submitted data. Depending on how often you anticipate a user needing to access this tab, you can configure it to show in the main tabs list (preferable for admin users) or in the secondary hamburger menu (preferable for CHW users). -The permissions set for your role and your placement in the hierarchy will determine which reports you’re able to see on this tab. As a rule, you can only view reports submitted by yourself or those below you in the [hierarchy]({{< ref "building/workflows/hierarchy" >}}). Therefore, CHWs will only see reports that they submitted on this tab, while supervisors will see reports that they submitted as well as those submitted by their CHWs. Advanced configuration options are available for a specific off-line user role to manage what [level of report data]({{< ref "building/guides/performance/replication#report-depth" >}}) is copied to their device. +The permissions set for your role and your placement in the hierarchy will determine which reports you’re able to see on this tab. As a rule, you can only view reports submitted by yourself or those below you in the [hierarchy]({{< ref "building/workflows/hierarchy" >}}). Therefore, CHWs will only see reports that they submitted on this tab, while supervisors will see reports that they submitted as well as those submitted by their CHWs. Advanced configuration options are available for a specific off-line user role to manage what [level of report data]({{< ref "technical-overview/data/performance/replication#report-depth" >}}) is copied to their device. {{< figure src="reports-desktop.png" link="reports-desktop.png" class="left col-9 col-lg-9" >}} diff --git a/content/en/building/targets/targets-overview.md b/content/en/building/targets/targets-overview.md index 2e1a61858c..a5a58bd558 100644 --- a/content/en/building/targets/targets-overview.md +++ b/content/en/building/targets/targets-overview.md @@ -5,7 +5,7 @@ description: > Dashboards to track metrics for an individual CHW or for an entire health facility relatedContent: > building/targets/targets-js - technical-overview/concepts/db-schema#targets + technical-overview/data/db-schema#targets building/integrations/dhis2 building/supervision/#chw-aggregate-targets aliases: diff --git a/content/en/building/tasks/managing-tasks/query-task-data.md b/content/en/building/tasks/managing-tasks/query-task-data.md index 7ad82565c6..61f5f275ed 100644 --- a/content/en/building/tasks/managing-tasks/query-task-data.md +++ b/content/en/building/tasks/managing-tasks/query-task-data.md @@ -5,8 +5,8 @@ description: > Querying the data which results from an example task. Notes on the performance implications of tasks. relatedContent: > building/tasks/simple-tasks - technical-overview/concepts/db-schema#tasks - technical-overview/concepts/data-flows-for-analytics + technical-overview/data/db-schema#tasks + technical-overview/data/analytics/data-flows-for-analytics aliases: - /apps/guides/tasks/query-task-data --- @@ -19,12 +19,12 @@ This guide explains the data which results from tasks and how to query it. ## Prerequisites -* [Data Flows for Analytics]({{< ref "technical-overview/concepts/data-flows-for-analytics" >}}) +* [Data Flows for Analytics]({{< ref "technical-overview/data/analytics/data-flows-for-analytics" >}}) ## Querying task data -The task system running on each user's device is powered by [task documents]({{< ref "technical-overview/concepts/db-schema#tasks" >}}) and those task documents sync to the server and to PostgreSQL just like a contact or a report. Having task documents in PostgreSQL allows system administrators to analyse how users are interacting with tasks. +The task system running on each user's device is powered by [task documents]({{< ref "technical-overview/data/db-schema#tasks" >}}) and those task documents sync to the server and to PostgreSQL just like a contact or a report. Having task documents in PostgreSQL allows system administrators to analyse how users are interacting with tasks. -{{< see-also page="technical-overview/concepts/data-flows-for-analytics" title="Data flows for analytics" >}} +{{< see-also page="technical-overview/data/analytics/data-flows-for-analytics" title="Data flows for analytics" >}} ### First Assessment Completion Rate Working with the _First Assessment_ task from the [Configuring Tasks Tutorial]({{< ref "building/tasks/simple-tasks" >}}), let's try to answer the question **What percentage of the scheduled _first assessment_ events have been completed?**. @@ -66,8 +66,8 @@ module.exports = [{ ``` **What is this code doing?** -* `useview_task` - This is a materialized view of the data from the [task document schema]({{< ref "technical-overview/concepts/db-schema#tasks" >}}). -* `task_state` - The meaning of each task state is explained in the [task document schema]({{< ref "technical-overview/concepts/db-schema#tasks" >}}). +* `useview_task` - This is a materialized view of the data from the [task document schema]({{< ref "technical-overview/data/db-schema#tasks" >}}). +* `task_state` - The meaning of each task state is explained in the [task document schema]({{< ref "technical-overview/data/db-schema#tasks" >}}). * `WHERE title` - The _name_ attribute in the [task.js schema]({{< ref "building/tasks/tasks-js#tasksjs" >}}) is used exclusively in the task's backend data. Here we limit the query to task documents resulting from our named task. The `title` in postgres maps to the `name` in JavaScript not the `title` in JavaScript - which is confusing. * `WHERE duedate` - One task document is created per event and this task has one event per contact which is due 7 days after the contact's creation date. Here we limit the query to task documents which are _due in the last 3 calendar months_. diff --git a/content/en/building/tasks/managing-tasks/task-schema-parameters.md b/content/en/building/tasks/managing-tasks/task-schema-parameters.md index 6854ead1d0..354c7d0ad9 100644 --- a/content/en/building/tasks/managing-tasks/task-schema-parameters.md +++ b/content/en/building/tasks/managing-tasks/task-schema-parameters.md @@ -5,9 +5,9 @@ description: > Understanding the data which is passed into Task interfaces relatedContent: > building/tasks/tasks-js - building/guides/data/hydration - technical-overview/concepts/db-schema#contacts-persons-and-places - technical-overview/concepts/db-schema#reports + technical-overview/data/hydration + technical-overview/data/db-schema#contacts-persons-and-places + technical-overview/data/db-schema#reports building/tasks/simple-tasks aliases: @@ -22,13 +22,13 @@ This guide explains the parameters available in the Task Schema and important co Let's synthesize some knowledge about CHT applications to help clarify what is happening within the task system: -1. All contacts in CHT applications are organised into hierarchies. For more information, read the [Contact and User Management Tutorial]({{< ref "building/contact-management/contact-and-users-1" >}}) or [schema for contact documents]({{< ref "technical-overview/concepts/db-schema#contacts-persons-and-places" >}}). +1. All contacts in CHT applications are organised into hierarchies. For more information, read the [Contact and User Management Tutorial]({{< ref "building/contact-management/contact-and-users-1" >}}) or [schema for contact documents]({{< ref "technical-overview/data/db-schema#contacts-persons-and-places" >}}). -2. All reports in the system are linked to one (and only one) contact. For more information, read [App Forms Tutorial]({{< ref "building/tutorials/app-forms" >}}) or the [schema for report documents]({{< ref "technical-overview/concepts/db-schema#reports" >}}). +2. All reports in the system are linked to one (and only one) contact. For more information, read [App Forms Tutorial]({{< ref "building/tutorials/app-forms" >}}) or the [schema for report documents]({{< ref "technical-overview/data/db-schema#reports" >}}). -3. Documents are stored [minified]({{< ref "building/guides/data/hydration" >}}) (not hydrated). All data that is passed into the tasks system is minified. +3. Documents are stored [minified]({{< ref "technical-overview/data/hydration" >}}) (not hydrated). All data that is passed into the tasks system is minified. -4. Settings which control the documents which are available on the user's device are an important considerations to remember (eg [replication depth]({{< ref "building/guides/performance/replication#depth" >}}) or [purging]({{< ref "building/guides/performance/purging" >}})) since both tasks can only process docs which are present on the device. +4. Settings which control the documents which are available on the user's device are an important considerations to remember (eg [replication depth]({{< ref "technical-overview/data/performance/replication#depth" >}}) or [purging]({{< ref "technical-overview/data/performance/purging" >}})) since both tasks can only process docs which are present on the device. > [!IMPORTANT] > The code in `tasks.js` runs on the user's devices, not in the cloud and not on a server. diff --git a/content/en/building/training/onboarding/_index.md b/content/en/building/training/onboarding/_index.md index a36bdda007..7fd3e871f7 100644 --- a/content/en/building/training/onboarding/_index.md +++ b/content/en/building/training/onboarding/_index.md @@ -15,7 +15,7 @@ aliases: When onboarding new users, having a dedicated CHT app and instance for training can be helpful; it allows new users to do training exercises with mock data to get familiar with the app, while not having the data from their training interfering with the future use of their CHT app. Different approaches are possible, such as only entering real patient data during training, or manually deleting all the training data, but these methods are less practical for large deployments. > [!NOTE] -> The suggestions in this guide should be assessed and adapted as needed to benefit a deployment. It is important that users don't accidentally use the wrong app. The [troubleshooting guide]({{< relref "building/guides/data/training-instance" >}}) can help to monitor and remediate training data being in the production instance, or the opposite. +> The suggestions in this guide should be assessed and adapted as needed to benefit a deployment. It is important that users don't accidentally use the wrong app. The [troubleshooting guide]({{< relref "building/training/training-instance" >}}) can help to monitor and remediate training data being in the production instance, or the opposite. ## Setting up a training app @@ -41,4 +41,4 @@ If the production app can always be installed after the use of the training is c Changing passwords for the training users in an attempt to lock them out is not recommended. In some circumstances a user would be able to continue to use the training app for production use and not have the data sync back to the server. -It is preferable to remove the training app from devices, and [monitor the training instance for unexpected activity]({{< relref "building/guides/data/training-instance" >}}) that can be brought over to the production instance if needed. +It is preferable to remove the training app from devices, and [monitor the training instance for unexpected activity]({{< relref "building/training/training-instance" >}}) that can be brought over to the production instance if needed. 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 e70a40befa..090b1cc337 100644 --- a/content/en/building/training/training-cards/training-cards-configuration.md +++ b/content/en/building/training/training-cards/training-cards-configuration.md @@ -107,7 +107,7 @@ cht --url=http://admin-user:secretpass@my-xyz-project.org upload-training-forms At this point the training cards are ready to use. You can verify by logging in with a user that has a valid role assigned for the training card, on the day that the training starts. Remember, to sync the app to see the results (the uncompleted training will display once a day). -Using [telemetry]({{< relref "building/guides/performance/telemetry" >}}) you can monitor user interaction with each training card "set". Some key metrics you can view include: +Using [telemetry]({{< relref "technical-overview/data/performance/telemetry" >}}) you can monitor user interaction with each training card "set". Some key metrics you can view include: 1. Number of times each user was presented with training cards 2. The date(s) each user was presented with training cards diff --git a/content/en/building/guides/data/training-instance.md b/content/en/building/training/training-instance.md similarity index 98% rename from content/en/building/guides/data/training-instance.md rename to content/en/building/training/training-instance.md index 9941fd4fa5..e509525c4e 100644 --- a/content/en/building/guides/data/training-instance.md +++ b/content/en/building/training/training-instance.md @@ -7,14 +7,15 @@ description: > aliases: - /apps/guides/data/training-instance + - /building/guides/data/training-instance --- After [onboarding CHWs]({{< relref "building/training/onboarding" >}}), sometimes data ends up on the wrong CHT instance. There are some passive and active actions you can take to help deal with this situation. -## Monitoring +## Monitoring`` Monitoring is a good way to see if CHWs are sending forms to the wrong CHT server. By catching such a problem early, it may be easy to fix manually which avoids more laborious fixes on the command line for admins. - +`` ### Manual device checks Supervisors can actively monitor CHWs as they register their first household. If each CHW is given a deadline to do this, the Supervisor can follow up promptly with CHWs who have not met the deadline. diff --git a/content/en/building/guides/data/training-instance/create.view.png b/content/en/building/training/training-instance/create.view.png similarity index 100% rename from content/en/building/guides/data/training-instance/create.view.png rename to content/en/building/training/training-instance/create.view.png diff --git a/content/en/building/guides/data/users-bulk-load.md b/content/en/building/training/users-bulk-load.md similarity index 98% rename from content/en/building/guides/data/users-bulk-load.md rename to content/en/building/training/users-bulk-load.md index 0a0ec78b29..6354fc705a 100644 --- a/content/en/building/guides/data/users-bulk-load.md +++ b/content/en/building/training/users-bulk-load.md @@ -1,21 +1,23 @@ --- title: "How to bulk load users" linkTitle: "Bulk Load Users" -weight: 15 +weight: 15`` description: > How to create users in bulk aliases: - - /core/guides/users-bulk-load + - /core/guides/users-bulk-load - /apps/guides/data/users-bulk-load/ + - /building/training/users-bulk-load + - /building/guides/data/users-bulk-load/ relatedContent: > - building/guides/data/csv-to-docs + /community/contributing/code/test-data/csv-to-docs building/reference/api/#post-apiv2users building/admin --- {{< callout >}} - The bulk user upload feature is available in 3.16.0 and later versions of the CHT. As of CHT 3.17.0, when creating both a contact and a place, the contact will be set as the default contact of the place. User creation can be scripted using the [CHT API]({{< relref "building/reference/api#post-apiv2users" >}}) directly or using the [`cht-conf` tool](https://github.com/medic/cht-conf), which is detailed in the [CSV-to-Docs guide]({{< relref "building/guides/data/csv-to-docs" >}}). + The bulk user upload feature is available in 3.16.0 and later versions of the CHT. As of CHT 3.17.0, when creating both a contact and a place, the contact will be set as the default contact of the place. User creation can be scripted using the [CHT API]({{< relref "building/reference/api#post-apiv2users" >}}) directly or using the [`cht-conf` tool](https://github.com/medic/cht-conf), which is detailed in the [CSV-to-Docs guide]({{< relref "/community/contributing/code/test-data/csv-to-docs" >}}). This feature can be used to load as many users as possible but works optimally with chunks of 1,000 users or less. {{< /callout >}} diff --git a/content/en/building/guides/data/users-bulk-load/access.denied.png b/content/en/building/training/users-bulk-load/access.denied.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/access.denied.png rename to content/en/building/training/users-bulk-load/access.denied.png diff --git a/content/en/building/guides/data/users-bulk-load/adding-places-cht-new-site.png b/content/en/building/training/users-bulk-load/adding-places-cht-new-site.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/adding-places-cht-new-site.png rename to content/en/building/training/users-bulk-load/adding-places-cht-new-site.png diff --git a/content/en/building/guides/data/users-bulk-load/adding-places-existing-spreadsheet.png b/content/en/building/training/users-bulk-load/adding-places-existing-spreadsheet.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/adding-places-existing-spreadsheet.png rename to content/en/building/training/users-bulk-load/adding-places-existing-spreadsheet.png diff --git a/content/en/building/guides/data/users-bulk-load/bad.type.png b/content/en/building/training/users-bulk-load/bad.type.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/bad.type.png rename to content/en/building/training/users-bulk-load/bad.type.png diff --git a/content/en/building/guides/data/users-bulk-load/importing-users-download-status-file.png b/content/en/building/training/users-bulk-load/importing-users-download-status-file.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/importing-users-download-status-file.png rename to content/en/building/training/users-bulk-load/importing-users-download-status-file.png diff --git a/content/en/building/guides/data/users-bulk-load/importing-users-entering-data.png b/content/en/building/training/users-bulk-load/importing-users-entering-data.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/importing-users-entering-data.png rename to content/en/building/training/users-bulk-load/importing-users-entering-data.png diff --git a/content/en/building/guides/data/users-bulk-load/importing-users-export-csv.png b/content/en/building/training/users-bulk-load/importing-users-export-csv.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/importing-users-export-csv.png rename to content/en/building/training/users-bulk-load/importing-users-export-csv.png diff --git a/content/en/building/guides/data/users-bulk-load/importing-users-fix-errors.png b/content/en/building/training/users-bulk-load/importing-users-fix-errors.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/importing-users-fix-errors.png rename to content/en/building/training/users-bulk-load/importing-users-fix-errors.png diff --git a/content/en/building/guides/data/users-bulk-load/importing-users-import-csv-confirmation.png b/content/en/building/training/users-bulk-load/importing-users-import-csv-confirmation.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/importing-users-import-csv-confirmation.png rename to content/en/building/training/users-bulk-load/importing-users-import-csv-confirmation.png diff --git a/content/en/building/guides/data/users-bulk-load/importing-users-import-csv.png b/content/en/building/training/users-bulk-load/importing-users-import-csv.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/importing-users-import-csv.png rename to content/en/building/training/users-bulk-load/importing-users-import-csv.png diff --git a/content/en/building/guides/data/users-bulk-load/importing-users-import-fixed-csv.png b/content/en/building/training/users-bulk-load/importing-users-import-fixed-csv.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/importing-users-import-fixed-csv.png rename to content/en/building/training/users-bulk-load/importing-users-import-fixed-csv.png diff --git a/content/en/building/guides/data/users-bulk-load/importing-users-import-progress.png b/content/en/building/training/users-bulk-load/importing-users-import-progress.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/importing-users-import-progress.png rename to content/en/building/training/users-bulk-load/importing-users-import-progress.png diff --git a/content/en/building/guides/data/users-bulk-load/importing-users-populate-parents-places.png b/content/en/building/training/users-bulk-load/importing-users-populate-parents-places.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/importing-users-populate-parents-places.png rename to content/en/building/training/users-bulk-load/importing-users-populate-parents-places.png diff --git a/content/en/building/guides/data/users-bulk-load/importing-users-transfer-errors.png b/content/en/building/training/users-bulk-load/importing-users-transfer-errors.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/importing-users-transfer-errors.png rename to content/en/building/training/users-bulk-load/importing-users-transfer-errors.png diff --git a/content/en/building/guides/data/users-bulk-load/users-spreadsheet-warning.png b/content/en/building/training/users-bulk-load/users-spreadsheet-warning.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/users-spreadsheet-warning.png rename to content/en/building/training/users-bulk-load/users-spreadsheet-warning.png diff --git a/content/en/building/guides/data/users-bulk-load/users-spreadsheet.png b/content/en/building/training/users-bulk-load/users-spreadsheet.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/users-spreadsheet.png rename to content/en/building/training/users-bulk-load/users-spreadsheet.png diff --git a/content/en/building/guides/data/users-bulk-load/valid.roles.png b/content/en/building/training/users-bulk-load/valid.roles.png similarity index 100% rename from content/en/building/guides/data/users-bulk-load/valid.roles.png rename to content/en/building/training/users-bulk-load/valid.roles.png diff --git a/content/en/building/tutorials/application-settings.md b/content/en/building/tutorials/application-settings.md index 93b74a178a..90ed3550c5 100644 --- a/content/en/building/tutorials/application-settings.md +++ b/content/en/building/tutorials/application-settings.md @@ -6,7 +6,7 @@ description: > Managing CHT application settings relatedContent: > building/reference/app-settings - building/guides/performance/replication + technical-overview/data/performance/replication building/reference/app-settings/transitions aliases: - /apps/tutorials/application-settings @@ -30,7 +30,7 @@ The settings which control CHT apps are defined in the *[app_settings.json]({{< *[Roles]({{< relref "building/users#roles" >}})* define permissions for users to access a group of app features and functionality. -*[Replication]({{< relref "building/guides/performance/replication" >}})* is when users download a copy of the data on to their device. *Replication depth* refers to the number of levels within a hierarchy a specific user role is able to replicate. +*[Replication]({{< relref "technical-overview/data/performance/replication" >}})* is when users download a copy of the data on to their device. *Replication depth* refers to the number of levels within a hierarchy a specific user role is able to replicate. *[Transitions]({{< relref "building/reference/app-settings/transitions" >}})* are Javascript code that run when a document is changed. A transition can edit the changed doc or do anything server side code can do for that matter. @@ -191,7 +191,7 @@ Configure the CHW role's depth to 2 by adding the following key/value pairs to t { "role": "chw", "depth": 2 } ``` -{{< see-also page="building/guides/performance/replication" title="Replication Depth" >}} +{{< see-also page="technical-overview/data/performance/replication" title="Replication Depth" >}} ### 5. Upload App Settings diff --git a/content/en/building/tutorials/application-tests.md b/content/en/building/tutorials/application-tests.md index 689e96b0a0..577981acf6 100644 --- a/content/en/building/tutorials/application-tests.md +++ b/content/en/building/tutorials/application-tests.md @@ -310,7 +310,7 @@ Commonly used harness methods when testing tasks are: - [`harness.loadAction()`](https://docs.communityhealthtoolkit.org/cht-conf-test-harness/Harness.html#loadAction): Simulates the user clicking on an action -With `getTasks()`, you get an array of [`Task`](https://docs.communityhealthtoolkit.org/cht-conf-test-harness/global.html#Task) objects which corresponds to the [tasks schema](https://docs.communityhealthtoolkit.org/technical-overview/concepts/db-schema/#tasks). +With `getTasks()`, you get an array of [`Task`](https://docs.communityhealthtoolkit.org/cht-conf-test-harness/global.html#Task) objects which corresponds to the [tasks schema](https://docs.communityhealthtoolkit.org/technical-overview/data/db-schema/#tasks). Let's look back at the simple task from this tutorial: [Building A Simple Task]({{< ref "building/tasks/simple-tasks" >}}). @@ -446,7 +446,7 @@ Testing a target is relatively straightforward. Add a report or contact that inc |Ideal:|One test for each user scenario
Ensure proper deduplication (particularly for those with emitCustom)| -Use [`harness.getTargets`](https://docs.communityhealthtoolkit.org/cht-conf-test-harness/Harness.html#getTargets) to check the state of targets. It returns a [`Target`](https://docs.communityhealthtoolkit.org/cht-conf-test-harness/global.html#Target) object which corresponds to the [targets schema](https://docs.communityhealthtoolkit.org/technical-overview/concepts/db-schema/#targets). +Use [`harness.getTargets`](https://docs.communityhealthtoolkit.org/cht-conf-test-harness/Harness.html#getTargets) to check the state of targets. It returns a [`Target`](https://docs.communityhealthtoolkit.org/cht-conf-test-harness/global.html#Target) object which corresponds to the [targets schema](https://docs.communityhealthtoolkit.org/technical-overview/data/db-schema/#targets). To test the first two targets created in the [targets tutorial]({{< ref "building/targets/target-widgets" >}}), use this code: ```js highlight diff --git a/content/en/building/users.md b/content/en/building/users.md index e6dfa26f37..f6ad21eb11 100644 --- a/content/en/building/users.md +++ b/content/en/building/users.md @@ -8,7 +8,7 @@ relatedContent: > design/personas building/contact-management/contact-and-users-1 building/contact-management/contact-and-users-2 - building/guides/data/users-bulk-load + building/training/users-bulk-load aliases: - /apps/concepts/users - /building/concepts/users @@ -38,7 +38,7 @@ Online roles are for users who need access to a lot of data and need to maintain Offline roles are for users who need to be able to access data on-the-go in the field and don’t have a reliable internet connection. All the data they have access to will be synced to their device. System administrators cannot be offline users as they won't have access to the app management tools offline. > [!NOTE] -> Advanced configuration options are available for a specific offline user role to manage what [level of data]({{< ref "building/guides/performance/replication" >}}) is synced to their device. +> Advanced configuration options are available for a specific offline user role to manage what [level of data]({{< ref "technical-overview/data/performance/replication" >}}) is synced to their device. ## Permissions diff --git a/content/en/community/contributing/code/android/releasing.md b/content/en/community/contributing/code/android/releasing.md index 13aa4cd820..60a4fe0072 100644 --- a/content/en/community/contributing/code/android/releasing.md +++ b/content/en/community/contributing/code/android/releasing.md @@ -5,7 +5,7 @@ weight: 2 description: > Instructions for releasing Android Apps relatedContent: > - building/guides/android/publishing + building/branding/publishing building/branding/android aliases: > /core/guides/android/releasing @@ -32,5 +32,5 @@ All Medic's Android projects automatically build, sign, and release builds via G 1. Update the CHANGELOG with the details of what's in this release. 1. Repeat steps 2-3 from the above [alpha release section](#alpha-for-release-testing) with the naming convention `v..`. 1. The CI build for the tag will create a new draft release on GitHub. Include the release notes from the CHANGELOG in the description of the release and publish the release on GitHub. -1. [Publish]({{< ref "building/guides/android/publishing" >}}) in the Play Store. For the CHT-Android app, the "reference" apps (`medicmobilegamma` and `unbranded`) must be published in the Play Store. Other channels such as F-Droid can also be used to publish the app. +1. [Publish]({{< ref "building/branding/publishing" >}}) in the Play Store. For the CHT-Android app, the "reference" apps (`medicmobilegamma` and `unbranded`) must be published in the Play Store. Other channels such as F-Droid can also be used to publish the app. 1. Announce the release on the [CHT forum](https://forum.communityhealthtoolkit.org), under the "Product - Releases" category. diff --git a/content/en/building/guides/data/csv-to-docs.md b/content/en/community/contributing/code/test-data/csv-to-docs.md similarity index 99% rename from content/en/building/guides/data/csv-to-docs.md rename to content/en/community/contributing/code/test-data/csv-to-docs.md index e16ddea113..800172933b 100644 --- a/content/en/building/guides/data/csv-to-docs.md +++ b/content/en/community/contributing/code/test-data/csv-to-docs.md @@ -9,6 +9,7 @@ relatedContent: > building/forms/contact aliases: - /apps/guides/data/csv-to-docs + - /building/guides/data/csv-to-docs --- diff --git a/content/en/building/test-data-generator.md b/content/en/community/contributing/code/test-data/test-data-generator.md similarity index 99% rename from content/en/building/test-data-generator.md rename to content/en/community/contributing/code/test-data/test-data-generator.md index 6d681362fc..a7ae3b5c62 100644 --- a/content/en/building/test-data-generator.md +++ b/content/en/community/contributing/code/test-data/test-data-generator.md @@ -7,6 +7,7 @@ description: > aliases: - /core/overview/test-data-generator/ - /technical-overview/test-data-generator/ + - /building/test-data-generator/ --- {{< callout type="error" >}} diff --git a/content/en/building/guides/data/invalid-reports.md b/content/en/community/contributing/code/troubleshooting/invalid-reports.md similarity index 94% rename from content/en/building/guides/data/invalid-reports.md rename to content/en/community/contributing/code/troubleshooting/invalid-reports.md index 7e37291b48..f1a750dad6 100644 --- a/content/en/building/guides/data/invalid-reports.md +++ b/content/en/community/contributing/code/troubleshooting/invalid-reports.md @@ -9,6 +9,8 @@ relatedContent: > building/reports aliases: - /apps/guides/data/invalid-reports + - /community/contributing/code/troubleshooting/invalid-reports + - /building/guides/data/invalid-reports/ --- You may encounter a dreaded case when reports coming in to a Medic Webapp instance have a red indicator instead of the green indicator. diff --git a/content/en/building/guides/data/invalid-reports/invalid_report.png b/content/en/community/contributing/code/troubleshooting/invalid-reports/invalid_report.png similarity index 100% rename from content/en/building/guides/data/invalid-reports/invalid_report.png rename to content/en/community/contributing/code/troubleshooting/invalid-reports/invalid_report.png diff --git a/content/en/building/guides/debugging/replicating-production-data-locally.md b/content/en/community/contributing/code/troubleshooting/replicating-production-data-locally.md similarity index 98% rename from content/en/building/guides/debugging/replicating-production-data-locally.md rename to content/en/community/contributing/code/troubleshooting/replicating-production-data-locally.md index 624323efd7..f1edeaf0ed 100644 --- a/content/en/building/guides/debugging/replicating-production-data-locally.md +++ b/content/en/community/contributing/code/troubleshooting/replicating-production-data-locally.md @@ -5,9 +5,10 @@ weight: description: > How to copy data from an instance to a local CouchDB database and app relatedContent: > - building/guides/performance/replication + technical-overview/data/performance/replication aliases: - /apps/guides/debugging/replicating-production-data-locally + - /building/guides/debugging/replicating-production-data-locally --- Sometimes there will be a production problem that you need to dig into locally to solve. This guide explains how to: diff --git a/content/en/community/contributing/creating-good-first-issues.md b/content/en/community/contributing/creating-good-first-issues.md index 55810154ca..83cf94fe6b 100644 --- a/content/en/community/contributing/creating-good-first-issues.md +++ b/content/en/community/contributing/creating-good-first-issues.md @@ -34,7 +34,7 @@ Taken from [#9869](https://github.com/medic/cht-core/issues/9869) opened Apr 202 > Right now there's a [user-devices API](https://docs.communityhealthtoolkit.org/building/reference/api/#get-apiv2exportuser-devices) which has per user information, but does not include used and total storage space on the device. If we add this to this report, it would make an easy way to find this data! > > **Describe alternatives you've considered** -> Administrators could either manually check telemetry documents per user in Couch ([see](https://docs.communityhealthtoolkit.org/building/guides/performance/telemetry/#metadata) `deviceInfo.storage.free`) or they could set up a process like CHT Sync or couch2pg to sync this data to a Postgres database. +> Administrators could either manually check telemetry documents per user in Couch ([see](https://docs.communityhealthtoolkit.org/technical-overview/data/performance/telemetry/#metadata) `deviceInfo.storage.free`) or they could set up a process like CHT Sync or couch2pg to sync this data to a Postgres database. > > These are either slow (manually checking) or hard to set up (syncing data), where as the API is built in. > @@ -126,4 +126,4 @@ Taken from [#9869](https://github.com/medic/cht-core/issues/9869) opened Apr 202 > }, > "quux": "banana" > } -> ``` \ No newline at end of file +> ``` diff --git a/content/en/hosting/analytics/_index.md b/content/en/hosting/analytics/_index.md index 9115742dc2..b704ce70b4 100644 --- a/content/en/hosting/analytics/_index.md +++ b/content/en/hosting/analytics/_index.md @@ -6,7 +6,7 @@ description: > Using CHT Sync for data synchronization and analytics relatedContent: > technical-overview/architecture/cht-sync - technical-overview/concepts/data-flows-for-analytics/ + technical-overview/data/analytics/data-flows-for-analytics/ aliases: - /apps/guides/data/analytics/ - /apps/guides/data/analytics/introduction diff --git a/content/en/hosting/analytics/building-dbt-models.md b/content/en/hosting/analytics/building-dbt-models.md index af205242c7..4cf386d250 100644 --- a/content/en/hosting/analytics/building-dbt-models.md +++ b/content/en/hosting/analytics/building-dbt-models.md @@ -5,7 +5,7 @@ weight: 4 description: > Guide for building dbt models for CHT applications relatedContent: > - technical-overview/concepts/db-schema + technical-overview/data/db-schema building/reference/app-settings/hierarchy aliases: - /apps/guides/data/analytics/building-dbt-models @@ -18,7 +18,7 @@ aliases: [CHT Sync]({{< relref "technical-overview/architecture/cht-sync" >}}) copies data from CouchDB to a relational database. It initially stores the document data from CouchDB in a `jsonb` column in a single PostgreSQL table. This is not possible to query for analytics, so it uses [dbt](https://www.getdbt.com/) to convert the document data to a relational database format. -The [cht-pipeline repository](https://github.com/medic/cht-pipeline) defines a dbt project, which contains model files for the data schema described in the [database schema conventions]({{< ref "technical-overview/concepts/db-schema" >}}). +The [cht-pipeline repository](https://github.com/medic/cht-pipeline) defines a dbt project, which contains model files for the data schema described in the [database schema conventions]({{< ref "technical-overview/data/db-schema" >}}). Forms may be specific to each CHT application; additional models will need to be developed to analyze data from responses to these custom forms. One additional model will be needed for each form, and for any aggregations, dashboards, or reusable views that use those form responses as input. If using the [configurable contact hierarchy]({{< ref "building/reference/app-settings/hierarchy#app_settingsjson-contact_types" >}}), it may also be useful to add models for other contact types. @@ -101,7 +101,7 @@ The document itself is not copied to this table; to use it requires joining to t |`dbname`| The name of the CouchDB database the document was synced from. | ### `data_record` -All form responses are stored in the `data_record` table; see more details [in the database schema conventions]({{< ref "technical-overview/concepts/db-schema#reports" >}}). +All form responses are stored in the `data_record` table; see more details [in the database schema conventions]({{< ref "technical-overview/data/db-schema#reports" >}}). This table contains columns for the contact who made the report, the parent of that contact, and the date it was reported. |Field|Description| @@ -118,7 +118,7 @@ This table contains columns for the contact who made the report, the parent of t |`grandparent_uuid`| uuid of the parent of `contact` who submitted the form (at the date `reported`; contacts parent may have changed since then, this column will not)| ### `contact` -See a description of contact documents in CouchDB [in the database schema conventions]({{< ref "technical-overview/concepts/db-schema#contacts-persons-and-places" >}}). +See a description of contact documents in CouchDB [in the database schema conventions]({{< ref "technical-overview/data/db-schema#contacts-persons-and-places" >}}). Every person and place is stored in the `contact` table. Persons and places are stored in their own tables, but because contact types are configurable, other contact types do not have their own tables by default. The contact hierarchy defines "is a" relationships between contact types; e.g., a patient is a person is a contact. This is modeled as one table per type, where the `uuid` is both the primary key for the child table and a foreign key to the parent table. diff --git a/content/en/hosting/analytics/couch2pg-to-cht-sync-migration.md b/content/en/hosting/analytics/couch2pg-to-cht-sync-migration.md index ea3d70d3ce..f9414d5da4 100644 --- a/content/en/hosting/analytics/couch2pg-to-cht-sync-migration.md +++ b/content/en/hosting/analytics/couch2pg-to-cht-sync-migration.md @@ -6,7 +6,7 @@ description: > Instructions on migrating from couch2pg to CHT Sync for data synchronization and analytics relatedContent: > technical-overview/architecture/cht-sync - technical-overview/concepts/data-flows-for-analytics/ + technical-overview/data/analytics/data-flows-for-analytics/ aliases: - /apps/guides/data/analytics/couch2pg-to-cht-sync-migration - /building/guides/data/analytics/couch2pg-to-cht-sync-migration diff --git a/content/en/hosting/couch2pg/couch2pg-oom-errors.md b/content/en/hosting/couch2pg/couch2pg-oom-errors.md index b5bc97bfa4..67433e70bb 100644 --- a/content/en/hosting/couch2pg/couch2pg-oom-errors.md +++ b/content/en/hosting/couch2pg/couch2pg-oom-errors.md @@ -6,7 +6,7 @@ description: > Dealing with out-of-memory errors in couch2pg aliases: - /apps/guides/database/couch2pg-oom-errors - - /building/guides/database/couch2pg-oom-errors + - /technical-overview/data/analytics/couch2pg-oom-errors --- {{< callout type="warning" >}} diff --git a/content/en/hosting/monitoring/dashboards.md b/content/en/hosting/monitoring/dashboards.md index 4de558a46b..e4a99483c2 100644 --- a/content/en/hosting/monitoring/dashboards.md +++ b/content/en/hosting/monitoring/dashboards.md @@ -51,7 +51,7 @@ Replication Apdex: A score of 100 means all successful syncs proceeded by the se ![replication.png](dashboards/replication.png) -Note that this is not the same as [client side form Apdex](/building/guides/performance/telemetry/#performance-data). +Note that this is not the same as [client side form Apdex](/technical-overview/data/performance/telemetry/#performance-data). ## API Server diff --git a/content/en/releases/3_10_0.md b/content/en/releases/3_10_0.md index 4827929610..64b613b4eb 100644 --- a/content/en/releases/3_10_0.md +++ b/content/en/releases/3_10_0.md @@ -53,7 +53,7 @@ See [the documentation](https://docs.communityhealthtoolkit.org/apps/reference/a To support the ability of sending SMS messages to people that are not primary contacts, contact documents now expose a new property, `linked_docs`, that can contain a collection of ids representing documents that are relevant to the respective contact. Every document listed in `linked_docs` will be shallowly hydrated when the contact is hydrated, thus providing a means of accessing the contents of these related documents everywhere the contact is used within the app. This feature can have a multitude of applications, from providing a way to access an arbitrary contact's phone number when resolving an SMS recipient to linking a delivery report to a child person document (`linked_docs` can also be used in `contact-summary`). -See [the documentation](https://docs.communityhealthtoolkit.org/technical-overview/concepts/db-schema/#contacts-persons-and-places) for more information. +See [the documentation](https://docs.communityhealthtoolkit.org/technical-overview/data/db-schema/#contacts-persons-and-places) for more information. ## Privacy Policies diff --git a/content/en/releases/3_14_0.md b/content/en/releases/3_14_0.md index 3ec4f3e250..770d9758d6 100644 --- a/content/en/releases/3_14_0.md +++ b/content/en/releases/3_14_0.md @@ -75,9 +75,9 @@ We have updated the tab labels to always display even on small screens. Addition ### Improved server-side purging -We have made several improvements to our [server-side purging]({{< ref "building/guides/performance/purging#server-side" >}}) functionality allowing it to perform better at scale. +We have made several improvements to our [server-side purging]({{< ref "technical-overview/data/performance/purging#server-side" >}}) functionality allowing it to perform better at scale. -- Enhanced logging during purging via a new [`purgelog` document]({{< ref "building/guides/performance/purging#purged-documents-server-side" >}}) saved in the `medic-sentinel` database after every purge. +- Enhanced logging during purging via a new [`purgelog` document]({{< ref "technical-overview/data/performance/purging#purged-documents-server-side" >}}) saved in the `medic-sentinel` database after every purge. - If a contact has more than 20,000 records, it will be skipped and none of its records will be purged. - A log will appear for the skipped contact and the id of this contact will be saved in a new `skipped_contacts` property in the `purgelog`. - The batch size for contacts to purge will dynamically adjust based on the number of records associated with the contacts. diff --git a/content/en/releases/3_17_0.md b/content/en/releases/3_17_0.md index c75ea164a2..6bf8923496 100644 --- a/content/en/releases/3_17_0.md +++ b/content/en/releases/3_17_0.md @@ -46,7 +46,7 @@ NOTE: The old version of the UI can be temporarily re-enabled by following the i ### Places created with bulk upload now have a primary contact -We have improved the [bulk upload]({{< ref "building/guides/data/users-bulk-load" >}}) feature to automatically assign a primary contact to a newly created place. +We have improved the [bulk upload]({{< ref "building/training/users-bulk-load" >}}) feature to automatically assign a primary contact to a newly created place. - [#7724](https://github.com/medic/cht-core/issues/7724): Places created with bulk upload don't have a primary contact. diff --git a/content/en/releases/3_7_0.md b/content/en/releases/3_7_0.md index 613c73ac70..316c611f12 100644 --- a/content/en/releases/3_7_0.md +++ b/content/en/releases/3_7_0.md @@ -63,7 +63,7 @@ Marking documents as no longer useful so that they don't take up mobile device r is now handled server-side. This enables devices to not download unnecessary documents during an initial replication and makes the actual "purging" process faster. -For more information about changes in purging, refer to the [purging documentation]({{% ref "building/guides/performance/purging#server-side" %}}). +For more information about changes in purging, refer to the [purging documentation]({{% ref "technical-overview/data/performance/purging#server-side" %}}). ## Warn when replicating too many docs diff --git a/content/en/releases/3_8_0.md b/content/en/releases/3_8_0.md index 3f3118bc06..bca96b43b6 100644 --- a/content/en/releases/3_8_0.md +++ b/content/en/releases/3_8_0.md @@ -47,7 +47,7 @@ There are no required changes to the [supported software matrix]({{% ref "releas ## Task and target data available for analysis -The task and target system has undergone a significant rework. It is now powered by [task documents](https://docs.communityhealthtoolkit.org/technical-overview/concepts/db-schema/#tasks) and [target documents](https://docs.communityhealthtoolkit.org/technical-overview/concepts/db-schema/#targets) which are written to PouchDB and synced to CouchDB/Postgres. This exposes task and target data in CouchDB and Postgres so queries can easily capture how tasks and targets are behaving for users in the field. These changes also set the foundation for powerful collaborative supervisor features to come in the future. +The task and target system has undergone a significant rework. It is now powered by [task documents](https://docs.communityhealthtoolkit.org/technical-overview/data/db-schema/#tasks) and [target documents](https://docs.communityhealthtoolkit.org/technical-overview/data/db-schema/#targets) which are written to PouchDB and synced to CouchDB/Postgres. This exposes task and target data in CouchDB and Postgres so queries can easily capture how tasks and targets are behaving for users in the field. These changes also set the foundation for powerful collaborative supervisor features to come in the future. These changes have resulted in important performance changes for the app. diff --git a/content/en/releases/4_18_0.md b/content/en/releases/4_18_0.md index 4436a5049f..17cef09919 100644 --- a/content/en/releases/4_18_0.md +++ b/content/en/releases/4_18_0.md @@ -60,11 +60,11 @@ chw_area --- chw & family_a & family_b -Controlling the data accessible to ["offline" CHT users]({{< ref "building/users#offline-users" >}}) is essential. Often, the [`replication_depth` configuration]({{< ref "building/guides/performance/replication#depth" >}}) is used to limit how much of the contact hierarchy is visible to a user (and downloaded to their device) by preventing the replication of contacts/reports beyond a specified depth. +Controlling the data accessible to ["offline" CHT users]({{< ref "building/users#offline-users" >}}) is essential. Often, the [`replication_depth` configuration]({{< ref "technical-overview/data/performance/replication#depth" >}}) is used to limit how much of the contact hierarchy is visible to a user (and downloaded to their device) by preventing the replication of contacts/reports beyond a specified depth. However, in some cases this configuration is not sufficient. For example, perhaps a CHW Supervisor needs to have access to the contact data for the CHWs they supervise (including the reports for those contacts), but should not have access to all the households/patients served by those CHWs. A typical hierarchy (as seen here) might have the CHW contact and the family household contacts both at the same depth level as children of the CHW Area. If the supervisor user is configured to have a replication depth of `1`, they will not have access to the CHW contact. If the replication depth is set to `2`, the supervisor will have access to all the household contacts. -In this case, the new [`replicate_primary_contacts` configuration]({{< ref "building/guides/performance/replication#replicate-primary-contacts" >}}) can be used to ensure the primary contacts of the places at the user's deepest replication depth are also replicated (even if those contacts are technically located deeper in the hierarchy than the configured depth limit). So, with a replication depth of `1` and `replicate_primary_contacts` set to `true`, the supervisor user will have access to the CHW contact, but not the household contacts. +In this case, the new [`replicate_primary_contacts` configuration]({{< ref "technical-overview/data/performance/replication#replicate-primary-contacts" >}}) can be used to ensure the primary contacts of the places at the user's deepest replication depth are also replicated (even if those contacts are technically located deeper in the hierarchy than the configured depth limit). So, with a replication depth of `1` and `replicate_primary_contacts` set to `true`, the supervisor user will have access to the CHW contact, but not the household contacts. [#8034](https://github.com/medic/cht-core/issues/8034): Add config to allow replicating primary contacts for places at max depth diff --git a/content/en/technical-overview/architecture/cht-sync.md b/content/en/technical-overview/architecture/cht-sync.md index eea1123e9a..4caa609d5b 100644 --- a/content/en/technical-overview/architecture/cht-sync.md +++ b/content/en/technical-overview/architecture/cht-sync.md @@ -6,7 +6,7 @@ description: > Data synchronization tools to enable analytics relatedContent: > technical-overview/architecture - technical-overview/concepts/data-flows-for-analytics/ + technical-overview/data/analytics/data-flows-for-analytics/ hosting/analytics/ aliases: - /core/overview/data-flows-for-analytics/cht-sync/ diff --git a/content/en/building/guides/data/impact-metrics.md b/content/en/technical-overview/concepts/impact-metrics.md similarity index 96% rename from content/en/building/guides/data/impact-metrics.md rename to content/en/technical-overview/concepts/impact-metrics.md index df4017a745..01eb60fd28 100644 --- a/content/en/building/guides/data/impact-metrics.md +++ b/content/en/technical-overview/concepts/impact-metrics.md @@ -6,10 +6,11 @@ description: > A set of impact metrics for monitoring priority use cases across the Community Health Toolkit keywords: impact monitoring relatedContent: > - technical-overview/concepts/data-flows-for-analytics - building/guides/performance/telemetry + technical-overview/data/analytics/data-flows-for-analytics + technical-overview/data/performance/telemetry aliases: - /apps/guides/data/impact-metrics + - /building/guides/data/impact-metrics/ --- Impact monitoring is an essential part of both the Community Health Toolkit and Medic's processes and ethos. We are committed to harnessing data to: diff --git a/content/en/technical-overview/concepts/offline-first.md b/content/en/technical-overview/concepts/offline-first.md index cb99a912cb..a5e045fb9e 100644 --- a/content/en/technical-overview/concepts/offline-first.md +++ b/content/en/technical-overview/concepts/offline-first.md @@ -43,7 +43,7 @@ Once the application has started up it needs data to be useful. This data falls Both of these types of data are cached on the device because they are required for the user to do their job. The CHT Core Framework uses [PouchDB](https://pouchdb.com/) to store the data on the device's disk. Once cached, when the application starts up the code is executed, which reads the data, allowing the user to do their job regardless of the quality of their internet connection. -If the user creates new patient data by registering a family or completing a task the application stores this in the phone's cache and attempts to submit this to the server. Periodically the application checks to see if there is new data on the server that is relevant to the user and if so, it updates the cache. This process of sending and receiving data updates is called [replication]({{< relref "building/guides/performance/replication" >}}), and is performed without interrupting the user from their work. +If the user creates new patient data by registering a family or completing a task the application stores this in the phone's cache and attempts to submit this to the server. Periodically the application checks to see if there is new data on the server that is relevant to the user and if so, it updates the cache. This process of sending and receiving data updates is called [replication]({{< relref "technical-overview/data/performance/replication" >}}), and is performed without interrupting the user from their work. ## FAQs from CHT contributors diff --git a/content/en/building/guides/database/_index.md b/content/en/technical-overview/data/_index.md similarity index 88% rename from content/en/building/guides/database/_index.md rename to content/en/technical-overview/data/_index.md index c4479c509d..d998245187 100644 --- a/content/en/building/guides/database/_index.md +++ b/content/en/technical-overview/data/_index.md @@ -6,6 +6,7 @@ description: > Managing databases used by CHT applications aliases: - /apps/guides/database/ + - /building/guides/database/ --- ## CouchDB @@ -16,7 +17,7 @@ The CHT has a range of CouchDB databases for storing different types of data. By The main database, used to store all contact and report data. Data access is protected by API to provide protection on a per document basis. -{{< see-also page="technical-overview/concepts/db-schema" >}} +{{< see-also page="technical-overview/data/db-schema" >}} ### medic-sentinel @@ -51,7 +52,7 @@ Used for documents which are only relevant to a single user, including: - "feedback". Errors and exceptions caught in the browser, and user initiated feedback. Support staff must monitor these docs to detect any errors that are occurring on the client device. - "read". Records that a document has been opened in the browser so it can be marked as read in the UI. -- "telemetry". Aggregate telemetry information for performance and usage metrics analysis. {{< see-also page="building/guides/performance/telemetry" >}} +- "telemetry". Aggregate telemetry information for performance and usage metrics analysis. {{< see-also page="technical-overview/data/performance/telemetry" >}} ### medic-users-meta @@ -71,10 +72,10 @@ Stores meta data about the user including when they last connected to the server Used to store documents on the client device to allow for [Offline-First]({{< ref "technical-overview/concepts/offline-first" >}}) access. Bidirectional replication is done on the "medic" and "medic-user-{username}-meta" databases. The "medic" database is only partially replicated so the user stores only a subset of the entire CouchDB database for performance and security reasons. -{{< see-also page="building/guides/performance/replication" >}} +{{< see-also page="technical-overview/data/performance/replication" >}} ## PostgreSQL -Used to store data for performant analytical queries such as impact and monitoring dashboards. The CHT uses [CHT Sync](https://github.com/medic/cht-sync) to handle replication of docs from "medic", "medic-sentinel", and "medic-users-meta" databases into Postgres. +Used to store data for performant analytical queries such as impact and monitoring dashboards. -{{< see-also page="technical-overview/concepts/data-flows-for-analytics" >}} +{{< see-also page="technical-overview/data/analytics" >}} diff --git a/content/en/technical-overview/data/analytics/_index.md b/content/en/technical-overview/data/analytics/_index.md new file mode 100644 index 0000000000..483516d14c --- /dev/null +++ b/content/en/technical-overview/data/analytics/_index.md @@ -0,0 +1,18 @@ +--- +title: "PostgreSQL Analytics" +linkTitle: "PostgreSQL Analytics" +weight: 10 +description: > + Managing databases used by CHT applications +aliases: + - /apps/guides/database/ + - /building/guides/data/ +relatedContent: + technical-overview/data +--- + +## PostgreSQL + +Used to store data for performant analytical queries such as impact and monitoring dashboards. The CHT uses [CHT Sync](https://github.com/medic/cht-sync) to handle replication of docs from "medic", "medic-sentinel", and "medic-users-meta" databases into Postgres. + +{{< subpages >}} diff --git a/content/en/technical-overview/concepts/data-flows-for-analytics.md b/content/en/technical-overview/data/analytics/data-flows-for-analytics.md similarity index 98% rename from content/en/technical-overview/concepts/data-flows-for-analytics.md rename to content/en/technical-overview/data/analytics/data-flows-for-analytics.md index 94c903d9f5..24d4d1a8eb 100644 --- a/content/en/technical-overview/concepts/data-flows-for-analytics.md +++ b/content/en/technical-overview/data/analytics/data-flows-for-analytics.md @@ -1,16 +1,17 @@ --- title: "Data Flows for Analytics" linkTitle: "Data Flows" -weight: 9 +weight: 1 description: > Overview of data flows in the CHT for analytics, impact monitoring, and data science relatedContent: > - building/guides/data - building/guides/database + technical-overview/data + technical-overview/data/analytics aliases: - /core/data-flows-for-analytics - /core/overview/data-flows-for-analytics - /technical-overview/data-flows-for-analytics/ + - /technical-overview/concepts/data-flows-for-analytics/ --- In this section, we focus on how data flows through the various components of the Community Health Toolkit. The CHT is built to support the delivery of quality community health care at the last mile. The CHT is designed to work in areas with low connectivity, which means it is an [Offline-First]({{< ref "technical-overview/concepts/offline-first" >}}) toolkit for care provision. The architectural and technology choices in the stack are mostly guided by this principle, which will be evident in the discussion of the data management pipeline. diff --git a/content/en/technical-overview/concepts/data-flows-for-analytics/data-flows.png b/content/en/technical-overview/data/analytics/data-flows-for-analytics/data-flows.png similarity index 100% rename from content/en/technical-overview/concepts/data-flows-for-analytics/data-flows.png rename to content/en/technical-overview/data/analytics/data-flows-for-analytics/data-flows.png diff --git a/content/en/building/guides/database/muting_in_dashboards.md b/content/en/technical-overview/data/analytics/muting_in_dashboards.md similarity index 97% rename from content/en/building/guides/database/muting_in_dashboards.md rename to content/en/technical-overview/data/analytics/muting_in_dashboards.md index 23bf3b8388..fe722a43a9 100644 --- a/content/en/building/guides/database/muting_in_dashboards.md +++ b/content/en/technical-overview/data/analytics/muting_in_dashboards.md @@ -7,6 +7,7 @@ description: > relevantLinks: > aliases: - /apps/guides/database/muting_in_dashboards + - /building/guides/database/muting_in_dashboards --- When a contact gets muted, two of [many things]({{< ref "building/reference/app-settings/transitions#muting" >}}) happen: @@ -88,4 +89,4 @@ You can query the table above (`mute_timeline`) to check if the contact was mute ``` -This query checks if a record exists for this contact where they were muted earlier or on `EXAMPLE_DATE` and unmuted on or after the `EXAMPLE_DATE`. For the earlier example where the contact was muted in February and unmuted in May if we pass February, March, or April as `EXAMPLE_DATE`, we find a record because our `unmuted_on` is always greater than `EXAMPLE_DATE`. If we pass May going forward, we find no records that match our condition. \ No newline at end of file +This query checks if a record exists for this contact where they were muted earlier or on `EXAMPLE_DATE` and unmuted on or after the `EXAMPLE_DATE`. For the earlier example where the contact was muted in February and unmuted in May if we pass February, March, or April as `EXAMPLE_DATE`, we find a record because our `unmuted_on` is always greater than `EXAMPLE_DATE`. If we pass May going forward, we find no records that match our condition. diff --git a/content/en/building/guides/database/querying_apdex_telemetry.md b/content/en/technical-overview/data/analytics/querying_apdex_telemetry.md similarity index 88% rename from content/en/building/guides/database/querying_apdex_telemetry.md rename to content/en/technical-overview/data/analytics/querying_apdex_telemetry.md index 9abe4ab8ed..3e8fa7ae07 100644 --- a/content/en/building/guides/database/querying_apdex_telemetry.md +++ b/content/en/technical-overview/data/analytics/querying_apdex_telemetry.md @@ -5,16 +5,17 @@ weight: description: > How to use SQL queries to view Apdex scores relatedContent: > - building/guides/performance/telemetry/ - technical-overview/concepts/data-flows-for-analytics - building/guides/database/#postgresql + technical-overview/data/performance/telemetry + technical-overview/data/analytics/data-flows-for-analytics + technical-overview/data/analytics/#postgresql aliases: - /apps/guides/database/querying_apdex_telemetry + - /building/guides/database/querying_apdex_telemetry/ --- Added in `4.7.0`, CHT now records the Apdex (Application Performance Index) that is an open standard for measuring performance of software applications. -Since Apdex is part of the [telemetry]({{< ref "building/guides/performance/telemetry" >}}) system, it is possible to view Apdex data directly from CouchDB. However, it is more useful when aggregated across many users, interactions, and/or days. With this in mind, it is typically easier to query the data using SQL from an [analytics database]({{< ref "technical-overview/concepts/data-flows-for-analytics" >}}). +Since Apdex is part of the [telemetry]({{< ref "technical-overview/data/performance/telemetry" >}}) system, it is possible to view Apdex data directly from CouchDB. However, it is more useful when aggregated across many users, interactions, and/or days. With this in mind, it is typically easier to query the data using SQL from an [analytics database]({{< ref "technical-overview/data/analytics/data-flows-for-analytics" >}}). An example of an SQL to view the Apdex score: diff --git a/content/en/building/guides/database/querying_training_card_telemetry.md b/content/en/technical-overview/data/analytics/querying_training_card_telemetry.md similarity index 85% rename from content/en/building/guides/database/querying_training_card_telemetry.md rename to content/en/technical-overview/data/analytics/querying_training_card_telemetry.md index 81dbec223b..ec2ba48a66 100644 --- a/content/en/building/guides/database/querying_training_card_telemetry.md +++ b/content/en/technical-overview/data/analytics/querying_training_card_telemetry.md @@ -1,21 +1,22 @@ --- title: "Querying Training Cards Telemetry Data" linkTitle: "Querying Training Cards Data" -weight: +weight: description: > How to use SQL queries to view metrics about Training Cards usage relatedContent: > - building/guides/performance/telemetry/ - technical-overview/concepts/data-flows-for-analytics + technical-overview/data/performance/telemetry + technical-overview/data/analytics/data-flows-for-analytics aliases: - /apps/guides/database/querying_training_card_telemetry + - /building/guides/database/querying_training_card_telemetry/ --- Introduced in `4.2.0`, CHT has supported deployment of in-app training cards to facilitate remote training. -Since interaction with training cards logs [telemetry data]({{< ref "building/guides/performance/telemetry" >}}), it is possible to view the data directly from CouchDB. However, it is more useful when you can run queries that provide useful metrics about the usage of training cards aggregated across many users, and interactions. +Since interaction with training cards logs [telemetry data]({{< ref "technical-overview/data/performance/telemetry" >}}), it is possible to view the data directly from CouchDB. However, it is more useful when you can run queries that provide useful metrics about the usage of training cards aggregated across many users, and interactions. -With this in mind, it is typically easier to query the data using SQL from an [analytics database]({{< ref "technical-overview/concepts/data-flows-for-analytics" >}}). The couchDB data can be replicated using [CHT Sync]({{< ref "/hosting/analytics" >}}) to a postgresql instance where you can then run the SQL queries. +With this in mind, it is typically easier to query the data using SQL from an [analytics database]({{< ref "technical-overview/data/analytics/data-flows-for-analytics" >}}). The couchDB data can be replicated using [CHT Sync]({{< ref "/hosting/analytics" >}}) to a postgresql instance where you can then run the SQL queries. This guide includes several SQL queries that can act as a starting point for identifying useful metrics. diff --git a/content/en/building/guides/database/rdbms-from-mac.md b/content/en/technical-overview/data/analytics/rdbms-from-mac.md similarity index 96% rename from content/en/building/guides/database/rdbms-from-mac.md rename to content/en/technical-overview/data/analytics/rdbms-from-mac.md index d6fd115885..5b9b5d0802 100644 --- a/content/en/building/guides/database/rdbms-from-mac.md +++ b/content/en/technical-overview/data/analytics/rdbms-from-mac.md @@ -1,13 +1,14 @@ --- title: "Connecting to RDBMS from MacOS" linkTitle: "RDBMS from MacOS" -weight: +weight: 2 description: > How to connect to the PostgreSQL RDBMS server from MacOS relatedContent: > - building/guides/database/rdbms-from-windows + technical-overview/data/analytics/rdbms-from-windows aliases: - /apps/guides/database/rdbms-from-mac + - /building/guides/database/rdbms-from-mac --- Follow these steps on a Mac to generate your public/private keys and access the PostgreSQL server. diff --git a/content/en/building/guides/database/rdbms-from-mac/connection-settings.png b/content/en/technical-overview/data/analytics/rdbms-from-mac/connection-settings.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-mac/connection-settings.png rename to content/en/technical-overview/data/analytics/rdbms-from-mac/connection-settings.png diff --git a/content/en/building/guides/database/rdbms-from-mac/ssh-commands.png b/content/en/technical-overview/data/analytics/rdbms-from-mac/ssh-commands.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-mac/ssh-commands.png rename to content/en/technical-overview/data/analytics/rdbms-from-mac/ssh-commands.png diff --git a/content/en/building/guides/database/rdbms-from-mac/terminal.png b/content/en/technical-overview/data/analytics/rdbms-from-mac/terminal.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-mac/terminal.png rename to content/en/technical-overview/data/analytics/rdbms-from-mac/terminal.png diff --git a/content/en/building/guides/database/rdbms-from-windows.md b/content/en/technical-overview/data/analytics/rdbms-from-windows.md similarity index 95% rename from content/en/building/guides/database/rdbms-from-windows.md rename to content/en/technical-overview/data/analytics/rdbms-from-windows.md index 178f3a18db..10a0cf85c9 100644 --- a/content/en/building/guides/database/rdbms-from-windows.md +++ b/content/en/technical-overview/data/analytics/rdbms-from-windows.md @@ -1,13 +1,14 @@ --- title: "Connecting to RDBMS from Windows" linkTitle: "RDBMS from Windows" -weight: +weight: 3 description: > How to connect to the PostgreSQL RDBMS server from Windows relatedContent: > - building/guides/database/rdbms-from-mac + technical-overview/data/analytics/rdbms-from-mac aliases: - /apps/guides/database/rdbms-from-windows + - /building/guides/database/rdbms-from-windows --- Connecting to RDBMS, the PostgreSQL server, is pretty stratightforward in nix systems. In Windows there are a couple of things you need to do to get it up and running. diff --git a/content/en/building/guides/database/rdbms-from-windows/putty-add-key.png b/content/en/technical-overview/data/analytics/rdbms-from-windows/putty-add-key.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-windows/putty-add-key.png rename to content/en/technical-overview/data/analytics/rdbms-from-windows/putty-add-key.png diff --git a/content/en/building/guides/database/rdbms-from-windows/putty-connect-final.png b/content/en/technical-overview/data/analytics/rdbms-from-windows/putty-connect-final.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-windows/putty-connect-final.png rename to content/en/technical-overview/data/analytics/rdbms-from-windows/putty-connect-final.png diff --git a/content/en/building/guides/database/rdbms-from-windows/putty-connect.png b/content/en/technical-overview/data/analytics/rdbms-from-windows/putty-connect.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-windows/putty-connect.png rename to content/en/technical-overview/data/analytics/rdbms-from-windows/putty-connect.png diff --git a/content/en/building/guides/database/rdbms-from-windows/putty-gen-import.png b/content/en/technical-overview/data/analytics/rdbms-from-windows/putty-gen-import.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-windows/putty-gen-import.png rename to content/en/technical-overview/data/analytics/rdbms-from-windows/putty-gen-import.png diff --git a/content/en/building/guides/database/rdbms-from-windows/putty-save-key.png b/content/en/technical-overview/data/analytics/rdbms-from-windows/putty-save-key.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-windows/putty-save-key.png rename to content/en/technical-overview/data/analytics/rdbms-from-windows/putty-save-key.png diff --git a/content/en/building/guides/database/rdbms-from-windows/puttygen-run-key-generate.png b/content/en/technical-overview/data/analytics/rdbms-from-windows/puttygen-run-key-generate.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-windows/puttygen-run-key-generate.png rename to content/en/technical-overview/data/analytics/rdbms-from-windows/puttygen-run-key-generate.png diff --git a/content/en/building/guides/database/rdbms-from-windows/rdbms_connect_1.png b/content/en/technical-overview/data/analytics/rdbms-from-windows/rdbms_connect_1.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-windows/rdbms_connect_1.png rename to content/en/technical-overview/data/analytics/rdbms-from-windows/rdbms_connect_1.png diff --git a/content/en/building/guides/database/rdbms-from-windows/rdbms_connect_2.png b/content/en/technical-overview/data/analytics/rdbms-from-windows/rdbms_connect_2.png similarity index 100% rename from content/en/building/guides/database/rdbms-from-windows/rdbms_connect_2.png rename to content/en/technical-overview/data/analytics/rdbms-from-windows/rdbms_connect_2.png diff --git a/content/en/building/guides/data/audit.md b/content/en/technical-overview/data/audit.md similarity index 99% rename from content/en/building/guides/data/audit.md rename to content/en/technical-overview/data/audit.md index c33168f4a2..b0f0a30a1a 100644 --- a/content/en/building/guides/data/audit.md +++ b/content/en/technical-overview/data/audit.md @@ -1,12 +1,14 @@ --- title: "Database document auditing" linkTitle: "Document auditing" -weight: 10 +weight: 3 description: > Overview of document change auditing keywords: audit relatedContent: > - technical-overview/concepts/db-schema + technical-overview/data/db-schema +aliases: + - /building/guides/data/audit/ --- {{< callout >}} @@ -291,4 +293,4 @@ so that the resulting CouchDB queries can be traced. } } } -``` \ No newline at end of file +``` diff --git a/content/en/building/guides/database/couchdb-authentication.md b/content/en/technical-overview/data/couchdb-authentication.md similarity index 92% rename from content/en/building/guides/database/couchdb-authentication.md rename to content/en/technical-overview/data/couchdb-authentication.md index e49bd9814d..cafd35748f 100644 --- a/content/en/building/guides/database/couchdb-authentication.md +++ b/content/en/technical-overview/data/couchdb-authentication.md @@ -1,13 +1,14 @@ --- title: "CouchDB Authentication" linkTitle: "CouchDB Authentication" -weight: +weight: 5 description: > Invalidating Sessions relatedContent: > aliases: - /apps/guides/database/couchdb-authentication + - /building/guides/database/couchdb-authentication --- ### To invalidate a session in couchdb, there are two options: diff --git a/content/en/building/guides/database/database-conflicts.md b/content/en/technical-overview/data/database-conflicts.md similarity index 99% rename from content/en/building/guides/database/database-conflicts.md rename to content/en/technical-overview/data/database-conflicts.md index 273b6e0802..09078ddaa4 100644 --- a/content/en/building/guides/database/database-conflicts.md +++ b/content/en/technical-overview/data/database-conflicts.md @@ -1,12 +1,13 @@ --- title: "Database Conflicts" linkTitle: "Database Conflicts" -weight: +weight: 4 description: > How to handle conflicts with CouchDB documents relevantLinks: > aliases: - /apps/guides/database/database-conflicts + - /building/guides/database/database-conflicts --- Conflicts are a natural and unavoidable part of working in a distributed system. diff --git a/content/en/technical-overview/concepts/db-schema.md b/content/en/technical-overview/data/db-schema.md similarity index 96% rename from content/en/technical-overview/concepts/db-schema.md rename to content/en/technical-overview/data/db-schema.md index 016738fc8f..7613592670 100644 --- a/content/en/technical-overview/concepts/db-schema.md +++ b/content/en/technical-overview/data/db-schema.md @@ -1,17 +1,23 @@ --- title: "Database schema conventions" linkTitle: "Database Schema" -weight: 8 +weight: 1 description: > Schema for CHT database objects relatedContent: > - building/guides/database + technical-overview/data + technical-overview/data/analytics building/contact-summary/contact-summary-templated building/targets/targets-js building/tasks/tasks-js aliases: - /core/overview/db-schema/ - /technical-overview/db-schema/ + - /technical-overview/concepts/db-schema/ + - /technical-overview/data/db-schema/ + - /technical-overview/data/db-schema/#tasks + - /technical-overview/data/db-schema/#targets + - /technical-overview/data/db-schema/#contacts-persons-and-places --- CouchDB (and PouchDB in the browser) is a JSON-based NoSQL datastore that we use to store our data. While unlike SQL databases there is no enforced schema, code still follows conventions, and this document aims to describe the schema as defined by how our code operates. @@ -100,7 +106,7 @@ Generally when contacts are **used** in the app they are first "hydrated", with } ``` -{{< see-also page="building/guides/data/hydration" title="Document hydration" >}} +{{< see-also page="technical-overview/data/hydration" title="Document hydration" >}} As of version **3.10**, you can connect contacts with other documents via the `linked_docs` property. This allows the app to have access to these linked documents when the contact is used. diff --git a/content/en/building/guides/data/hydration.md b/content/en/technical-overview/data/hydration.md similarity index 96% rename from content/en/building/guides/data/hydration.md rename to content/en/technical-overview/data/hydration.md index cd77c6ebb7..f63ae09d15 100644 --- a/content/en/building/guides/data/hydration.md +++ b/content/en/technical-overview/data/hydration.md @@ -6,9 +6,10 @@ description: > Overview of database document hydration keywords: hydration schema relatedContent: > - technical-overview/concepts/db-schema + technical-overview/data/db-schema aliases: - /apps/guides/data/hydration + - /building/guides/data/hydration --- Documents are connected with each other via their document `_id`. @@ -16,7 +17,7 @@ For example: - a contact document is connected to its parent by storing their `_id` in the `parent` property - a report document is connected to its submitter by storing their `_id` in the `contact` property -{{% see-also page="technical-overview/concepts/db-schema" title="DB Schema" %}} +{{% see-also page="technical-overview/data/db-schema" title="DB Schema" %}} To optimize database storage, documents are "minified" when stored and are "hydrated" when they are used by the app. diff --git a/content/en/building/guides/performance/_index.md b/content/en/technical-overview/data/performance/_index.md similarity index 85% rename from content/en/building/guides/performance/_index.md rename to content/en/technical-overview/data/performance/_index.md index 9c0a6eee6f..17c9cd6466 100644 --- a/content/en/building/guides/performance/_index.md +++ b/content/en/technical-overview/data/performance/_index.md @@ -6,4 +6,5 @@ description: > Guides for tracking and improving the performance of CHT applications and servers aliases: - /apps/guides/performance/ ---- \ No newline at end of file + - /building/guides/performance/ +--- diff --git a/content/en/building/guides/performance/purging.md b/content/en/technical-overview/data/performance/purging.md similarity index 99% rename from content/en/building/guides/performance/purging.md rename to content/en/technical-overview/data/performance/purging.md index 89fe68f3e3..e6d57b827a 100644 --- a/content/en/building/guides/performance/purging.md +++ b/content/en/technical-overview/data/performance/purging.md @@ -8,10 +8,11 @@ keywords: relatedContent: > design/personas/chw-janet building/reports - building/guides/data/invalid-reports + community/contributing/code/troubleshooting/invalid-reports building/reference/app-settings/patient_reports aliases: - /apps/guides/performance/purging + - /building/guides/performance/purging --- *Only available in 3.7.0 and above* diff --git a/content/en/building/guides/performance/replication.md b/content/en/technical-overview/data/performance/replication.md similarity index 99% rename from content/en/building/guides/performance/replication.md rename to content/en/technical-overview/data/performance/replication.md index d281b13a97..034ad6c4a6 100644 --- a/content/en/building/guides/performance/replication.md +++ b/content/en/technical-overview/data/performance/replication.md @@ -7,9 +7,10 @@ description: > keywords: relatedContent: > building/reference/app-settings/replication_depth - building/guides/debugging/replicating-production-data-locally + community/contributing/code/troubleshooting/replicating-production-data-locally aliases: - /apps/guides/performance/replication + - /building/guides/performance/replication --- Replication is what we call it when users download a copy of the data on to their device. diff --git a/content/en/building/guides/performance/telemetry.md b/content/en/technical-overview/data/performance/telemetry.md similarity index 99% rename from content/en/building/guides/performance/telemetry.md rename to content/en/technical-overview/data/performance/telemetry.md index af056090e7..49a5413610 100644 --- a/content/en/building/guides/performance/telemetry.md +++ b/content/en/technical-overview/data/performance/telemetry.md @@ -5,9 +5,11 @@ weight: description: > Performance data of certain user actions relatedContent: > - technical-overview/concepts/data-flows-for-analytics + technical-overview/data/analytics/data-flows-for-analytics aliases: - /apps/guides/performance/telemetry + - /building/guides/performance/telemetry/ + - /technical-overview/data/performance/telemetry --- _Introduced in v3.4.0_ From b3e667a63018f568a540193307dddb19abeedebe Mon Sep 17 00:00:00 2001 From: mrjones-plip Date: Fri, 8 Aug 2025 14:53:14 -0700 Subject: [PATCH 16/16] revise based on feedback and readings --- .../community/contributing/core-committer.md | 61 +++++++++++++++++++ .../community/contributing/core-maintainer.md | 57 ----------------- 2 files changed, 61 insertions(+), 57 deletions(-) create mode 100644 content/en/community/contributing/core-committer.md delete mode 100644 content/en/community/contributing/core-maintainer.md diff --git a/content/en/community/contributing/core-committer.md b/content/en/community/contributing/core-committer.md new file mode 100644 index 0000000000..492e5a1599 --- /dev/null +++ b/content/en/community/contributing/core-committer.md @@ -0,0 +1,61 @@ +--- +title: "Core Committer" +linkTitle: "Core Committer" +weight: 10 +description: > + How to gain commit status on CHT repositories in GitHub +--- + +{{< callout emoji="🥳" >}} +This page covers committer permissions, but everyone is **already** in the CHT community. Please contribute code, documentation, translations, icons and conversation - no permission needed! Our [getting involved with the CHT community](/community/) guide has more info. +{{< /callout >}} + +Being community first software means empowering select individuals to approve changes to the core code powering CHT software without further oversight. This is achieved through quality contributions and peer recognition which enables the wider community to contribute to CHT code at the highest level: as a core committer. + +This is not just for the [CHT Core](https://github.com/medic/cht-core/) repository though! We welcome maintainers want to [update the documentation](https://docs.communityhealthtoolkit.org/) as well. There's actually dozens of repositories that you can contribute to - [check them out](https://github.com/orgs/medic/repositories)! + +If you have any questions about how this works in practice, please post a [question to the forum](https://forum.communityhealthtoolkit.org/c/community/10). + +## Adding a core committer + +Community member needs to have shown they're capable of being helpful to the CHT by having: + +* Contributed code by completing one of: + * Authoring code on a [squad](/community/squads/) * + * 3 features merged to CHT Core outside of a squad * + * 5 bug fixes merged to CHT Core outside of a squad * +* Reviewed 3 pull requests that have been merged +* Created a forum account and have achieved the "[Member](https://forum.communityhealthtoolkit.org/badges/2/member)" badge. +* Attended 3 out of 12 round up calls a year +* Being nominated by the CHT Community (self-nomination is OK!) +* Have 2 existing core maintainers sign off on your nomination + +_\* Features and bug fixes are measured by a pull requests that was successfully merged to `main`. Nominees for core committer of CHT Docs can count docs content as code._ + +### Steps + +* Open an issue on the repository - with TBD template for adding new maintainer +* Ensure all steps are completed per requirements above +* Have 2 existing core maintainers and the 1 nominator add their approval to the ticket +* Ticket is assigned to GH owner who can grant permissions +* TBD specific permissions are added in GitHub by a existing GitHub repo admin + +### Multiple repositories + +If a community member would like access to more than one repository, they can just get 2 of the same (or different) existing maintainers of that repository to sign off on their nomination. You can be a committer on as many repositories as you're interested in. + +## Removing a core committer + +It's important to understand how and when someone is no longer a core committer. This only has one requirement that 3 existing core maintainers agree you should no longer be a maintainer because one or more of: + * You no longer attend round up calls + * You're no longer active on the forums + * It has been over 18 months since your last CHT related GitHub activity + * You have violated the [Code of Conduct](/community/contributing/code-of-conduct) + +### Steps + +* Open an issue on the repository - with TBD template for removing an existing maintainer +* Ensure all steps are completed per requirements above +* Ticket is assigned to GH owner who can grant permissions +* Have 3 existing core maintainers add their approval to the ticket +* TBD permissions are removed in GitHub by a existing GitHub repo admin diff --git a/content/en/community/contributing/core-maintainer.md b/content/en/community/contributing/core-maintainer.md deleted file mode 100644 index 4e8a2fde7f..0000000000 --- a/content/en/community/contributing/core-maintainer.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: "Core Maintainer" -linkTitle: "Core Maintainer" -weight: 10 -description: > - Who can commit directly to CHT repositories in GitHub ---- - -Historically only [Medic](https://medic.org/) teammates were given GitHub permissions to merge code into CHT repositories. This is no longer the case! Now, everyone is treated as an equal: If you meet these requirements, you can commit code. Medic teammates who already have maintainer status do not get exemptions - they've just already meet the requirements. - -This is not just for the [CHT Core](https://github.com/medic/cht-core/) repository though! We welcome maintainers want to [update the documentation](https://docs.communityhealthtoolkit.org/) as well. There's actually dozens of repositories that you can contribute to - [check them out](https://github.com/orgs/medic/repositories)! - -If you have any questions about how this works in practice, please post a [question to the forum](https://forum.communityhealthtoolkit.org/c/community/10). - -## Requirements - -* Participate in a squad where you author, commit and revise code that gets merged to at least one CHT repo *
- **OR**
- 3 features merged to CHT Core outside of a squad *
- **OR**
- 5 bug fixes merged to CHT Core outside of a squad * -* Have a forum account and have achieved the "[Member](https://forum.communityhealthtoolkit.org/badges/2/member)" badge. -* Attend 3 out of 12 round up calls a year -* Have 2 existing core maintainers sign off on your nomination - -_\* Features and bug fixes are measured by a PR that was successfully merged to `main`_ - -## How to add a core maintainer - -* Open an issue on the repository - with TBD template for adding new maintainer -* Ensure all steps are completed per requirements above -* Have 2 existing core maintainers add their approval to the ticket -* Ticket is assigned to GH owner who can grant permissions -* TBD specific permissions are added in GitHub by a existing GitHub repo admin - -## Maintainer status on multiple repositories - -If a community member would like access to more than one repository, they can just get 2 of the same (or different) existing maintainers of that repository to sign off on their nomination. You can be a committer on as many repositories as you're interested in. - -## When to remove a core maintainer - -* 3 existing core maintainers agree you should no longer be a maintainer - -This may because some or all of the following: -* You no longer attend round up calls -* You're no longer active on the forums -* It has been over 18 months since your last CHT related GitHub activity -* You have violated the [Code of Conduct](/community/contributing/code-of-conduct) - - -## How to remove a core maintainer - -* Open an issue on the repository - with TBD template for removing an existing maintainer -* Ensure all steps are completed per requirements above -* Ticket is assigned to GH owner who can grant permissions -* Have 3 existing core maintainers add their approval to the ticket -* TBD permissions are removed in GitHub by a existing GitHub repo admin