# 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 = { 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