pub async fn demote_manager(
pool: &PgPool,
actor: &Actor,
project_id: Uuid,
user_id: Uuid,
) -> AppResult<()>Expand description
Lowers a manager to a plain member (managers and admins): the member keeps the membership and its source, so this works for IdP-synchronised memberships too, which cannot be removed while their user is active.
§Invariants
- Permission: the group is visible to the actor (“not found” otherwise) and the actor manages it (or is an administrator; 403). Managers may demote themselves.
- Locks: the group row (
FOR UPDATE), so membership changes of one group are serialised (asadd_member/remove_member). - Data: the user is a manager of the group (“not found” for a non-member, 409 for a plain member); at least one other active manager remains, except when an administrator demotes (409).
- Audit:
project.demote_manager. - Notifications / webhooks: none.
- Atomic: one transaction.