Spaces:
Sleeping
Sleeping
feat: app management roles for who can view what app
Browse files
docs/api/user-profile/APP_ACCESS_UPDATE_SUMMARY.md
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# App Access Model Update - Summary
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
Updated the app management system to reflect real-world business scenarios where users wear multiple hats and need broad VIEW access with controlled ACTION permissions.
|
| 6 |
+
|
| 7 |
+
**Date:** November 18, 2025
|
| 8 |
+
**Updated Files:**
|
| 9 |
+
- `src/app/config/apps.py`
|
| 10 |
+
- `docs/api/user-profile/APP_MANAGEMENT_SYSTEM.md`
|
| 11 |
+
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
## Philosophy Change
|
| 15 |
+
|
| 16 |
+
### Before: Restrictive Access
|
| 17 |
+
- Roles had limited app access
|
| 18 |
+
- Field agents couldn't see payroll
|
| 19 |
+
- Dispatchers had narrow view
|
| 20 |
+
- Sales managers isolated from operations
|
| 21 |
+
|
| 22 |
+
### After: Broad Views, Restricted Actions
|
| 23 |
+
- **Most roles see most apps** (VIEW access)
|
| 24 |
+
- **Actions controlled via RBAC** (create/edit/delete permissions)
|
| 25 |
+
- **Real-world flexibility** (admins can wear multiple hats)
|
| 26 |
+
- **Casual workers track earnings** (field/sales agents see payroll)
|
| 27 |
+
|
| 28 |
+
---
|
| 29 |
+
|
| 30 |
+
## New Apps Added (4)
|
| 31 |
+
|
| 32 |
+
1. **Incidents** - Incident tracking and resolution
|
| 33 |
+
- Category: Operations
|
| 34 |
+
- Icon: alert-triangle
|
| 35 |
+
- Route: /incidents
|
| 36 |
+
|
| 37 |
+
2. **Tasks** - Task management and assignment
|
| 38 |
+
- Category: Operations
|
| 39 |
+
- Icon: check-square
|
| 40 |
+
- Route: /tasks
|
| 41 |
+
|
| 42 |
+
3. **Subscriptions** - Recurring revenue management
|
| 43 |
+
- Category: Finance
|
| 44 |
+
- Icon: refresh-cw
|
| 45 |
+
- Route: /subscriptions
|
| 46 |
+
- Requires: view_subscriptions permission
|
| 47 |
+
|
| 48 |
+
4. **Inventory** - Asset management
|
| 49 |
+
- Category: Operations
|
| 50 |
+
- Icon: package
|
| 51 |
+
- Route: /inventory
|
| 52 |
+
- Requires: view_inventory permission
|
| 53 |
+
|
| 54 |
+
**Total Apps:** 26 (was 22)
|
| 55 |
+
|
| 56 |
+
---
|
| 57 |
+
|
| 58 |
+
## Role Access Changes
|
| 59 |
+
|
| 60 |
+
### Platform Admin
|
| 61 |
+
- **Before:** 8 apps
|
| 62 |
+
- **After:** 26 apps (ALL)
|
| 63 |
+
- **Reason:** System administrators need full visibility
|
| 64 |
+
|
| 65 |
+
### Client Admin
|
| 66 |
+
- **Before:** 10 apps
|
| 67 |
+
- **After:** 23 apps
|
| 68 |
+
- **Added:** Organizations, incidents, tasks, maps, timesheets, payroll, expenses, documents, inventory, subscriptions, billing, notifications
|
| 69 |
+
- **Reason:** Can work as PM/dispatcher, needs full business visibility
|
| 70 |
+
|
| 71 |
+
### Contractor Admin
|
| 72 |
+
- **Before:** 9 apps
|
| 73 |
+
- **After:** 23 apps
|
| 74 |
+
- **Added:** Organizations, incidents, tasks, sales_orders, customers, maps, expenses, documents, inventory, subscriptions, billing, notifications, contractors
|
| 75 |
+
- **Reason:** Can work as PM/dispatcher, needs operational visibility
|
| 76 |
+
|
| 77 |
+
### Sales Manager
|
| 78 |
+
- **Before:** 8 apps
|
| 79 |
+
- **After:** 24 apps
|
| 80 |
+
- **Added:** Projects, tickets, incidents, tasks, timesheets, payroll, expenses, contractors, documents, inventory, subscriptions, billing, notifications
|
| 81 |
+
- **Reason:** Needs finance & operations visibility for fulfillment pipeline
|
| 82 |
+
|
| 83 |
+
### Project Manager
|
| 84 |
+
- **Before:** 8 apps
|
| 85 |
+
- **After:** 25 apps
|
| 86 |
+
- **Added:** Organizations, incidents, tasks, sales_orders, customers, contractors, timesheets, payroll, expenses, documents, inventory, subscriptions, billing, notifications
|
| 87 |
+
- **Reason:** Needs full visibility for project coordination
|
| 88 |
+
|
| 89 |
+
### Dispatcher
|
| 90 |
+
- **Before:** 8 apps
|
| 91 |
+
- **After:** 20 apps
|
| 92 |
+
- **Added:** Incidents, tasks, sales_orders, customers, contractors, timesheets, expenses, documents, inventory, subscriptions
|
| 93 |
+
- **Reason:** Sees what PM sees, different action permissions
|
| 94 |
+
|
| 95 |
+
### Field Agent (Casual Worker)
|
| 96 |
+
- **Before:** 7 apps (no payroll)
|
| 97 |
+
- **After:** 14 apps
|
| 98 |
+
- **Added:** Dashboard, incidents, tasks, **payroll**, customers, notifications
|
| 99 |
+
- **Reason:** Track daily earnings from errands, see customer info for field visits
|
| 100 |
+
|
| 101 |
+
### Sales Agent (Casual Worker)
|
| 102 |
+
- **Before:** 7 apps (no payroll)
|
| 103 |
+
- **After:** 15 apps
|
| 104 |
+
- **Added:** Tickets, tasks, **payroll**, expenses, documents, notifications
|
| 105 |
+
- **Reason:** Track sales commissions, follow up on customer issues
|
| 106 |
+
|
| 107 |
+
---
|
| 108 |
+
|
| 109 |
+
## Why Casual Workers Need Payroll
|
| 110 |
+
|
| 111 |
+
### Problem
|
| 112 |
+
Field agents and sales agents are typically casual/gig workers who:
|
| 113 |
+
- Get paid per completed task (field agent: "How much did I earn today?")
|
| 114 |
+
- Earn commission on sales (sales agent: "What's my commission this week?")
|
| 115 |
+
- Want transparency on their compensation
|
| 116 |
+
- Need to verify payments
|
| 117 |
+
|
| 118 |
+
### Solution
|
| 119 |
+
Give VIEW-only access to payroll app with:
|
| 120 |
+
- **Row-level security:** Workers only see their own payroll records
|
| 121 |
+
- **No action permissions:** Can't modify payroll data
|
| 122 |
+
- **Real-time visibility:** Track daily/weekly earnings
|
| 123 |
+
- **Transparent compensation:** Build trust with workers
|
| 124 |
+
|
| 125 |
+
### Implementation
|
| 126 |
+
```python
|
| 127 |
+
# Backend query with row-level filtering
|
| 128 |
+
if user.role in ['field_agent', 'sales_agent']:
|
| 129 |
+
payroll = Payroll.query.filter(Payroll.user_id == user.id)
|
| 130 |
+
else:
|
| 131 |
+
payroll = Payroll.query # Admins see all
|
| 132 |
+
```
|
| 133 |
+
|
| 134 |
+
---
|
| 135 |
+
|
| 136 |
+
## Multi-Role Reality
|
| 137 |
+
|
| 138 |
+
### Use Case: Small Business Client Admin
|
| 139 |
+
|
| 140 |
+
**Scenario:** John is a client admin at a small company. He also:
|
| 141 |
+
- Coordinates projects (PM role)
|
| 142 |
+
- Dispatches field agents (dispatcher role)
|
| 143 |
+
- Approves timesheets (HR role)
|
| 144 |
+
- Reviews sales reports (sales manager role)
|
| 145 |
+
|
| 146 |
+
**Solution:**
|
| 147 |
+
- John sees ALL 23 apps (broad VIEW access)
|
| 148 |
+
- Different permissions for different actions:
|
| 149 |
+
- ✅ Can create projects (has `can_create_project`)
|
| 150 |
+
- ✅ Can dispatch agents (has `can_assign_tickets`)
|
| 151 |
+
- ❌ Cannot approve payroll (lacks `can_approve_payroll`)
|
| 152 |
+
- ✅ Can view sales reports (has `can_view_sales`)
|
| 153 |
+
|
| 154 |
+
**UI Behavior:**
|
| 155 |
+
- Navigation shows all accessible apps
|
| 156 |
+
- Action buttons appear/disappear based on permissions
|
| 157 |
+
- Tooltips explain why actions are disabled
|
| 158 |
+
|
| 159 |
+
---
|
| 160 |
+
|
| 161 |
+
## Action Permissions vs View Access
|
| 162 |
+
|
| 163 |
+
### View Access (App Level)
|
| 164 |
+
- Controlled by `ROLE_APP_ACCESS` in `apps.py`
|
| 165 |
+
- Determines which apps appear in navigation
|
| 166 |
+
- Broad by default for most roles
|
| 167 |
+
|
| 168 |
+
### Action Permissions (Feature Level)
|
| 169 |
+
- Controlled by RBAC system (database `permissions` table)
|
| 170 |
+
- Fine-grained (can_create_ticket, can_approve_payroll, etc.)
|
| 171 |
+
- Checked on every mutation/action
|
| 172 |
+
- Independent of app access
|
| 173 |
+
|
| 174 |
+
### Example Matrix
|
| 175 |
+
|
| 176 |
+
| Role | Payroll App Access | View Own Payroll | View All Payroll | Approve Payroll | Process Payroll |
|
| 177 |
+
|------|-------------------|------------------|------------------|-----------------|-----------------|
|
| 178 |
+
| Field Agent | ✅ Yes | ✅ Yes | ❌ No | ❌ No | ❌ No |
|
| 179 |
+
| Sales Agent | ✅ Yes | ✅ Yes | ❌ No | ❌ No | ❌ No |
|
| 180 |
+
| Dispatcher | ✅ Yes | ✅ Yes | ✅ Yes* | ❌ No | ❌ No |
|
| 181 |
+
| PM | ✅ Yes | ✅ Yes | ✅ Yes* | ❌ No | ❌ No |
|
| 182 |
+
| Contractor Admin | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
|
| 183 |
+
| Client Admin | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
|
| 184 |
+
|
| 185 |
+
*Limited to their team/organization
|
| 186 |
+
|
| 187 |
+
---
|
| 188 |
+
|
| 189 |
+
## Default Favorites Update
|
| 190 |
+
|
| 191 |
+
### Changed
|
| 192 |
+
- **Contractor Admin:** Added "payroll" to defaults (was team)
|
| 193 |
+
- **Dispatcher:** Added "tasks" to defaults (was team)
|
| 194 |
+
- **Field Agent:** Changed to "tickets, maps, timesheets, payroll"
|
| 195 |
+
- **Sales Agent:** Changed to "sales_orders, customers, maps, payroll"
|
| 196 |
+
|
| 197 |
+
### Why
|
| 198 |
+
- Reflect most-used apps for each role
|
| 199 |
+
- Casual workers prioritize earnings tracking
|
| 200 |
+
- Dispatchers focus on task assignment
|
| 201 |
+
|
| 202 |
+
---
|
| 203 |
+
|
| 204 |
+
## Frontend Impact
|
| 205 |
+
|
| 206 |
+
### Navigation Bar
|
| 207 |
+
```javascript
|
| 208 |
+
// Before: Hardcoded app list
|
| 209 |
+
const navItems = ['dashboard', 'tickets', 'projects'];
|
| 210 |
+
|
| 211 |
+
// After: Dynamic from API
|
| 212 |
+
const { apps } = useFetchApps();
|
| 213 |
+
const accessibleApps = apps.filter(app => app.has_access);
|
| 214 |
+
```
|
| 215 |
+
|
| 216 |
+
### App Launcher
|
| 217 |
+
```javascript
|
| 218 |
+
// Before: Role-based switch statement
|
| 219 |
+
switch(userRole) {
|
| 220 |
+
case 'field_agent': return ['tickets', 'maps'];
|
| 221 |
+
// ...
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
// After: API-driven with categories
|
| 225 |
+
const { apps_by_category } = useFetchApps();
|
| 226 |
+
{Object.entries(apps_by_category).map(([category, apps]) => (
|
| 227 |
+
<CategorySection>
|
| 228 |
+
{apps.filter(app => app.has_access).map(renderApp)}
|
| 229 |
+
</CategorySection>
|
| 230 |
+
))}
|
| 231 |
+
```
|
| 232 |
+
|
| 233 |
+
### Action Buttons
|
| 234 |
+
```javascript
|
| 235 |
+
// Separate permission checks for actions
|
| 236 |
+
{hasPermission('can_create_ticket') && (
|
| 237 |
+
<Button onClick={createTicket}>Create Ticket</Button>
|
| 238 |
+
)}
|
| 239 |
+
|
| 240 |
+
{hasPermission('can_approve_payroll') && (
|
| 241 |
+
<Button onClick={approvePayroll}>Approve</Button>
|
| 242 |
+
)}
|
| 243 |
+
```
|
| 244 |
+
|
| 245 |
+
---
|
| 246 |
+
|
| 247 |
+
## Backend Implementation
|
| 248 |
+
|
| 249 |
+
### Row-Level Security Example
|
| 250 |
+
```python
|
| 251 |
+
# Payroll endpoint
|
| 252 |
+
@router.get("/payroll")
|
| 253 |
+
def get_payroll(user: User = Depends(get_current_user), db: Session = Depends(get_db)):
|
| 254 |
+
query = db.query(Payroll)
|
| 255 |
+
|
| 256 |
+
# Apply row-level filtering
|
| 257 |
+
if user.role in ['field_agent', 'sales_agent']:
|
| 258 |
+
# Workers only see their own records
|
| 259 |
+
query = query.filter(Payroll.user_id == user.id)
|
| 260 |
+
elif user.role == 'dispatcher':
|
| 261 |
+
# Dispatchers see their team
|
| 262 |
+
query = query.filter(Payroll.organization_id == user.organization_id)
|
| 263 |
+
# Admins see all (no additional filter)
|
| 264 |
+
|
| 265 |
+
return query.all()
|
| 266 |
+
```
|
| 267 |
+
|
| 268 |
+
### Permission Decorator
|
| 269 |
+
```python
|
| 270 |
+
def require_permission(permission: str):
|
| 271 |
+
def decorator(func):
|
| 272 |
+
async def wrapper(*args, user: User = Depends(get_current_user), **kwargs):
|
| 273 |
+
if not user.has_permission(permission):
|
| 274 |
+
raise HTTPException(403, f"Missing permission: {permission}")
|
| 275 |
+
return await func(*args, user=user, **kwargs)
|
| 276 |
+
return wrapper
|
| 277 |
+
return decorator
|
| 278 |
+
|
| 279 |
+
@router.post("/payroll/approve")
|
| 280 |
+
@require_permission('can_approve_payroll')
|
| 281 |
+
def approve_payroll(payroll_id: int, user: User):
|
| 282 |
+
# Only executes if user has permission
|
| 283 |
+
pass
|
| 284 |
+
```
|
| 285 |
+
|
| 286 |
+
---
|
| 287 |
+
|
| 288 |
+
## Testing Checklist
|
| 289 |
+
|
| 290 |
+
### Backend Tests
|
| 291 |
+
- [ ] All 26 apps defined in APPS dictionary
|
| 292 |
+
- [ ] All roles have valid app access lists
|
| 293 |
+
- [ ] Helper functions work with new apps
|
| 294 |
+
- [ ] Default favorites include valid app codes
|
| 295 |
+
- [ ] Row-level security filters work correctly
|
| 296 |
+
|
| 297 |
+
### Frontend Tests
|
| 298 |
+
- [ ] Navigation shows correct apps per role
|
| 299 |
+
- [ ] App launcher displays all accessible apps
|
| 300 |
+
- [ ] Categories render correctly
|
| 301 |
+
- [ ] Action buttons appear/disappear based on permissions
|
| 302 |
+
- [ ] Settings page allows favoriting new apps
|
| 303 |
+
- [ ] Max 6 favorites enforced
|
| 304 |
+
- [ ] Invalid apps rejected with clear error
|
| 305 |
+
|
| 306 |
+
### Integration Tests
|
| 307 |
+
- [ ] Field agent sees only their payroll records
|
| 308 |
+
- [ ] Dispatcher sees incidents, tasks, expenses
|
| 309 |
+
- [ ] PM sees all apps except platform admin apps
|
| 310 |
+
- [ ] Sales manager sees finance and inventory
|
| 311 |
+
- [ ] Client admin can work as PM
|
| 312 |
+
- [ ] Payroll access doesn't grant approval permissions
|
| 313 |
+
|
| 314 |
+
---
|
| 315 |
+
|
| 316 |
+
## Migration Steps
|
| 317 |
+
|
| 318 |
+
### Phase 1: Backend (Done ✅)
|
| 319 |
+
1. Add 4 new apps to APPS dictionary
|
| 320 |
+
2. Update ROLE_APP_ACCESS for all 8 roles
|
| 321 |
+
3. Update DEFAULT_FAVORITE_APPS
|
| 322 |
+
4. Add philosophy comment
|
| 323 |
+
|
| 324 |
+
### Phase 2: Frontend (Next)
|
| 325 |
+
1. Update API calls to fetch new apps
|
| 326 |
+
2. Test navigation with expanded app lists
|
| 327 |
+
3. Verify app launcher categories
|
| 328 |
+
4. Test favorites with new apps
|
| 329 |
+
5. Implement permission-based action buttons
|
| 330 |
+
|
| 331 |
+
### Phase 3: Permissions Setup
|
| 332 |
+
1. Define action permissions in database
|
| 333 |
+
2. Assign permissions to roles
|
| 334 |
+
3. Implement row-level security queries
|
| 335 |
+
4. Add permission decorators to endpoints
|
| 336 |
+
|
| 337 |
+
### Phase 4: Testing
|
| 338 |
+
1. User acceptance testing with each role
|
| 339 |
+
2. Verify casual workers can see earnings
|
| 340 |
+
3. Test multi-role scenarios
|
| 341 |
+
4. Performance testing with 26 apps
|
| 342 |
+
|
| 343 |
+
---
|
| 344 |
+
|
| 345 |
+
## Breaking Changes
|
| 346 |
+
|
| 347 |
+
### None! 🎉
|
| 348 |
+
|
| 349 |
+
This is a **backward-compatible** update:
|
| 350 |
+
- Existing apps still work
|
| 351 |
+
- Old favorites still valid
|
| 352 |
+
- No API contract changes
|
| 353 |
+
- Only additive changes (more apps, more access)
|
| 354 |
+
|
| 355 |
+
Frontend will automatically:
|
| 356 |
+
- Fetch new apps from API
|
| 357 |
+
- Display expanded navigation
|
| 358 |
+
- Allow favoriting new apps
|
| 359 |
+
|
| 360 |
+
---
|
| 361 |
+
|
| 362 |
+
## Future Enhancements
|
| 363 |
+
|
| 364 |
+
1. **Permission Management UI** - Admin interface to assign permissions
|
| 365 |
+
2. **Role Templates** - Pre-configured permission sets per role
|
| 366 |
+
3. **Custom Roles** - Organizations define their own roles
|
| 367 |
+
4. **App Analytics** - Track which apps users access most
|
| 368 |
+
5. **Dynamic Permissions** - Time-based or condition-based permissions
|
| 369 |
+
6. **App Bundles** - Group apps into bundles (Operations Bundle, Finance Bundle)
|
| 370 |
+
|
| 371 |
+
---
|
| 372 |
+
|
| 373 |
+
**Updated By:** AI Assistant
|
| 374 |
+
**Reviewed By:** Pending
|
| 375 |
+
**Status:** Ready for Frontend Integration
|
docs/api/user-profile/APP_MANAGEMENT_SYSTEM.md
CHANGED
|
@@ -94,18 +94,21 @@ class AppDefinition:
|
|
| 94 |
|
| 95 |
Apps are organized into 6 categories:
|
| 96 |
|
| 97 |
-
| Category | Purpose | Example Apps |
|
| 98 |
-
|----------|---------|--------------|
|
| 99 |
-
| **Core** | Essential platform features | Dashboard, Organizations, Users, Activity |
|
| 100 |
-
| **Operations** | Field operations & ticketing | Tickets, Projects, Maps, Contractors |
|
| 101 |
-
| **Sales** | Sales & customer management | Sales Orders, Customers
|
| 102 |
-
| **Team** | Team management & scheduling | Team, Timesheets |
|
| 103 |
-
| **Finance** | Financial management | Payroll, Billing, Expenses |
|
| 104 |
-
| **Settings** | Configuration & support | Settings, Profile, Help
|
| 105 |
|
| 106 |
-
|
|
|
|
|
|
|
| 107 |
|
| 108 |
```python
|
|
|
|
| 109 |
"dashboard": AppDefinition(
|
| 110 |
code="dashboard",
|
| 111 |
name="Dashboard",
|
|
@@ -114,8 +117,45 @@ Apps are organized into 6 categories:
|
|
| 114 |
route="/dashboard",
|
| 115 |
category=AppCategory.CORE
|
| 116 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
```
|
| 118 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
---
|
| 120 |
|
| 121 |
## API Endpoints
|
|
@@ -502,18 +542,30 @@ Create the frontend page and add route:
|
|
| 502 |
|
| 503 |
## Role Configuration
|
| 504 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 505 |
### Current Roles and App Access
|
| 506 |
|
| 507 |
-
| Role |
|
| 508 |
-
|------|----------------|-------------------|
|
| 509 |
-
| **Platform Admin** |
|
| 510 |
-
| **Client Admin** |
|
| 511 |
-
| **Contractor Admin** |
|
| 512 |
-
| **Sales Manager** |
|
| 513 |
-
| **Project Manager** |
|
| 514 |
-
| **Dispatcher** |
|
| 515 |
-
| **Field Agent** |
|
| 516 |
-
| **Sales Agent** |
|
|
|
|
|
|
|
| 517 |
|
| 518 |
### Modifying Role Access
|
| 519 |
|
|
@@ -532,6 +584,66 @@ ROLE_APP_ACCESS = {
|
|
| 532 |
|
| 533 |
---
|
| 534 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 535 |
## Best Practices
|
| 536 |
|
| 537 |
### Backend
|
|
|
|
| 94 |
|
| 95 |
Apps are organized into 6 categories:
|
| 96 |
|
| 97 |
+
| Category | Purpose | Example Apps | Total |
|
| 98 |
+
|----------|---------|--------------|-------|
|
| 99 |
+
| **Core** | Essential platform features | Dashboard, Organizations, Users, Activity, Notifications | 5 apps |
|
| 100 |
+
| **Operations** | Field operations & ticketing | Tickets, Projects, Maps, Contractors, Incidents, Tasks, Documents, Inventory, Reports | 9 apps |
|
| 101 |
+
| **Sales** | Sales & customer management | Sales Orders, Customers | 2 apps |
|
| 102 |
+
| **Team** | Team management & scheduling | Team, Timesheets | 2 apps |
|
| 103 |
+
| **Finance** | Financial management | Payroll, Billing, Expenses, Subscriptions | 4 apps |
|
| 104 |
+
| **Settings** | Configuration & support | Settings, Profile, Help | 3 apps |
|
| 105 |
|
| 106 |
+
**Total Apps in System:** 26 apps
|
| 107 |
+
|
| 108 |
+
### Example App Definitions
|
| 109 |
|
| 110 |
```python
|
| 111 |
+
# Core App
|
| 112 |
"dashboard": AppDefinition(
|
| 113 |
code="dashboard",
|
| 114 |
name="Dashboard",
|
|
|
|
| 117 |
route="/dashboard",
|
| 118 |
category=AppCategory.CORE
|
| 119 |
)
|
| 120 |
+
|
| 121 |
+
# Operations App with Permission
|
| 122 |
+
"incidents": AppDefinition(
|
| 123 |
+
code="incidents",
|
| 124 |
+
name="Incidents",
|
| 125 |
+
description="Incident tracking and resolution",
|
| 126 |
+
icon="alert-triangle",
|
| 127 |
+
route="/incidents",
|
| 128 |
+
category=AppCategory.OPERATIONS
|
| 129 |
+
)
|
| 130 |
+
|
| 131 |
+
# Finance App with Permission
|
| 132 |
+
"subscriptions": AppDefinition(
|
| 133 |
+
code="subscriptions",
|
| 134 |
+
name="Subscriptions",
|
| 135 |
+
description="Subscription and recurring revenue management",
|
| 136 |
+
icon="refresh-cw",
|
| 137 |
+
route="/subscriptions",
|
| 138 |
+
category=AppCategory.FINANCE,
|
| 139 |
+
requires_permission="view_subscriptions" # Action permissions controlled separately
|
| 140 |
+
)
|
| 141 |
```
|
| 142 |
|
| 143 |
+
### New Apps Added
|
| 144 |
+
|
| 145 |
+
**Operations:**
|
| 146 |
+
- **Incidents** - Incident tracking and resolution for critical issues
|
| 147 |
+
- **Tasks** - Task management and assignment for daily operations
|
| 148 |
+
- **Inventory** - Inventory and asset management
|
| 149 |
+
|
| 150 |
+
**Finance:**
|
| 151 |
+
- **Subscriptions** - Recurring revenue and subscription management
|
| 152 |
+
|
| 153 |
+
**Why These Apps?**
|
| 154 |
+
- **Dispatchers** need to see incidents, tasks, expenses, sales orders, and subscriptions
|
| 155 |
+
- **Field Agents & Sales Agents** (casual workers) need to track their daily earnings via payroll
|
| 156 |
+
- **PMs** need full visibility into all business operations
|
| 157 |
+
- **Sales Managers** need finance and inventory visibility to understand fulfillment
|
| 158 |
+
|
| 159 |
---
|
| 160 |
|
| 161 |
## API Endpoints
|
|
|
|
| 542 |
|
| 543 |
## Role Configuration
|
| 544 |
|
| 545 |
+
### Philosophy: Views Are Broad, Actions Are Restricted
|
| 546 |
+
|
| 547 |
+
**Key Principle:** Most roles can VIEW most apps to understand the full business context. Action permissions (create, edit, delete) are controlled separately via RBAC (Role-Based Access Control).
|
| 548 |
+
|
| 549 |
+
**Real-World Reality:**
|
| 550 |
+
- A **client_admin** can also do PM or dispatcher work
|
| 551 |
+
- A **PM** needs visibility into sales, finance, and operations for coordination
|
| 552 |
+
- A **dispatcher** sees what PM sees but has different action permissions
|
| 553 |
+
- **Field agents & sales agents** (casual workers) need to track their daily earnings via payroll
|
| 554 |
+
|
| 555 |
### Current Roles and App Access
|
| 556 |
|
| 557 |
+
| Role | Total Apps | Key Focus | Default Favorites |
|
| 558 |
+
|------|-----------|-----------|-------------------|
|
| 559 |
+
| **Platform Admin** | 26 apps (ALL) | System management | Dashboard, Organizations, Users, Activity |
|
| 560 |
+
| **Client Admin** | 23 apps (ALMOST ALL) | Can work as PM/dispatcher too | Dashboard, Projects, Tickets, Team |
|
| 561 |
+
| **Contractor Admin** | 23 apps (ALMOST ALL) | Can work as PM/dispatcher too | Dashboard, Projects, Tickets, Payroll |
|
| 562 |
+
| **Sales Manager** | 24 apps (ALMOST ALL) | Sales + operations visibility | Dashboard, Sales Orders, Customers, Reports |
|
| 563 |
+
| **Project Manager** | 25 apps (ALMOST ALL) | Full business visibility | Dashboard, Projects, Tickets, Team |
|
| 564 |
+
| **Dispatcher** | 20 apps | Same views as PM, different actions | Dashboard, Tickets, Maps, Tasks |
|
| 565 |
+
| **Field Agent** | 14 apps | Daily work + earnings tracking | Tickets, Maps, Timesheets, Payroll |
|
| 566 |
+
| **Sales Agent** | 15 apps | Sales + commission tracking | Sales Orders, Customers, Maps, Payroll |
|
| 567 |
+
|
| 568 |
+
**Note:** Numbers represent apps with VIEW access. Action permissions (create/edit/delete) are controlled via separate RBAC permissions.
|
| 569 |
|
| 570 |
### Modifying Role Access
|
| 571 |
|
|
|
|
| 584 |
|
| 585 |
---
|
| 586 |
|
| 587 |
+
## Special Considerations
|
| 588 |
+
|
| 589 |
+
### Casual Workers (Field Agents & Sales Agents)
|
| 590 |
+
|
| 591 |
+
**Payroll Access for Earnings Tracking:**
|
| 592 |
+
|
| 593 |
+
Field agents and sales agents are typically casual workers who:
|
| 594 |
+
- Get paid per task/errand completed (field agents)
|
| 595 |
+
- Earn commissions on sales (sales agents)
|
| 596 |
+
- Need to track their daily/weekly earnings
|
| 597 |
+
- Want transparency on their compensation
|
| 598 |
+
|
| 599 |
+
**Why Payroll Access:**
|
| 600 |
+
- **Field Agent:** "How much did I earn from today's 5 service calls?"
|
| 601 |
+
- **Sales Agent:** "What's my commission from this week's sales?"
|
| 602 |
+
- VIEW-only access to their own earnings data
|
| 603 |
+
- Cannot see other workers' payroll (controlled by row-level security)
|
| 604 |
+
- Cannot modify payroll data (controlled by action permissions)
|
| 605 |
+
|
| 606 |
+
**Implementation:**
|
| 607 |
+
```python
|
| 608 |
+
# Backend: Row-level security
|
| 609 |
+
if user.role in ['field_agent', 'sales_agent']:
|
| 610 |
+
# Only show their own payroll records
|
| 611 |
+
payroll = db.query(Payroll).filter(
|
| 612 |
+
Payroll.user_id == user.id
|
| 613 |
+
)
|
| 614 |
+
else:
|
| 615 |
+
# Admins/managers can see all payroll
|
| 616 |
+
payroll = db.query(Payroll)
|
| 617 |
+
```
|
| 618 |
+
|
| 619 |
+
### Multi-Role Reality
|
| 620 |
+
|
| 621 |
+
**Client/Contractor Admins Wearing Multiple Hats:**
|
| 622 |
+
|
| 623 |
+
In real-world small/medium businesses:
|
| 624 |
+
- A client_admin might also coordinate projects (PM role)
|
| 625 |
+
- Same person might dispatch field agents (dispatcher role)
|
| 626 |
+
- They need access to ALL apps but with different permissions
|
| 627 |
+
|
| 628 |
+
**Solution:**
|
| 629 |
+
- Give admins VIEW access to all apps
|
| 630 |
+
- Control ACTIONS via permissions (can_create_project, can_approve_payroll, etc.)
|
| 631 |
+
- UI shows/hides action buttons based on permissions
|
| 632 |
+
- Backend validates permissions on all mutations
|
| 633 |
+
|
| 634 |
+
**Example:**
|
| 635 |
+
```javascript
|
| 636 |
+
// Frontend: Conditional action buttons
|
| 637 |
+
{hasPermission('can_create_ticket') && (
|
| 638 |
+
<Button onClick={createTicket}>Create Ticket</Button>
|
| 639 |
+
)}
|
| 640 |
+
|
| 641 |
+
// Backend: Permission check
|
| 642 |
+
@require_permission('can_create_ticket')
|
| 643 |
+
def create_ticket(ticket_data):
|
| 644 |
+
# Only executes if user has permission
|
| 645 |
+
```
|
| 646 |
+
|
| 647 |
## Best Practices
|
| 648 |
|
| 649 |
### Backend
|
src/app/config/apps.py
CHANGED
|
@@ -272,84 +272,137 @@ APPS: Dict[str, AppDefinition] = {
|
|
| 272 |
route="/help",
|
| 273 |
category=AppCategory.SETTINGS
|
| 274 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
}
|
| 276 |
|
| 277 |
|
| 278 |
# ============================================================
|
| 279 |
# ROLE-BASED ACCESS - Defines which apps each role can access
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 280 |
# ============================================================
|
| 281 |
|
| 282 |
ROLE_APP_ACCESS: Dict[str, List[str]] = {
|
| 283 |
"platform_admin": [
|
| 284 |
-
#
|
| 285 |
"dashboard", "organizations", "users", "activity",
|
| 286 |
-
|
| 287 |
-
"
|
|
|
|
|
|
|
|
|
|
| 288 |
],
|
| 289 |
|
| 290 |
"client_admin": [
|
| 291 |
-
#
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
"sales_orders", "customers",
|
| 295 |
-
|
| 296 |
-
"
|
| 297 |
-
|
| 298 |
-
"reports", "settings", "help"
|
| 299 |
],
|
| 300 |
|
| 301 |
"contractor_admin": [
|
| 302 |
-
#
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
"
|
| 306 |
-
|
| 307 |
-
"
|
|
|
|
| 308 |
],
|
| 309 |
|
| 310 |
"sales_manager": [
|
| 311 |
-
# Sales
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
"
|
| 315 |
-
|
| 316 |
-
"
|
|
|
|
| 317 |
],
|
| 318 |
|
| 319 |
"project_manager": [
|
| 320 |
-
#
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
"
|
| 324 |
-
|
| 325 |
-
"settings", "help"
|
| 326 |
],
|
| 327 |
|
| 328 |
"dispatcher": [
|
| 329 |
-
#
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
"
|
| 333 |
-
|
| 334 |
-
"settings", "help"
|
| 335 |
],
|
| 336 |
|
| 337 |
"field_agent": [
|
| 338 |
-
# Field
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
"
|
| 342 |
-
#
|
| 343 |
-
"help"
|
| 344 |
],
|
| 345 |
|
| 346 |
"sales_agent": [
|
| 347 |
-
# Sales
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
"
|
| 351 |
-
#
|
| 352 |
-
"
|
|
|
|
| 353 |
]
|
| 354 |
}
|
| 355 |
|
|
@@ -361,12 +414,12 @@ ROLE_APP_ACCESS: Dict[str, List[str]] = {
|
|
| 361 |
DEFAULT_FAVORITE_APPS: Dict[str, List[str]] = {
|
| 362 |
"platform_admin": ["dashboard", "organizations", "users", "activity"],
|
| 363 |
"client_admin": ["dashboard", "projects", "tickets", "team"],
|
| 364 |
-
"contractor_admin": ["dashboard", "projects", "tickets", "
|
| 365 |
"sales_manager": ["dashboard", "sales_orders", "customers", "reports"],
|
| 366 |
"project_manager": ["dashboard", "projects", "tickets", "team"],
|
| 367 |
-
"dispatcher": ["dashboard", "tickets", "maps", "
|
| 368 |
-
"field_agent": ["tickets", "maps", "timesheets", "
|
| 369 |
-
"sales_agent": ["
|
| 370 |
}
|
| 371 |
|
| 372 |
|
|
|
|
| 272 |
route="/help",
|
| 273 |
category=AppCategory.SETTINGS
|
| 274 |
),
|
| 275 |
+
|
| 276 |
+
# ADDITIONAL OPERATIONS
|
| 277 |
+
"incidents": AppDefinition(
|
| 278 |
+
code="incidents",
|
| 279 |
+
name="Incidents",
|
| 280 |
+
description="Incident tracking and resolution",
|
| 281 |
+
icon="alert-triangle",
|
| 282 |
+
route="/incidents",
|
| 283 |
+
category=AppCategory.OPERATIONS
|
| 284 |
+
),
|
| 285 |
+
|
| 286 |
+
"tasks": AppDefinition(
|
| 287 |
+
code="tasks",
|
| 288 |
+
name="Tasks",
|
| 289 |
+
description="Task management and assignment",
|
| 290 |
+
icon="check-square",
|
| 291 |
+
route="/tasks",
|
| 292 |
+
category=AppCategory.OPERATIONS
|
| 293 |
+
),
|
| 294 |
+
|
| 295 |
+
"subscriptions": AppDefinition(
|
| 296 |
+
code="subscriptions",
|
| 297 |
+
name="Subscriptions",
|
| 298 |
+
description="Subscription and recurring revenue management",
|
| 299 |
+
icon="refresh-cw",
|
| 300 |
+
route="/subscriptions",
|
| 301 |
+
category=AppCategory.FINANCE,
|
| 302 |
+
requires_permission="view_subscriptions"
|
| 303 |
+
),
|
| 304 |
+
|
| 305 |
+
"inventory": AppDefinition(
|
| 306 |
+
code="inventory",
|
| 307 |
+
name="Inventory",
|
| 308 |
+
description="Inventory and asset management",
|
| 309 |
+
icon="package",
|
| 310 |
+
route="/inventory",
|
| 311 |
+
category=AppCategory.OPERATIONS,
|
| 312 |
+
requires_permission="view_inventory"
|
| 313 |
+
),
|
| 314 |
}
|
| 315 |
|
| 316 |
|
| 317 |
# ============================================================
|
| 318 |
# ROLE-BASED ACCESS - Defines which apps each role can access
|
| 319 |
+
#
|
| 320 |
+
# PHILOSOPHY: Views are broad, actions are restricted
|
| 321 |
+
# - Most roles can VIEW most apps to understand the full business context
|
| 322 |
+
# - Action permissions (create, edit, delete) are controlled separately via RBAC
|
| 323 |
+
# - This reflects real-world scenarios where:
|
| 324 |
+
# * A client_admin can also do PM/dispatcher work
|
| 325 |
+
# * A PM needs visibility into sales, finance, and operations
|
| 326 |
+
# * A dispatcher sees what PM sees but has different action permissions
|
| 327 |
+
# * Field agents & sales agents (casual workers) track their daily earnings
|
| 328 |
# ============================================================
|
| 329 |
|
| 330 |
ROLE_APP_ACCESS: Dict[str, List[str]] = {
|
| 331 |
"platform_admin": [
|
| 332 |
+
# Platform admin has access to ALL apps for system management
|
| 333 |
"dashboard", "organizations", "users", "activity",
|
| 334 |
+
"tickets", "projects", "maps", "contractors", "incidents", "tasks",
|
| 335 |
+
"sales_orders", "customers", "reports",
|
| 336 |
+
"team", "timesheets", "payroll",
|
| 337 |
+
"expenses", "documents", "inventory", "subscriptions",
|
| 338 |
+
"profile", "settings", "billing", "notifications", "help"
|
| 339 |
],
|
| 340 |
|
| 341 |
"client_admin": [
|
| 342 |
+
# Client admin has access to ALL apps (can also work as PM/dispatcher)
|
| 343 |
+
# Action permissions differ but views are the same
|
| 344 |
+
"dashboard", "organizations", "projects", "tickets", "team", "incidents", "tasks",
|
| 345 |
+
"sales_orders", "customers", "contractors", "reports",
|
| 346 |
+
"maps", "timesheets", "payroll", "expenses", "documents",
|
| 347 |
+
"inventory", "subscriptions", "billing",
|
| 348 |
+
"profile", "settings", "notifications", "help"
|
|
|
|
| 349 |
],
|
| 350 |
|
| 351 |
"contractor_admin": [
|
| 352 |
+
# Contractor admin has access to ALL apps (can also work as PM/dispatcher)
|
| 353 |
+
# Focus on contractor operations but can see everything
|
| 354 |
+
"dashboard", "organizations", "projects", "tickets", "team", "incidents", "tasks",
|
| 355 |
+
"sales_orders", "customers", "contractors", "reports",
|
| 356 |
+
"maps", "timesheets", "payroll", "expenses", "documents",
|
| 357 |
+
"inventory", "subscriptions", "billing",
|
| 358 |
+
"profile", "settings", "notifications", "help"
|
| 359 |
],
|
| 360 |
|
| 361 |
"sales_manager": [
|
| 362 |
+
# Sales manager has access to ALL apps including finance & inventory
|
| 363 |
+
# Can see operations to understand fulfillment pipeline
|
| 364 |
+
"dashboard", "projects", "tickets", "team", "incidents", "tasks",
|
| 365 |
+
"sales_orders", "customers", "reports", "maps",
|
| 366 |
+
"timesheets", "payroll", "expenses", "inventory", "subscriptions",
|
| 367 |
+
"contractors", "documents", "billing",
|
| 368 |
+
"profile", "settings", "notifications", "help"
|
| 369 |
],
|
| 370 |
|
| 371 |
"project_manager": [
|
| 372 |
+
# PM has access to ALL apps - needs full visibility for project coordination
|
| 373 |
+
# Can see sales, finance, team, operations - everything
|
| 374 |
+
"dashboard", "organizations", "projects", "tickets", "team", "incidents", "tasks",
|
| 375 |
+
"sales_orders", "customers", "contractors", "reports", "maps",
|
| 376 |
+
"timesheets", "payroll", "expenses", "documents", "inventory", "subscriptions",
|
| 377 |
+
"billing", "profile", "settings", "notifications", "help"
|
| 378 |
],
|
| 379 |
|
| 380 |
"dispatcher": [
|
| 381 |
+
# Dispatcher sees what PM sees (same views, different action permissions)
|
| 382 |
+
# Needs full visibility to coordinate field operations
|
| 383 |
+
"dashboard", "projects", "tickets", "team", "incidents", "tasks",
|
| 384 |
+
"sales_orders", "customers", "contractors", "reports", "maps",
|
| 385 |
+
"timesheets", "expenses", "documents", "inventory", "subscriptions",
|
| 386 |
+
"profile", "settings", "notifications", "help"
|
| 387 |
],
|
| 388 |
|
| 389 |
"field_agent": [
|
| 390 |
+
# Field agents (casual workers) need to see their earnings and daily work
|
| 391 |
+
# Include payroll to track earnings from daily errands
|
| 392 |
+
"dashboard", "tickets", "maps", "timesheets", "tasks", "incidents",
|
| 393 |
+
"payroll", # Track their daily earnings
|
| 394 |
+
"expenses", "documents", "customers", # Customer info for field visits
|
| 395 |
+
"profile", "notifications", "help"
|
| 396 |
],
|
| 397 |
|
| 398 |
"sales_agent": [
|
| 399 |
+
# Sales agents (casual workers) need to track their commission/earnings
|
| 400 |
+
# Include payroll to see earnings from sales
|
| 401 |
+
"dashboard", "sales_orders", "customers", "maps", "reports",
|
| 402 |
+
"tickets", "tasks", # Follow up on customer issues
|
| 403 |
+
"payroll", # Track their sales commissions/earnings
|
| 404 |
+
"expenses", "documents",
|
| 405 |
+
"profile", "notifications", "help"
|
| 406 |
]
|
| 407 |
}
|
| 408 |
|
|
|
|
| 414 |
DEFAULT_FAVORITE_APPS: Dict[str, List[str]] = {
|
| 415 |
"platform_admin": ["dashboard", "organizations", "users", "activity"],
|
| 416 |
"client_admin": ["dashboard", "projects", "tickets", "team"],
|
| 417 |
+
"contractor_admin": ["dashboard", "projects", "tickets", "payroll"],
|
| 418 |
"sales_manager": ["dashboard", "sales_orders", "customers", "reports"],
|
| 419 |
"project_manager": ["dashboard", "projects", "tickets", "team"],
|
| 420 |
+
"dispatcher": ["dashboard", "tickets", "maps", "tasks"],
|
| 421 |
+
"field_agent": ["tickets", "maps", "timesheets", "payroll"], # Focus on work & earnings
|
| 422 |
+
"sales_agent": ["sales_orders", "customers", "maps", "payroll"] # Focus on sales & commissions
|
| 423 |
}
|
| 424 |
|
| 425 |
|