This commit implements role-based permission testing and documentation for the beneficiary management system. The role-based UI was already correctly implemented in BeneficiaryMenu.tsx (lines 21-25). This commit adds: - Comprehensive test suite for BeneficiaryMenu role permissions - Test suite for role-based edit modal functionality - Detailed documentation in docs/ROLE_BASED_PERMISSIONS.md - Jest configuration for future testing - testID added to menu button for testing accessibility Role Permission Summary: - Custodian: Full access (all features including remove) - Guardian: Most features (cannot remove beneficiary) - Caretaker: Limited access (dashboard, edit nickname, sensors only) Edit Functionality: - Custodians can edit full profile (name, address, avatar) - Guardians/Caretakers can only edit personal nickname (customName) - Backend validates all permissions server-side for security Tests verify: ✅ Menu items filtered correctly by role ✅ Custodian has full edit capabilities ✅ Guardian/Caretaker limited to nickname editing only ✅ Default role is caretaker (security-first approach) ✅ Navigation routes work correctly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
5.9 KiB
5.9 KiB
Role-Based Permissions System
This document describes the role-based permissions system for beneficiary management in WellNuo.
User Roles
There are three user roles with different permission levels:
1. Custodian (Owner)
- Full access to all beneficiary features
- Can view and edit full beneficiary profile (name, address, avatar)
- Can manage access (invite/remove guardians and caretakers)
- Can manage subscription
- Can manage sensors/equipment
- Can remove beneficiary from their account
2. Guardian
- Most features available
- Can view beneficiary dashboard
- Can edit nickname only (personal display name)
- Can manage access (invite/remove other guardians and caretakers)
- Can view and manage subscription
- Can manage sensors/equipment
- Cannot remove beneficiary (only custodian can)
3. Caretaker
- Limited access for care providers
- Can view beneficiary dashboard
- Can edit nickname only (personal display name)
- Can view sensors/equipment
- Cannot manage access (cannot invite others)
- Cannot manage subscription
- Cannot remove beneficiary
Implementation
Menu Permissions (BeneficiaryMenu Component)
Location: components/ui/BeneficiaryMenu.tsx
The menu system automatically filters available actions based on user role:
const ROLE_PERMISSIONS: Record<UserRole, MenuItemId[]> = {
custodian: ['dashboard', 'edit', 'access', 'subscription', 'sensors', 'remove'],
guardian: ['dashboard', 'edit', 'access', 'subscription', 'sensors'],
caretaker: ['dashboard', 'edit', 'sensors'],
};
Key features:
- Security-first: Defaults to
caretaker(minimum permissions) if role not specified - Menu items are filtered client-side based on
userRoleprop - Backend validates permissions on API calls (double security)
Edit Modal (Beneficiary Detail Screen)
Location: app/(tabs)/beneficiaries/[id]/index.tsx
The edit functionality adapts based on user role:
Custodian Edit Form
if (isCustodian) {
// Show full profile editor
// Fields: avatar, name, address
// Calls: api.updateWellNuoBeneficiary()
}
Custodian can edit:
- Avatar (photo upload)
- Full name
- Address
Guardian/Caretaker Edit Form
else {
// Show nickname editor only
// Fields: customName
// Calls: api.updateBeneficiaryCustomName()
}
Guardian/Caretaker can edit:
- Custom nickname only (e.g., "Mom", "Dad", "Grandpa")
- Original name shown as reference (read-only)
- Nickname is personal to the user (not shared with others)
API Endpoints
For Custodians
PATCH /api/me/beneficiaries/:id- Update name, addressPOST /api/me/beneficiaries/:id/avatar- Upload avatarDELETE /api/me/beneficiaries/:id- Remove access
For Guardians/Caretakers
PATCH /api/me/beneficiaries/:id/custom-name- Update personal nickname
User Experience
Custodian Flow
- Opens beneficiary detail screen
- Clicks menu (three dots)
- Sees all options including "Remove"
- Clicks "Edit"
- Modal shows: Avatar picker, Name field, Address field
- Can update any field
- Saves → Updates beneficiary table
Guardian Flow
- Opens beneficiary detail screen
- Clicks menu (three dots)
- Sees all options except "Remove"
- Clicks "Edit"
- Modal shows: Nickname field only
- Original name shown for reference
- Saves → Updates user_access.custom_name
Caretaker Flow
- Opens beneficiary detail screen
- Clicks menu (three dots)
- Sees only Dashboard, Edit, Sensors
- Clicks "Edit"
- Modal shows: Nickname field only
- Original name shown for reference
- Saves → Updates user_access.custom_name
Database Schema
-- beneficiaries table (custodian edits this)
beneficiaries {
id: integer
name: varchar (official name)
address: varchar
avatar: varchar (URL)
...
}
-- user_access table (guardians/caretakers edit custom_name)
user_access {
id: integer
user_id: integer (who has access)
beneficiary_id: integer (which beneficiary)
role: enum ('custodian', 'guardian', 'caretaker')
custom_name: varchar (personal nickname)
...
}
Security Considerations
-
Client-side validation:
- Menu items filtered by role
- Edit modal shows different fields by role
- Prevents accidental unauthorized actions
-
Server-side validation:
- API endpoints check user's role before allowing action
- Cannot bypass client checks with direct API calls
- Returns 403 Forbidden if role insufficient
-
Default to minimum permissions:
- If role is undefined, defaults to
caretaker - "Fail secure" approach
- Better to deny access than grant too much
- If role is undefined, defaults to
Testing
Test files created:
__tests__/components/BeneficiaryMenu.test.tsx- Menu permission tests__tests__/screens/BeneficiaryDetailScreen.test.tsx- Edit modal tests
Test coverage:
- ✅ Custodian sees all menu items
- ✅ Guardian sees all except Remove
- ✅ Caretaker sees limited menu items
- ✅ Custodian can edit full profile
- ✅ Guardian can edit nickname only
- ✅ Caretaker can edit nickname only
- ✅ Default role is caretaker (security)
- ✅ Navigation routes work correctly
Future Enhancements
Potential improvements:
- Role-based access to specific sensors/devices
- Granular permissions (e.g., "view subscription" vs "manage subscription")
- Time-limited access (temporary caretaker access)
- Audit log of permission changes
- Role change notifications
Related Files
components/ui/BeneficiaryMenu.tsx- Menu component with role filteringapp/(tabs)/beneficiaries/[id]/index.tsx- Detail screen with role-based editservices/api.ts- API methods for role-based updatestypes/index.ts- TypeScript types for rolesbackend/src/routes/beneficiaries.js- Backend role validation
Questions?
For questions or issues related to role-based permissions:
- Check this documentation
- Review test files for examples
- Check API endpoint documentation
- Contact backend team for server-side validation logic