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>
209 lines
5.9 KiB
Markdown
209 lines
5.9 KiB
Markdown
# 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:
|
|
|
|
```typescript
|
|
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 `userRole` prop
|
|
- 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
|
|
```typescript
|
|
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
|
|
```typescript
|
|
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, address
|
|
- `POST /api/me/beneficiaries/:id/avatar` - Upload avatar
|
|
- `DELETE /api/me/beneficiaries/:id` - Remove access
|
|
|
|
### For Guardians/Caretakers
|
|
- `PATCH /api/me/beneficiaries/:id/custom-name` - Update personal nickname
|
|
|
|
## User Experience
|
|
|
|
### Custodian Flow
|
|
1. Opens beneficiary detail screen
|
|
2. Clicks menu (three dots)
|
|
3. Sees all options including "Remove"
|
|
4. Clicks "Edit"
|
|
5. Modal shows: Avatar picker, Name field, Address field
|
|
6. Can update any field
|
|
7. Saves → Updates beneficiary table
|
|
|
|
### Guardian Flow
|
|
1. Opens beneficiary detail screen
|
|
2. Clicks menu (three dots)
|
|
3. Sees all options **except "Remove"**
|
|
4. Clicks "Edit"
|
|
5. Modal shows: Nickname field only
|
|
6. Original name shown for reference
|
|
7. Saves → Updates user_access.custom_name
|
|
|
|
### Caretaker Flow
|
|
1. Opens beneficiary detail screen
|
|
2. Clicks menu (three dots)
|
|
3. Sees **only** Dashboard, Edit, Sensors
|
|
4. Clicks "Edit"
|
|
5. Modal shows: Nickname field only
|
|
6. Original name shown for reference
|
|
7. Saves → Updates user_access.custom_name
|
|
|
|
## Database Schema
|
|
|
|
```sql
|
|
-- 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
|
|
|
|
1. **Client-side validation:**
|
|
- Menu items filtered by role
|
|
- Edit modal shows different fields by role
|
|
- Prevents accidental unauthorized actions
|
|
|
|
2. **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
|
|
|
|
3. **Default to minimum permissions:**
|
|
- If role is undefined, defaults to `caretaker`
|
|
- "Fail secure" approach
|
|
- Better to deny access than grant too much
|
|
|
|
## 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:
|
|
1. Role-based access to specific sensors/devices
|
|
2. Granular permissions (e.g., "view subscription" vs "manage subscription")
|
|
3. Time-limited access (temporary caretaker access)
|
|
4. Audit log of permission changes
|
|
5. Role change notifications
|
|
|
|
## Related Files
|
|
|
|
- `components/ui/BeneficiaryMenu.tsx` - Menu component with role filtering
|
|
- `app/(tabs)/beneficiaries/[id]/index.tsx` - Detail screen with role-based edit
|
|
- `services/api.ts` - API methods for role-based updates
|
|
- `types/index.ts` - TypeScript types for roles
|
|
- `backend/src/routes/beneficiaries.js` - Backend role validation
|
|
|
|
## Questions?
|
|
|
|
For questions or issues related to role-based permissions:
|
|
1. Check this documentation
|
|
2. Review test files for examples
|
|
3. Check API endpoint documentation
|
|
4. Contact backend team for server-side validation logic
|