Skip to content

Added the role management feature#118

Open
dhruvi-16-me wants to merge 3 commits intoAOSSIE-Org:mainfrom
dhruvi-16-me:feat/role-management
Open

Added the role management feature#118
dhruvi-16-me wants to merge 3 commits intoAOSSIE-Org:mainfrom
dhruvi-16-me:feat/role-management

Conversation

@dhruvi-16-me
Copy link
Contributor

@dhruvi-16-me dhruvi-16-me commented Jan 4, 2026

Closes #114

📝 Description

This pull request adds basic role management for team members.
Team admins can now promote members to admin or demote admins back to member from the team members screen.
This makes team management more practical after a team is created, without changing the existing team join flow.

🔧 Changes Made

  1. Added promote/demote actions for admins in the team members list
  2. Added a confirmation dialog before changing a member’s role
  3. Updated Supabase service to confirm role updates using database response
  4. Updated RLS policies so only admins can manage roles within their team
  5. Prevented admins from modifying their own role

📷 Screenshots or Visual Changes (if applicable)

WhatsApp.Video.2026-01-04.at.7.02.13.PM.mp4

🤝 Collaboration

Collaborated with: @username (optional)

✅ Checklist

  • I have read the contributing guidelines.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added necessary documentation (if applicable).
  • Any dependent changes have been merged and published in downstream modules.

Summary by CodeRabbit

  • New Features

    • Team admins can now change a member's role between admin and member with proper validation and user feedback.
  • Chores

    • Updated backend access controls and permission checks to enforce team-scoped role management and ensure role updates follow allowed values only.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 4, 2026

📝 Walkthrough

Walkthrough

Adds team role management: a new Dart service method to request role changes and new/updated database RLS policies and helper functions to enforce admin-only role changes within the same team.

Changes

Cohort / File(s) Summary
Dart service
lib/services/supabase_service.dart
Added changeTeamMemberRole({required String userId, required String newRole}): initialization/auth checks, verifies caller is admin in same team, validates newRole (admin/member), performs users table update, handles RLS/permission failures and logs errors.
Database RLS policies & helpers
sqls/02_user_auth_policies.sql
Dropped/recreated several user/team policies; added is_admin_in_same_team(target_team_id UUID) and get_current_user_role() helpers; tightened user update policy to prevent self-role changes; added admin policy allowing admins to change roles within their team; re-enabled RLS and adjusted related view/insert policies.

Sequence Diagram

sequenceDiagram
    actor Client
    participant "Dart Service" as Dart
    participant "Supabase Auth" as Auth
    participant Database
    participant "RLS Policies" as RLS

    Client->>Dart: changeTeamMemberRole(userId, newRole)
    
    rect rgba(220,240,255,0.5)
    Dart->>Dart: check initialization
    Dart->>Auth: verify current user authenticated
    Dart->>Dart: validate newRole ∈ {admin, member}
    end

    rect rgba(240,220,255,0.5)
    Dart->>Database: SELECT target user (verify same team)
    Database->>Dart: return user + team info
    Dart->>Database: UPDATE users SET role = newRole WHERE id = userId
    end

    rect rgba(255,235,220,0.5)
    Database->>RLS: evaluate update (calls helpers)
    RLS->>RLS: is_admin_in_same_team(...) and get_current_user_role()
    RLS-->>Database: allow/deny
    Database->>Dart: update result / error
    end

    alt success
        Dart->>Client: {success: true, message}
    else failure
        Dart->>Client: {success: false, error, details}
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • SharkyBytes

Poem

🐰 A nibble of code, a hop of cheer,
Admins can shuffle roles with care so near.
RLS stands watch, helpers tidy the way,
Teams stay in order—hip hop hooray! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main feature being implemented—role management for team members, which aligns with the primary objective of PR #118.
Linked Issues check ✅ Passed The PR implements core requirements from #114: changeTeamMemberRole method in Dart service, RLS policies enforcing admin-only role changes, validation for 'admin'/'member' roles, and safeguards against self-role modification.
Out of Scope Changes check ✅ Passed All changes directly support the role management feature specified in #114; no unrelated modifications detected in the Dart service or SQL policies.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
lib/services/supabase_service.dart (1)

557-561: Consider refreshing the team members cache after role update.

The _teamMembersCache is not invalidated after a successful role change. This may cause the UI to display stale role information until the next manual refresh.

🔎 Proposed fix
       debugPrint('Successfully updated role to $newRole for user $userId');
+      
+      // Refresh team members cache to reflect the role change
+      if (_currentTeamId != null) {
+        _teamMembersCache = [];
+        await loadTeamMembers(_currentTeamId!);
+      }
+
       return {
         'success': true,
         'message': 'Role updated successfully',
       };
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 235a88b and 0bb8352.

📒 Files selected for processing (2)
  • lib/services/supabase_service.dart
  • sqls/02_user_auth_policies.sql
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-06T10:06:27.181Z
Learnt from: SharkyBytes
Repo: AOSSIE-Org/Ell-ena PR: 11
File: sqls/03_task_schema.sql:57-78
Timestamp: 2025-07-06T10:06:27.181Z
Learning: SharkyBytes prefers to keep separate database RLS policies during the development phase in the Ell-ena project for clarity and debugging purposes, even when they might be combined for better security. They handle complex authorization logic on the application side during development, with plans to optimize database-level security later when focusing on production readiness.

Applied to files:

  • sqls/02_user_auth_policies.sql
🔇 Additional comments (4)
lib/services/supabase_service.dart (1)

487-497: LGTM on the overall structure and error handling.

The method follows the established patterns in this service: initialization check, authentication verification, validation, database operation with result verification, and structured error responses with stack trace logging.

Also applies to: 499-505, 543-555, 562-569

sqls/02_user_auth_policies.sql (3)

29-50: LGTM on helper functions.

Both is_admin_in_same_team and get_current_user_role are correctly implemented with SECURITY DEFINER to bypass RLS during policy evaluation and STABLE for query optimization. The null check on team_id in is_admin_in_same_team is good defensive coding.


85-93: LGTM on user self-update policy.

The WITH CHECK clause correctly prevents users from changing their own role by validating role = get_current_user_role().


1-19: LGTM on cleanup statements.

The drop statements are comprehensive, including legacy policy names, which prevents conflicts during migration.

@g-k-s-03
Copy link
Contributor

g-k-s-03 commented Feb 1, 2026

Hey @dhruvi-16-me, I was going through the CodeRabbit comments on your PR, and they actually pointed out a real edge case.

Right now, an admin can still modify their own role because:
- In the Dart service, there’s no check for currentUser.id != userId

  • And in the RLS policy, the admin policy also matches the admin’s own row
    So even though the intention is correct, technically, an admin could demote themselves.

Probably the simplest fix is:

  • Add a small guard in the service to block self-role changes
  • And add an exclusion in the SQL policy, like users.id <> auth.uid()
    Might also make it easier for @SharkyBytes to review, since it aligns directly with what CodeRabbit flagged.

Just sharing since it’s one of those edge-case things.

@dhruvi-16-me
Copy link
Contributor Author

@g-k-s-03 Thanks for pointing it out. I should have added that edge case earlier. I will work on it.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
sqls/02_user_auth_policies.sql (2)

64-66: ⚠️ Potential issue | 🟡 Minor

Policy name doesn't match its logic.

The policy is named "Only admins can update their team" but the USING clause checks created_by = auth.uid(), which restricts updates to the team creator rather than admins. If the team creator is demoted to member, they would still be able to update the team.

Consider either:

  1. Renaming to "Only team creators can update their team", or
  2. Changing the condition to use is_admin_in_same_team(id) if admin-based access is intended.

119-120: ⚠️ Potential issue | 🟠 Major

Granting ALL permissions to anon role is overly permissive.

The anon role represents unauthenticated users in Supabase. While RLS policies provide row-level protection, granting ALL (SELECT, INSERT, UPDATE, DELETE) to anonymous users violates the principle of least privilege and increases attack surface if RLS policies have bugs or are temporarily disabled.

Consider restricting anon permissions:

🛡️ Proposed fix - restrict anonymous permissions
 GRANT USAGE ON SCHEMA public TO anon, authenticated;
 GRANT SELECT ON user_teams TO anon, authenticated;
-GRANT ALL ON teams TO anon, authenticated;
-GRANT ALL ON users TO anon, authenticated;
+GRANT SELECT ON teams TO anon;
+GRANT ALL ON teams TO authenticated;
+GRANT SELECT ON users TO anon;
+GRANT ALL ON users TO authenticated;

If anonymous access is intentionally required for specific operations (e.g., signup flow), grant only the minimum necessary permissions explicitly.

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.

FEATURE REQUEST: Add role management for team members

2 participants