diff --git a/versioned_docs/version-3.0/concepts/access-governance/responsibility.mdx b/versioned_docs/version-3.0/concepts/access-governance/responsibility.mdx new file mode 100644 index 00000000..175a8b75 --- /dev/null +++ b/versioned_docs/version-3.0/concepts/access-governance/responsibility.mdx @@ -0,0 +1,51 @@ +--- +sidebar_position: 5 +--- + +# Responsibility + +## Definition + +A **responsibility** in Care is a named group of staff, such as Doctors, Nurses, Technicians, or Volunteers. It records the designation that a user holds in that group, and it groups people for work that follows a designation instead of a place. A responsibility is one type of [organization](../access-governance/organization.mdx). It is flat: a responsibility has no child organizations. + +A responsibility answers "which group of staff is this person part of, and as what?". A governance organization answers "which place or administrative boundary does this person belong to?". + +## Key Attributes + +| Components | What it captures | +| --- | --- | +| Name | The name of the responsibility, such as Doctors or Volunteers. | +| Description | What the responsibility is used for. Optional. | +| Managing Responsibilities | The responsibilities that govern this one. | +| Managed Responsibilities | The responsibilities that this one can govern. | +| Members | The users assigned to the responsibility, each with one designation. | + +### Designation + +Every member of a responsibility holds one **designation**. Care ships three designations for responsibilities: + +| Designation | What the member can do | +| --- | --- | +| Admin | Manage the responsibility, and manage its members. | +| Manager | List members, and manage members of the responsibilities that this one governs. | +| Member | View the responsibility. | + +A designation is a [role](../../references/access-governance/role.mdx) with the Responsibility context. Care keeps these designations separate from facility and government organization roles. A designation gives no clinical access on its own. + +### Governance links + +Responsibilities are flat, but they are not isolated. One responsibility can govern another. Care calls the two directions **Managing Responsibilities** and **Managed Responsibilities**. + +A governance link lets an Admin or a Manager of the governing responsibility manage the members of the responsibility below it. A responsibility cannot manage itself. + +:::note +A responsibility is not a permission bundle. A designation names what a person is in the group. A role in a facility or a government organization decides what a person can do with patients and records. See [Roles and permissions](../access-governance/access-control.mdx). +::: + +## Related + +- Flow: [Create a responsibility](../../flows/access-governance/create-a-responsibility.mdx) +- Flow: [Assign a user to a responsibility](../../flows/access-governance/assign-a-user-to-a-responsibility.mdx) +- Flow: [Link responsibilities for governance](../../flows/access-governance/link-responsibilities-for-governance.mdx) +- Concept: [Organization](../access-governance/organization.mdx) · [Roles and permissions](../access-governance/access-control.mdx) · [User](../access-governance/user.mdx) +- Reference: [Organization](../../references/access-governance/organization.mdx) · [Role](../../references/access-governance/role.mdx) diff --git a/versioned_docs/version-3.0/flows/access-governance/_category_.json b/versioned_docs/version-3.0/flows/access-governance/_category_.json new file mode 100644 index 00000000..84656e51 --- /dev/null +++ b/versioned_docs/version-3.0/flows/access-governance/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Access & Governance", + "position": 2, + "key": "access-governance-flows" +} diff --git a/versioned_docs/version-3.0/flows/access-governance/assign-a-user-to-a-responsibility.mdx b/versioned_docs/version-3.0/flows/access-governance/assign-a-user-to-a-responsibility.mdx new file mode 100644 index 00000000..92f799db --- /dev/null +++ b/versioned_docs/version-3.0/flows/access-governance/assign-a-user-to-a-responsibility.mdx @@ -0,0 +1,75 @@ +--- +sidebar_position: 2 +--- + +# How to assign a user to a responsibility + +## Overview + +This flow describes how to add a user to a [responsibility](../../concepts/access-governance/responsibility.mdx), and how to give that user a designation in the group. + +## Pre-requisites + +- The responsibility exists in Care. +- The user has an account in Care. If the user has no account, create the account first. +- You are an Admin of the responsibility, or an Admin or a Manager of a responsibility that governs it. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can List Users in an Organizations | See the members of the responsibility. | +| Can Manage Users in an Organization | Add a member, change a designation, and remove a member. | +| Can Manage Connected Role Organizations | Do the same for the responsibilities that your responsibility governs. | + +:::note +You can grant only a designation that your own designation already covers. You cannot remove a member whose access is above your own. +::: + +## Steps + +### 1. Open the responsibility + +Select the responsibility in the sidebar switcher. Care opens the responsibility and shows its members. + +You can also open the responsibility from the responsibility directory in the administration menu. + +### 2. Open the users list + +Select **Users**. Care lists the current members and the designation of each one. + +### 3. Link the user + +Select **Link User**. Care opens a panel titled **Link User to Organization**. + +| Components | What it captures | +| --- | --- | +| User | The account that you add. Search for the user by username. | +| Role | The designation that the user holds in the group. Use **Select Role**. | + +Select **Link to Organization**. Care adds the member and shows the message "User added to organization successfully". + +### 4. Change a designation + +To change the designation of a member, select **Edit** on the member card. Select a different designation, then save the change. Care shows the message "User role updated successfully". + +Use the same panel to remove the member from the responsibility. + +## Expected Outcome + +- The user appears in the members list of the responsibility, with the designation that you selected. +- The responsibility appears in the sidebar switcher of that user. + +## Related + +Concepts: + +- [Responsibility](../../concepts/access-governance/responsibility.mdx) +- [User](../../concepts/access-governance/user.mdx) +- [Roles and permissions](../../concepts/access-governance/access-control.mdx) + +Flows: + +- [Create a responsibility](./create-a-responsibility.mdx) +- [Link responsibilities for governance](./link-responsibilities-for-governance.mdx) diff --git a/versioned_docs/version-3.0/flows/access-governance/create-a-responsibility.mdx b/versioned_docs/version-3.0/flows/access-governance/create-a-responsibility.mdx new file mode 100644 index 00000000..ee1a67a9 --- /dev/null +++ b/versioned_docs/version-3.0/flows/access-governance/create-a-responsibility.mdx @@ -0,0 +1,62 @@ +--- +sidebar_position: 1 +--- + +# How to create a responsibility + +## Overview + +This flow describes how to create a [responsibility](../../concepts/access-governance/responsibility.mdx) — a named group of staff such as Doctors, Nurses, or Volunteers. + +## Pre-requisites + +- You sign in to Care as a superadmin. Only a superadmin can create, rename, or delete a responsibility. +- You know the name of the group that you want to create. The name must be unique. + +## Permissions + +| Permission | Access | +| --- | --- | +| Superadmin | Create, rename, and delete a responsibility. | + +:::note +No system role grants this action. Care rejects the request from every non-superadmin account. +::: + +## Steps + +### 1. Open the responsibility workspace + +Select **Organizations** in the administration menu. Then select **Responsibilities**. Care shows the responsibility directory on the left, and the details panel on the right. + +### 2. Start a new responsibility + +Select **Create Responsibility**. Care opens a panel titled **Create Responsibility**. + +### 3. Enter the details + +| Components | What it captures | +| --- | --- | +| Name | The name of the group, such as Doctors. Required. | +| Description | What the responsibility is used for. Optional. | + +### 4. Save the responsibility + +Select **Create Responsibility** at the bottom of the panel. Care creates the group and shows the message "Organization created successfully". + +## Expected Outcome + +- The new responsibility appears in the responsibility directory. +- You can now assign users to it, and link it to other responsibilities for governance. + +## Related + +Concepts: + +- [Responsibility](../../concepts/access-governance/responsibility.mdx) +- [Organization](../../concepts/access-governance/organization.mdx) + +Flows: + +- [Assign a user to a responsibility](./assign-a-user-to-a-responsibility.mdx) +- [Link responsibilities for governance](./link-responsibilities-for-governance.mdx) diff --git a/versioned_docs/version-3.0/flows/access-governance/link-responsibilities-for-governance.mdx b/versioned_docs/version-3.0/flows/access-governance/link-responsibilities-for-governance.mdx new file mode 100644 index 00000000..56394e9c --- /dev/null +++ b/versioned_docs/version-3.0/flows/access-governance/link-responsibilities-for-governance.mdx @@ -0,0 +1,69 @@ +--- +sidebar_position: 3 +--- + +# How to link responsibilities for governance + +## Overview + +This flow describes how to connect one [responsibility](../../concepts/access-governance/responsibility.mdx) to another, so that the members of the governing group can manage the members of the group below it. + +## Pre-requisites + +- Both responsibilities exist in Care. +- You can manage both responsibilities. A superadmin, or an Admin of both groups, can make the link. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can Manage Organizations | Add or remove a governance link. Care checks this permission on both responsibilities. | + +## Steps + +### 1. Open the responsibility + +Select **Organizations** in the administration menu. Then select **Responsibilities**. Select the responsibility that you want to change. + +### 2. Open the governance panel + +Find the **Governance** section of the details panel. Care shows two lists: + +| Components | What it captures | +| --- | --- | +| Managing Responsibilities | The responsibilities that govern this one. | +| Managed Responsibilities | The responsibilities that this one can govern. | + +### 3. Add a managing responsibility + +Select a responsibility in **Add Managing Organization**. Then select **Add**. Care creates the link and shows the message "Managing organization added successfully". + +### 4. Add a managed responsibility + +Select a responsibility in **Add Managed Responsibility**. Then select **Add**. Care creates the link and shows the message "Managed responsibility added successfully". + +:::note +A responsibility cannot manage itself. Care shows the message "A responsibility cannot manage itself". +::: + +### 5. Remove a link + +Select the remove icon next to the responsibility in either list. Care removes the link. + +## Expected Outcome + +- The two responsibilities appear in each other's governance lists. +- An Admin or a Manager of the governing responsibility can now list and manage the members of the governed responsibility. + +## Related + +Concepts: + +- [Responsibility](../../concepts/access-governance/responsibility.mdx) +- [Organization](../../concepts/access-governance/organization.mdx) + +Flows: + +- [Create a responsibility](./create-a-responsibility.mdx) +- [Assign a user to a responsibility](./assign-a-user-to-a-responsibility.mdx) diff --git a/versioned_docs/version-3.0/references/access-governance/responsibility.mdx b/versioned_docs/version-3.0/references/access-governance/responsibility.mdx new file mode 100644 index 00000000..2803ab97 --- /dev/null +++ b/versioned_docs/version-3.0/references/access-governance/responsibility.mdx @@ -0,0 +1,103 @@ +--- +sidebar_position: 6 +--- + +# Responsibility + +Technical reference for the **responsibility** — the `role` organization type of the `Organization` model in Care EMR. See the [Responsibility](../../concepts/access-governance/responsibility.mdx) concept for the plain-language layer, and the [Organization](../access-governance/organization.mdx) reference for the full model. + +**Source:** + +- [`care/emr/models/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/models/organization.py) +- [`care/emr/resources/organization/spec.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/organization/spec.py) +- [`care/emr/resources/organization/organization_user_spec.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/organization/organization_user_spec.py) +- [`care/emr/api/viewsets/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/api/viewsets/organization.py) +- [`care/security/authorization/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/security/authorization/organization.py) +- [`care/security/permissions/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/security/permissions/organization.py) +- [`care/security/roles/role.py`](https://github.com/ohcnetwork/care/blob/develop/care/security/roles/role.py) + +A responsibility has no model of its own. It is an `Organization` row whose `org_type` is `role`, one of the four values of `OrganizationTypeChoices` (`team`, `govt`, `role`, `product_supplier`). The behaviour that makes it a responsibility comes from the viewset, the authorization handler, and the role contexts. + +## Distinguishing fields + +| Field | Type | Behaviour for `org_type = "role"` | +| --- | --- | --- | +| `org_type` | `CharField(255)` | Fixed to `role`. Writes bind to `OrganizationTypeChoices` | +| `parent` | `FK(self), nullable` | Always null. `authorize_create` rejects any organization created under a `role` organization | +| `has_children` | `BooleanField` | Always `False`. Responsibilities are flat | +| `managing_organizations` | `ArrayField[int]` | Internal ids of the responsibilities that govern this one. Only `role` organizations may appear here | +| `name` | `CharField(255)` | Unique among siblings, enforced by `Organization.validate_uniqueness` | +| `description` | `TextField, nullable` | Free text. Defaults to `""` in the spec | + +`OrganizationRetrieveSpec` expands `managing_organizations` to nested `OrganizationReadSpec` JSON, and adds the caller's `permissions`. + +## Membership + +Membership is an `OrganizationUser` row: `organization` + `user` + `role`. For a responsibility, that `role` is the member's designation. + +```text +OrganizationUser + organization -> Organization (org_type = "role") + user -> users.User + role -> security.RoleModel (contexts contains ROLE_ORG) +``` + +`OrganizationUser.save()` clears `User.cached_role_orgs` whenever the linked organization is of type `role`, so the user's cached responsibility list rebuilds on the next read. `User.get_cached_role_orgs()` repopulates it from `OrganizationUser.get_cached_role_orgs(user_id)`, which serializes each membership with `OrganizationUserExtendedReadSpec`. `UserSpec` and `UserRetrieveSpec` expose the result as `role_orgs`. + +`UserCreateSpec` accepts `role_orgs: list[UserRoleOrgCreateSpec]` (each `{ organization, role }`). `UserViewSet.perform_create` creates the memberships inside the same transaction, rejects any organization whose `org_type` is not `role`, and authorizes each pair through `can_manage_organization_users_obj`. + +## Designation roles + +`RoleModel.contexts` is an `ArrayField` of `RoleContext` values: `FACILITY`, `GOVT_ORG`, `ROLE_ORG`. Only roles carrying `ROLE_ORG` are selectable as designations. `RoleController.internal_roles` defines three: + +| Role constant | Name | Description | +| --- | --- | --- | +| `ROLE_ORGANIZATION_ADMIN_ROLE` | Admin | Administrator of a role organization | +| `ROLE_ORGANIZATION_MANAGER_ROLE` | Manager | Manager of a role organization | +| `ROLE_ORGANIZATION_MEMBER_ROLE` | Member | Member of a role organization | + +## Authorization + +The `OrganizationViewSet` treats responsibilities differently from other organization types: + +| Action | Behaviour | +| --- | --- | +| create | `authorize_create` raises `PermissionDenied` for `org_type` in `govt`, `role` unless the caller is a superuser | +| update | `authorize_update` raises `PermissionDenied` for `org_type` in `govt`, `role` unless the caller is a superuser | +| destroy | `authorize_destroy` raises `PermissionDenied` for `org_type` in `govt`, `role` unless the caller is a superuser, and for any organization that still has children | +| retrieve | `get_queryset` returns the unfiltered queryset when the requested organization is of type `role` | +| `managing_organization` | Both the target and the requested organization must be of type `role`. The caller needs `can_manage_organization_obj` on both | +| `accessible_role_organizations` | See below | + +`OrganizationAccess.can_list_organization_users_obj` and `can_manage_organization_users_obj` widen the search set for a `role` organization from `[*parent_cache, id]` to `[id, *managing_organizations]`. `can_manage_organization_users_obj` therefore passes when the caller holds `can_manage_organization_users` on the responsibility itself, **or** `can_manage_connected_role_organizations` on one of its managing responsibilities. `check_role_subset` still applies: the requested designation must be a subset of the caller's own permissions. + +### Permission slugs + +| Permission | Roles | +| --- | --- | +| `can_view_organization` | Facility Admin, Admin, Staff, Doctor, Administrator, Nurse, Volunteer, Pharmacist, Admin (responsibility), Manager (responsibility), Member (responsibility) | +| `can_manage_organization` | Admin, Admin (responsibility) | +| `can_list_organization_users` | Facility Admin, Admin, Staff, Doctor, Administrator, Nurse, Volunteer, Pharmacist, Admin (responsibility), Manager (responsibility) | +| `can_manage_organization_users` | Admin, Administrator, Facility Admin, Admin (responsibility) | +| `can_manage_connected_role_organizations` | Admin (responsibility), Manager (responsibility) | + +### `accessible_role_organizations` + +`GET /api/v1/organization/accessible_role_organizations/` returns `{ count, results }`, where each result is `{ role, organization }`. The set is: + +- every `role` organization the caller is a member of, with `role` set to the caller's designation, and +- every `role` organization governed by a responsibility where the caller holds `can_manage_connected_role_organizations`, with `role` set to `null` when the caller is not a member. + +Superusers receive every `role` organization. + +## API integration notes + +- Responsibilities use the standard organization endpoints under `/api/v1/organization/`, filtered with `org_type=role`. +- Governance links are written through `POST /api/v1/organization/{id}/managing_organization/` with `{ organization, action }`, where `action` is `add` or `remove`. The body's `organization` is the managing responsibility, and `{id}` is the managed one. +- Members are read and written through `/api/v1/organization/{id}/users/`. +- `role_orgs` on the user read specs is a cached, denormalized list. Treat it as read-only. + +## Related + +- Concept: [Responsibility](../../concepts/access-governance/responsibility.mdx) +- Reference: [Organization](../access-governance/organization.mdx) · [Role](../access-governance/role.mdx) · [User](../access-governance/user.mdx) · [Permission](../access-governance/permission.mdx) diff --git a/versioned_docs/version-3.1/concepts/access-governance/responsibility.mdx b/versioned_docs/version-3.1/concepts/access-governance/responsibility.mdx new file mode 100644 index 00000000..175a8b75 --- /dev/null +++ b/versioned_docs/version-3.1/concepts/access-governance/responsibility.mdx @@ -0,0 +1,51 @@ +--- +sidebar_position: 5 +--- + +# Responsibility + +## Definition + +A **responsibility** in Care is a named group of staff, such as Doctors, Nurses, Technicians, or Volunteers. It records the designation that a user holds in that group, and it groups people for work that follows a designation instead of a place. A responsibility is one type of [organization](../access-governance/organization.mdx). It is flat: a responsibility has no child organizations. + +A responsibility answers "which group of staff is this person part of, and as what?". A governance organization answers "which place or administrative boundary does this person belong to?". + +## Key Attributes + +| Components | What it captures | +| --- | --- | +| Name | The name of the responsibility, such as Doctors or Volunteers. | +| Description | What the responsibility is used for. Optional. | +| Managing Responsibilities | The responsibilities that govern this one. | +| Managed Responsibilities | The responsibilities that this one can govern. | +| Members | The users assigned to the responsibility, each with one designation. | + +### Designation + +Every member of a responsibility holds one **designation**. Care ships three designations for responsibilities: + +| Designation | What the member can do | +| --- | --- | +| Admin | Manage the responsibility, and manage its members. | +| Manager | List members, and manage members of the responsibilities that this one governs. | +| Member | View the responsibility. | + +A designation is a [role](../../references/access-governance/role.mdx) with the Responsibility context. Care keeps these designations separate from facility and government organization roles. A designation gives no clinical access on its own. + +### Governance links + +Responsibilities are flat, but they are not isolated. One responsibility can govern another. Care calls the two directions **Managing Responsibilities** and **Managed Responsibilities**. + +A governance link lets an Admin or a Manager of the governing responsibility manage the members of the responsibility below it. A responsibility cannot manage itself. + +:::note +A responsibility is not a permission bundle. A designation names what a person is in the group. A role in a facility or a government organization decides what a person can do with patients and records. See [Roles and permissions](../access-governance/access-control.mdx). +::: + +## Related + +- Flow: [Create a responsibility](../../flows/access-governance/create-a-responsibility.mdx) +- Flow: [Assign a user to a responsibility](../../flows/access-governance/assign-a-user-to-a-responsibility.mdx) +- Flow: [Link responsibilities for governance](../../flows/access-governance/link-responsibilities-for-governance.mdx) +- Concept: [Organization](../access-governance/organization.mdx) · [Roles and permissions](../access-governance/access-control.mdx) · [User](../access-governance/user.mdx) +- Reference: [Organization](../../references/access-governance/organization.mdx) · [Role](../../references/access-governance/role.mdx) diff --git a/versioned_docs/version-3.1/flows/access-governance/_category_.json b/versioned_docs/version-3.1/flows/access-governance/_category_.json new file mode 100644 index 00000000..84656e51 --- /dev/null +++ b/versioned_docs/version-3.1/flows/access-governance/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Access & Governance", + "position": 2, + "key": "access-governance-flows" +} diff --git a/versioned_docs/version-3.1/flows/access-governance/assign-a-user-to-a-responsibility.mdx b/versioned_docs/version-3.1/flows/access-governance/assign-a-user-to-a-responsibility.mdx new file mode 100644 index 00000000..92f799db --- /dev/null +++ b/versioned_docs/version-3.1/flows/access-governance/assign-a-user-to-a-responsibility.mdx @@ -0,0 +1,75 @@ +--- +sidebar_position: 2 +--- + +# How to assign a user to a responsibility + +## Overview + +This flow describes how to add a user to a [responsibility](../../concepts/access-governance/responsibility.mdx), and how to give that user a designation in the group. + +## Pre-requisites + +- The responsibility exists in Care. +- The user has an account in Care. If the user has no account, create the account first. +- You are an Admin of the responsibility, or an Admin or a Manager of a responsibility that governs it. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can List Users in an Organizations | See the members of the responsibility. | +| Can Manage Users in an Organization | Add a member, change a designation, and remove a member. | +| Can Manage Connected Role Organizations | Do the same for the responsibilities that your responsibility governs. | + +:::note +You can grant only a designation that your own designation already covers. You cannot remove a member whose access is above your own. +::: + +## Steps + +### 1. Open the responsibility + +Select the responsibility in the sidebar switcher. Care opens the responsibility and shows its members. + +You can also open the responsibility from the responsibility directory in the administration menu. + +### 2. Open the users list + +Select **Users**. Care lists the current members and the designation of each one. + +### 3. Link the user + +Select **Link User**. Care opens a panel titled **Link User to Organization**. + +| Components | What it captures | +| --- | --- | +| User | The account that you add. Search for the user by username. | +| Role | The designation that the user holds in the group. Use **Select Role**. | + +Select **Link to Organization**. Care adds the member and shows the message "User added to organization successfully". + +### 4. Change a designation + +To change the designation of a member, select **Edit** on the member card. Select a different designation, then save the change. Care shows the message "User role updated successfully". + +Use the same panel to remove the member from the responsibility. + +## Expected Outcome + +- The user appears in the members list of the responsibility, with the designation that you selected. +- The responsibility appears in the sidebar switcher of that user. + +## Related + +Concepts: + +- [Responsibility](../../concepts/access-governance/responsibility.mdx) +- [User](../../concepts/access-governance/user.mdx) +- [Roles and permissions](../../concepts/access-governance/access-control.mdx) + +Flows: + +- [Create a responsibility](./create-a-responsibility.mdx) +- [Link responsibilities for governance](./link-responsibilities-for-governance.mdx) diff --git a/versioned_docs/version-3.1/flows/access-governance/create-a-responsibility.mdx b/versioned_docs/version-3.1/flows/access-governance/create-a-responsibility.mdx new file mode 100644 index 00000000..ee1a67a9 --- /dev/null +++ b/versioned_docs/version-3.1/flows/access-governance/create-a-responsibility.mdx @@ -0,0 +1,62 @@ +--- +sidebar_position: 1 +--- + +# How to create a responsibility + +## Overview + +This flow describes how to create a [responsibility](../../concepts/access-governance/responsibility.mdx) — a named group of staff such as Doctors, Nurses, or Volunteers. + +## Pre-requisites + +- You sign in to Care as a superadmin. Only a superadmin can create, rename, or delete a responsibility. +- You know the name of the group that you want to create. The name must be unique. + +## Permissions + +| Permission | Access | +| --- | --- | +| Superadmin | Create, rename, and delete a responsibility. | + +:::note +No system role grants this action. Care rejects the request from every non-superadmin account. +::: + +## Steps + +### 1. Open the responsibility workspace + +Select **Organizations** in the administration menu. Then select **Responsibilities**. Care shows the responsibility directory on the left, and the details panel on the right. + +### 2. Start a new responsibility + +Select **Create Responsibility**. Care opens a panel titled **Create Responsibility**. + +### 3. Enter the details + +| Components | What it captures | +| --- | --- | +| Name | The name of the group, such as Doctors. Required. | +| Description | What the responsibility is used for. Optional. | + +### 4. Save the responsibility + +Select **Create Responsibility** at the bottom of the panel. Care creates the group and shows the message "Organization created successfully". + +## Expected Outcome + +- The new responsibility appears in the responsibility directory. +- You can now assign users to it, and link it to other responsibilities for governance. + +## Related + +Concepts: + +- [Responsibility](../../concepts/access-governance/responsibility.mdx) +- [Organization](../../concepts/access-governance/organization.mdx) + +Flows: + +- [Assign a user to a responsibility](./assign-a-user-to-a-responsibility.mdx) +- [Link responsibilities for governance](./link-responsibilities-for-governance.mdx) diff --git a/versioned_docs/version-3.1/flows/access-governance/link-responsibilities-for-governance.mdx b/versioned_docs/version-3.1/flows/access-governance/link-responsibilities-for-governance.mdx new file mode 100644 index 00000000..56394e9c --- /dev/null +++ b/versioned_docs/version-3.1/flows/access-governance/link-responsibilities-for-governance.mdx @@ -0,0 +1,69 @@ +--- +sidebar_position: 3 +--- + +# How to link responsibilities for governance + +## Overview + +This flow describes how to connect one [responsibility](../../concepts/access-governance/responsibility.mdx) to another, so that the members of the governing group can manage the members of the group below it. + +## Pre-requisites + +- Both responsibilities exist in Care. +- You can manage both responsibilities. A superadmin, or an Admin of both groups, can make the link. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can Manage Organizations | Add or remove a governance link. Care checks this permission on both responsibilities. | + +## Steps + +### 1. Open the responsibility + +Select **Organizations** in the administration menu. Then select **Responsibilities**. Select the responsibility that you want to change. + +### 2. Open the governance panel + +Find the **Governance** section of the details panel. Care shows two lists: + +| Components | What it captures | +| --- | --- | +| Managing Responsibilities | The responsibilities that govern this one. | +| Managed Responsibilities | The responsibilities that this one can govern. | + +### 3. Add a managing responsibility + +Select a responsibility in **Add Managing Organization**. Then select **Add**. Care creates the link and shows the message "Managing organization added successfully". + +### 4. Add a managed responsibility + +Select a responsibility in **Add Managed Responsibility**. Then select **Add**. Care creates the link and shows the message "Managed responsibility added successfully". + +:::note +A responsibility cannot manage itself. Care shows the message "A responsibility cannot manage itself". +::: + +### 5. Remove a link + +Select the remove icon next to the responsibility in either list. Care removes the link. + +## Expected Outcome + +- The two responsibilities appear in each other's governance lists. +- An Admin or a Manager of the governing responsibility can now list and manage the members of the governed responsibility. + +## Related + +Concepts: + +- [Responsibility](../../concepts/access-governance/responsibility.mdx) +- [Organization](../../concepts/access-governance/organization.mdx) + +Flows: + +- [Create a responsibility](./create-a-responsibility.mdx) +- [Assign a user to a responsibility](./assign-a-user-to-a-responsibility.mdx) diff --git a/versioned_docs/version-3.1/references/access-governance/responsibility.mdx b/versioned_docs/version-3.1/references/access-governance/responsibility.mdx new file mode 100644 index 00000000..2803ab97 --- /dev/null +++ b/versioned_docs/version-3.1/references/access-governance/responsibility.mdx @@ -0,0 +1,103 @@ +--- +sidebar_position: 6 +--- + +# Responsibility + +Technical reference for the **responsibility** — the `role` organization type of the `Organization` model in Care EMR. See the [Responsibility](../../concepts/access-governance/responsibility.mdx) concept for the plain-language layer, and the [Organization](../access-governance/organization.mdx) reference for the full model. + +**Source:** + +- [`care/emr/models/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/models/organization.py) +- [`care/emr/resources/organization/spec.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/organization/spec.py) +- [`care/emr/resources/organization/organization_user_spec.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/organization/organization_user_spec.py) +- [`care/emr/api/viewsets/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/api/viewsets/organization.py) +- [`care/security/authorization/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/security/authorization/organization.py) +- [`care/security/permissions/organization.py`](https://github.com/ohcnetwork/care/blob/develop/care/security/permissions/organization.py) +- [`care/security/roles/role.py`](https://github.com/ohcnetwork/care/blob/develop/care/security/roles/role.py) + +A responsibility has no model of its own. It is an `Organization` row whose `org_type` is `role`, one of the four values of `OrganizationTypeChoices` (`team`, `govt`, `role`, `product_supplier`). The behaviour that makes it a responsibility comes from the viewset, the authorization handler, and the role contexts. + +## Distinguishing fields + +| Field | Type | Behaviour for `org_type = "role"` | +| --- | --- | --- | +| `org_type` | `CharField(255)` | Fixed to `role`. Writes bind to `OrganizationTypeChoices` | +| `parent` | `FK(self), nullable` | Always null. `authorize_create` rejects any organization created under a `role` organization | +| `has_children` | `BooleanField` | Always `False`. Responsibilities are flat | +| `managing_organizations` | `ArrayField[int]` | Internal ids of the responsibilities that govern this one. Only `role` organizations may appear here | +| `name` | `CharField(255)` | Unique among siblings, enforced by `Organization.validate_uniqueness` | +| `description` | `TextField, nullable` | Free text. Defaults to `""` in the spec | + +`OrganizationRetrieveSpec` expands `managing_organizations` to nested `OrganizationReadSpec` JSON, and adds the caller's `permissions`. + +## Membership + +Membership is an `OrganizationUser` row: `organization` + `user` + `role`. For a responsibility, that `role` is the member's designation. + +```text +OrganizationUser + organization -> Organization (org_type = "role") + user -> users.User + role -> security.RoleModel (contexts contains ROLE_ORG) +``` + +`OrganizationUser.save()` clears `User.cached_role_orgs` whenever the linked organization is of type `role`, so the user's cached responsibility list rebuilds on the next read. `User.get_cached_role_orgs()` repopulates it from `OrganizationUser.get_cached_role_orgs(user_id)`, which serializes each membership with `OrganizationUserExtendedReadSpec`. `UserSpec` and `UserRetrieveSpec` expose the result as `role_orgs`. + +`UserCreateSpec` accepts `role_orgs: list[UserRoleOrgCreateSpec]` (each `{ organization, role }`). `UserViewSet.perform_create` creates the memberships inside the same transaction, rejects any organization whose `org_type` is not `role`, and authorizes each pair through `can_manage_organization_users_obj`. + +## Designation roles + +`RoleModel.contexts` is an `ArrayField` of `RoleContext` values: `FACILITY`, `GOVT_ORG`, `ROLE_ORG`. Only roles carrying `ROLE_ORG` are selectable as designations. `RoleController.internal_roles` defines three: + +| Role constant | Name | Description | +| --- | --- | --- | +| `ROLE_ORGANIZATION_ADMIN_ROLE` | Admin | Administrator of a role organization | +| `ROLE_ORGANIZATION_MANAGER_ROLE` | Manager | Manager of a role organization | +| `ROLE_ORGANIZATION_MEMBER_ROLE` | Member | Member of a role organization | + +## Authorization + +The `OrganizationViewSet` treats responsibilities differently from other organization types: + +| Action | Behaviour | +| --- | --- | +| create | `authorize_create` raises `PermissionDenied` for `org_type` in `govt`, `role` unless the caller is a superuser | +| update | `authorize_update` raises `PermissionDenied` for `org_type` in `govt`, `role` unless the caller is a superuser | +| destroy | `authorize_destroy` raises `PermissionDenied` for `org_type` in `govt`, `role` unless the caller is a superuser, and for any organization that still has children | +| retrieve | `get_queryset` returns the unfiltered queryset when the requested organization is of type `role` | +| `managing_organization` | Both the target and the requested organization must be of type `role`. The caller needs `can_manage_organization_obj` on both | +| `accessible_role_organizations` | See below | + +`OrganizationAccess.can_list_organization_users_obj` and `can_manage_organization_users_obj` widen the search set for a `role` organization from `[*parent_cache, id]` to `[id, *managing_organizations]`. `can_manage_organization_users_obj` therefore passes when the caller holds `can_manage_organization_users` on the responsibility itself, **or** `can_manage_connected_role_organizations` on one of its managing responsibilities. `check_role_subset` still applies: the requested designation must be a subset of the caller's own permissions. + +### Permission slugs + +| Permission | Roles | +| --- | --- | +| `can_view_organization` | Facility Admin, Admin, Staff, Doctor, Administrator, Nurse, Volunteer, Pharmacist, Admin (responsibility), Manager (responsibility), Member (responsibility) | +| `can_manage_organization` | Admin, Admin (responsibility) | +| `can_list_organization_users` | Facility Admin, Admin, Staff, Doctor, Administrator, Nurse, Volunteer, Pharmacist, Admin (responsibility), Manager (responsibility) | +| `can_manage_organization_users` | Admin, Administrator, Facility Admin, Admin (responsibility) | +| `can_manage_connected_role_organizations` | Admin (responsibility), Manager (responsibility) | + +### `accessible_role_organizations` + +`GET /api/v1/organization/accessible_role_organizations/` returns `{ count, results }`, where each result is `{ role, organization }`. The set is: + +- every `role` organization the caller is a member of, with `role` set to the caller's designation, and +- every `role` organization governed by a responsibility where the caller holds `can_manage_connected_role_organizations`, with `role` set to `null` when the caller is not a member. + +Superusers receive every `role` organization. + +## API integration notes + +- Responsibilities use the standard organization endpoints under `/api/v1/organization/`, filtered with `org_type=role`. +- Governance links are written through `POST /api/v1/organization/{id}/managing_organization/` with `{ organization, action }`, where `action` is `add` or `remove`. The body's `organization` is the managing responsibility, and `{id}` is the managed one. +- Members are read and written through `/api/v1/organization/{id}/users/`. +- `role_orgs` on the user read specs is a cached, denormalized list. Treat it as read-only. + +## Related + +- Concept: [Responsibility](../../concepts/access-governance/responsibility.mdx) +- Reference: [Organization](../access-governance/organization.mdx) · [Role](../access-governance/role.mdx) · [User](../access-governance/user.mdx) · [Permission](../access-governance/permission.mdx) diff --git a/versioned_sidebars/version-3.0-sidebars.json b/versioned_sidebars/version-3.0-sidebars.json index d253abeb..de5ad399 100644 --- a/versioned_sidebars/version-3.0-sidebars.json +++ b/versioned_sidebars/version-3.0-sidebars.json @@ -21,7 +21,20 @@ "type": "category", "label": "Clinical", "key": "clinical-flows", - "items": ["flows/clinical/create-patient", "flows/clinical/manage-encounter-care-team"] + "items": [ + "flows/clinical/create-patient", + "flows/clinical/manage-encounter-care-team" + ] + }, + { + "type": "category", + "label": "Access & Governance", + "key": "access-governance-flows", + "items": [ + "flows/access-governance/create-a-responsibility", + "flows/access-governance/assign-a-user-to-a-responsibility", + "flows/access-governance/link-responsibilities-for-governance" + ] } ] }, @@ -37,4 +50,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/versioned_sidebars/version-3.1-sidebars.json b/versioned_sidebars/version-3.1-sidebars.json index ffc66fb9..97adb169 100644 --- a/versioned_sidebars/version-3.1-sidebars.json +++ b/versioned_sidebars/version-3.1-sidebars.json @@ -40,6 +40,16 @@ }, "flows/clinical/manage-encounter-care-team" ] + }, + { + "type": "category", + "label": "Access & Governance", + "key": "access-governance-flows", + "items": [ + "flows/access-governance/create-a-responsibility", + "flows/access-governance/assign-a-user-to-a-responsibility", + "flows/access-governance/link-responsibilities-for-governance" + ] } ] }, @@ -55,4 +65,4 @@ ] } ] -} +} \ No newline at end of file