Skip to content

feat: add team role management - #41

Merged
bjarn merged 1 commit into
feat/team-invitesfrom
feat/team-roles
Oct 21, 2026
Merged

bjarn merged 1 commit into
feat/team-invitesfrom
feat/team-roles

Conversation

@bjarn

@bjarn bjarn commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

What changed

Non-breaking. Adds team role management as methods on team, next to the existing team.roles() list. Stacked on the team invites PR.

  • team.retrieve_role(role_id) returns a TeamRoleData, now with its description.
  • team.create_role(body) creates a custom role (CreateTeamRoleData {name, description?, permissions}). It needs a plan with custom roles; permissions must include what they depend on, and names are unique within the team.
  • team.update_role(role_id, body) replaces the name, description and permissions of a custom role. Built-in roles can't be changed.
  • team.delete_role(role_id, query=None) deletes a custom role and returns a MessageResponse. While the role is still assigned to members, invites or SCIM groups, pass {"replacement_role_id": ...} (DeleteTeamRoleQuery), the role that receives those assignments. Without it, no query parameter is sent. Built-in roles can't be deleted.
  • team.duplicate_role(role_id, body) copies a role under a new name (DuplicateTeamRoleData {name, description?}). Without a description, the copy keeps the source role's. The Owner role can't be duplicated.
  • All five use the team token and take the usual keyword-only timeout; none takes an idempotency key. The optional query follows the SDK's existing pattern (domains.retrieve(domain_id, query)).
  • A 409 raises ConflictError with the error code (for example built_in_role_immutable); a 422 raises ValidationError. Empty or .. role IDs raise LettermintConfigError before any request.
  • The coverage test no longer lists the role operations as pending; only member removal is left for the next PR.

Usage

role = lettermint.team.create_role({
    "name": "Support",
    "description": "Handles customer questions",
    "permissions": ["support:manage"],
})

copy = lettermint.team.duplicate_role(role["id"], {"name": "Support (EU)"})
print(copy["description"])  # "Handles customer questions"

lettermint.team.delete_role(role["id"], {"replacement_role_id": "member-role-id"})

Checks

Run locally at the tip of this branch:

  • python -m ruff check src tests scripts: all checks passed
  • python -m ruff format --check src tests scripts: 28 files already formatted
  • python -m mypy: no issues in 35 source files
  • python scripts/unasync.py --check: up to date
  • python scripts/generate.py --check: the generated files match the pinned spec, and the headers check that CI runs passes
  • python -m pytest tests/ -q on Python 3.10, 3.11, 3.12, 3.13 and 3.14: 297 passed on each
  • python -m build, python -m twine check --strict dist/*: passed; the wheel smoke import passes

Not run locally

Nothing.

🤖 Generated with Claude Code

- New methods on team: retrieve_role(role_id), create_role(body),
  update_role(role_id, body), delete_role(role_id, query=None) and
  duplicate_role(role_id, body). They use the team token and send no
  Idempotency-Key header.
- delete_role() takes a DeleteTeamRoleQuery: pass replacement_role_id
  while the role is still assigned to members, invites or SCIM groups.
  Without it, no query parameter is sent.
- create_role() and update_role() return the TeamRoleData with its
  description; a 409 raises ConflictError with the error code and a 422
  raises ValidationError.
- Remove the role operations from the coverage test's pending list.
- Document the role methods in the README and test the requests, the
  token, the bodies with and without a description, the query with and
  without replacement_role_id, the role ID checks, the description value
  and null, and the 409 and 422 errors.

Co-Authored-By: Claude <noreply@anthropic.com>
@bjarn
bjarn requested a review from a team as a code owner October 20, 2026 20:47
@bjarn
bjarn added this pull request to stack #43 October 20, 2026 20:47
@bjarn
bjarn merged commit 9363a75 into main Oct 21, 2026
6 checks passed
@bjarn
bjarn deleted the feat/team-roles branch October 21, 2026 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants