Docs: groups and roles/permissions architecture, Group moduledoc
All checks were successful
continuous-integration/drone/push Build is passing

- groups-architecture: normal_user and admin can manage groups.
- roles-and-permissions: matrix and MembershipFeeCycle :linked for own_data.
- group_policies_test: update moduledoc.
This commit is contained in:
Moritz 2026-02-04 09:20:26 +01:00
parent 178f5a01c7
commit c035d0f141
3 changed files with 13 additions and 12 deletions

View file

@ -420,9 +420,9 @@ lib/
**Actions:**
- `read` - View groups (all permission sets)
- `create` - Create groups (admin only)
- `update` - Edit groups (admin only)
- `destroy` - Delete groups (admin only)
- `create` - Create groups (normal_user and admin)
- `update` - Edit groups (normal_user and admin)
- `destroy` - Delete groups (normal_user and admin)
**Scopes:**
- `:all` - All groups (for all permission sets that have read access)
@ -444,7 +444,7 @@ lib/
**Own Data Permission Set:**
- `read` action on `Group` resource with `:all` scope - granted
**Note:** All permission sets use `:all` scope for groups. Groups are considered public information that all users with member read permission can view. Only admins can manage (create/update/destroy) groups.
**Note:** All permission sets use `:all` scope for groups. Groups are considered public information that all users with member read permission can view. normal_user and admin can manage (create/update/destroy) groups.
### Member-Group Association Permissions

View file

@ -97,10 +97,10 @@ Control CRUD operations on:
- CustomFieldValue (custom field values)
- CustomField (custom field definitions)
- Role (role management)
- Group (group definitions; read all, create/update/destroy admin only)
- Group (group definitions; read all, create/update/destroy normal_user and admin)
- MemberGroup (membergroup associations; own_data read :linked, read_only read :all, normal_user/admin create/destroy)
- MembershipFeeType (fee type definitions; all read, admin-only create/update/destroy)
- MembershipFeeCycle (fee cycles; all read, normal_user/admin read+create+update+destroy; manual "Regenerate Cycles" for normal_user and admin)
- MembershipFeeCycle (fee cycles; own_data read :linked, read_only read :all, normal_user/admin read+create+update+destroy; manual "Regenerate Cycles" for normal_user and admin)
**4. Page-Level Permissions**
@ -691,11 +691,12 @@ Quick reference table showing what each permission set allows:
| **CustomFieldValue** (all) | - | R | R, C, U, D | R, C, U, D |
| **CustomField** (all) | R | R | R | R, C, U, D |
| **Role** (all) | - | - | - | R, C, U, D |
| **Group** (all) | R | R | R | R, C, U, D |
| **Group** (all) | R | R | R, C, U, D | R, C, U, D |
| **MemberGroup** (linked) | R | - | - | - |
| **MemberGroup** (all) | - | R | R, C, D | R, C, D |
| **MembershipFeeType** (all) | R | R | R | R, C, U, D |
| **MembershipFeeCycle** (all) | R | R | R, C, U, D | R, C, U, D |
| **MembershipFeeCycle** (linked) | R | - | - | - |
| **MembershipFeeCycle** (all) | - | R | R, C, U, D | R, C, U, D |
**Legend:** R=Read, C=Create, U=Update, D=Destroy
@ -1217,13 +1218,13 @@ Only admins can change a user's role. The `update_user` action accepts `role_id`
**Location:** `lib/membership/group.ex`
Policies use `HasPermission` for read/create/update/destroy. All permission sets can read; only admin can create, update, destroy. No bypass (scope :all only in PermissionSets).
Policies use `HasPermission` for read/create/update/destroy. All permission sets can read; normal_user and admin can create, update, destroy. No bypass (scope :all only in PermissionSets).
### MemberGroup Resource Policies
**Location:** `lib/membership/member_group.ex`
Bypass for read with `expr(member_id == ^actor(:member_id))` (own_data list); HasPermission for read (read_only/normal_user/admin :all) and create/destroy (normal_user + admin only). HasPermission applies `:linked` scope for MemberGroup (see HasPermission apply_scope).
Bypass for read restricted to own_data (MemberGroupReadLinkedForOwnData check: own_data only, filter `member_id == actor.member_id`); HasPermission for read (read_only/normal_user/admin :all) and create/destroy (normal_user + admin only). Admin with member_id set still gets :all from HasPermission (bypass does not apply).
### MembershipFeeType Resource Policies
@ -1235,7 +1236,7 @@ Policies use `HasPermission` for read/create/update/destroy. All permission sets
**Location:** `lib/membership_fees/membership_fee_cycle.ex`
Policies use `HasPermission` for read/create/update/destroy. All can read; read_only cannot update/create/destroy; normal_user and admin can read, create, update, and destroy (including mark_as_paid and manual "Regenerate Cycles" in the member detail view; UI button is shown when `can_create_cycle`).
Bypass for read restricted to own_data (MembershipFeeCycleReadLinkedForOwnData: own_data only, filter `member_id == actor.member_id`); HasPermission for read (read_only/normal_user/admin :all) and create/update/destroy. own_data can only read cycles of the linked member; read_only can read all; normal_user and admin can read, create, update, and destroy (including mark_as_paid and manual "Regenerate Cycles"; UI button when `can_create_cycle`). Regenerate-cycles handler enforces `can?(:create, MembershipFeeCycle)` server-side.
---

View file

@ -3,7 +3,7 @@ defmodule Mv.Membership.GroupPoliciesTest do
Tests for Group resource authorization policies.
Verifies that own_data, read_only, normal_user can read groups;
only admin can create, update, and destroy groups.
normal_user and admin can create, update, and destroy groups.
"""
use Mv.DataCase, async: false