Skip to content

feat(permissions): support the member role in the permission picker - #3177

Merged
HarshMN2345 merged 4 commits into
mainfrom
fix-member-role-permissions
Aug 21, 2026
Merged

feat(permissions): support the member role in the permission picker#3177
HarshMN2345 merged 4 commits into
mainfrom
fix-member-role-permissions

Conversation

@HarshMN2345

@HarshMN2345 HarshMN2345 commented Aug 20, 2026

Copy link
Copy Markdown
Member

Role.member([MEMBERSHIP_ID]) has been part of the permissions API since 1.0 and is documented, but the console has never offered it. This adds it, and fixes how existing member roles are displayed.

…vable

parsePermission only recognised user and team, so a member role fell
through to the invalid branch: it rendered as a raw truncated string in
the styling reserved for a deleted entity, and its hover card showed the
missing-entity avatar — presenting a perfectly valid grant as broken.

It also called onNotFound. Nothing passes that callback today, but
d36135f wired it to auto-remove stale roles before row.svelte moved to
runes turned the event into a prop and left the consumer behind. If that
wiring is restored, member roles would be silently deleted from any
resource a user merely opened.

A membership can only be read through its team or its user, and the role
string carries neither, so the ID stands in for a name. That is still an
improvement on the raw role: the badge now reads Member and the hover
card offers the membership ID to copy.
The member role has been in the API and the docs since 1.0, but neither
console ever offered it — the only way to set one was to know the syntax
and type it into the custom permission box.

It keys on a membership ID, which nothing in the console surfaces, so
the picker resolves it in two steps: find the user, then choose which of
their team memberships to grant. It has to run in that direction —
teams.listMemberships indexes only the membership ID and the user ID for
search, so picking a team first would leave the member step with a
search box that matches nothing. users.list indexes name, email and
phone, so the first step behaves like the existing user picker.
@appwrite

appwrite Bot commented Aug 20, 2026

Copy link
Copy Markdown

Console (appwrite/console)

Project ID: 688b7bf400350cbd60e9

Sites (1)
Site Status Logs Preview QR
 console-stage
688b7cf6003b1842c9dc
Ready Ready View Logs Preview URL QR Code

Tip

Teams feature lets you group users with membership management and role permissions

@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds membership-role selection and display support to the permission editor, including user and membership lookup, pagination, loading states, and retryable failures.

  • Adds a two-step user and team-membership picker that creates Role.member(...) entries.
  • Extends permission and role editors with the new picker.
  • Parses and displays existing member roles with membership-specific labels and details.
  • Updates custom-role guidance to document the member role format.

Confidence Score: 4/5

The PR is not yet safe to merge because a rejected membership request can update the wrong picker step after the operator navigates Back.

The success path prevents stale membership data from being applied, but the rejection path lacks the same selected-user guard and can surface a membership failure as a user-list failure.

Files Needing Attention: src/lib/components/permissions/member.svelte

Important Files Changed

Filename Overview
src/lib/components/permissions/member.svelte Adds the membership picker and request lifecycle handling, but stale membership rejections can still update the user-selection state after navigating Back.
src/lib/components/permissions/actions.svelte Adds the membership picker action and conditionally mounts the new modal.
src/lib/components/permissions/permissions.svelte Threads membership-picker visibility through the permission matrix.
src/lib/components/permissions/roles.svelte Threads membership-picker visibility through the role list.
src/lib/components/permissions/row.svelte Adds parsing, badges, and tooltip presentation for existing member roles.
src/lib/components/permissions/custom.svelte Documents the supported member-role syntax in the custom permission form.

Fix all with Greploop Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
### Issue 1
src/lib/components/permissions/member.svelte:116-118
**Stale membership errors cross views**

When an operator returns to the user list while a membership request is pending and that request rejects, the rejection writes the shared `loadError` without checking the selected user, causing a stale notification and potentially displaying the membership failure as “Could not load users.”

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (3): Last reviewed commit: "fix(permissions): tell a failed membersh..." | Re-trigger Greptile

Comment thread src/lib/components/permissions/member.svelte Outdated
Comment thread src/lib/components/permissions/member.svelte Outdated
import { createEventDispatcher } from 'svelte';
import Label from './label.svelte';
import Custom from './custom.svelte';
import Member from './member.svelte';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Membership picker bypasses barrel exports

The new picker integration imports component implementations through relative file paths rather than the repository's required directory barrel exports, coupling the feature to internal filenames and bypassing the curated export surface. The same pattern appears in the new member.svelte imports.

Context Used: AGENTS.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/components/permissions/actions.svelte
Line: 5

Comment:
**Membership picker bypasses barrel exports**

The new picker integration imports component implementations through relative file paths rather than the repository's required directory barrel exports, coupling the feature to internal filenames and bypassing the curated export surface. The same pattern appears in the new `member.svelte` imports.

**Context Used:** AGENTS.md ([source](https://github.com/appwrite/console/blob/main/AGENTS.md))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Codex

…sponses

Stepping back and choosing a second user, or typing another search term,
leaves the earlier request in flight. Whichever resolves last was writing
to the shared list, so one user's memberships could be listed under
another user's name — and a row selected there would have granted the
membership actually belonging to the first user.

Requests now carry a sequence number and only the newest may write, with
the membership step additionally confirming the selection has not moved
on beneath it.

A rejected request also skipped the assignment that cleared the spinner,
leaving the picker loading forever with nothing said. Both requests now
settle in a finally and surface the failure.
@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

You're right on all three points. The imports in actions.svelte follow a pre-existing intra-directory convention, the barrel intentionally omits those private components, and adding Member there would expand the curated export surface rather than honor it. My comment was misapplying the rule to a scope it doesn't govern.

I won't carry that forward as a rule.

Comment thread src/lib/components/permissions/member.svelte
… one

A rejected request left the list undefined, which reads identically to a
successful empty response, so the picker stated that the user belongs to
no teams — and offered nothing to click, leaving Back and re-selecting
the user as the only way to try again.

The failure is now held separately from the list and rendered as its own
state with a Retry, in both steps. In the user step it is checked ahead
of the search branch, so a search that fails reports the failure rather
than claiming the term matched nothing.
Comment on lines +116 to +118
if (requestId !== latestRequest) return;
loadError = error.message;
addNotification({ type: 'error', message: error.message });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Stale membership errors cross views

When an operator returns to the user list while a membership request is pending and that request rejects, the rejection writes the shared loadError without checking the selected user, causing a stale notification and potentially displaying the membership failure as “Could not load users.”

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/components/permissions/member.svelte
Line: 116-118

Comment:
**Stale membership errors cross views**

When an operator returns to the user list while a membership request is pending and that request rejects, the rejection writes the shared `loadError` without checking the selected user, causing a stale notification and potentially displaying the membership failure as “Could not load users.”

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

@HarshMN2345
HarshMN2345 merged commit 5c99615 into main Aug 21, 2026
4 checks passed
@HarshMN2345
HarshMN2345 deleted the fix-member-role-permissions branch August 21, 2026 04:08
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