# Permissions & Security - Task Breakdown

## Pre-requisites

- [ ] Understanding of UserFrosting permission system
- [ ] Understanding of existing role hierarchy
- [ ] Database access for migrations

## Tasks

### Task 1: Create Permission Migration Script

**Estimated Complexity**: Low
**Files**: `sql/migrations/daybook_permissions.sql`

**Acceptance Criteria**:
- [ ] All 7 new permission keys inserted
- [ ] Permissions assigned to Employee role
- [ ] Permissions assigned to Shift Lead role
- [ ] Permissions assigned to Manager role
- [ ] Permissions assigned to Owner role
- [ ] Migration is idempotent (can run multiple times)
- [ ] Rollback script included

---

### Task 2: Create DaybookPermissions Helper Class

**Estimated Complexity**: Medium
**Files**: `userfrosting/lib/DaybookPermissions.php`

**Acceptance Criteria**:
- [ ] `canView()` checks daybook_view
- [ ] `canCompleteTasks()` checks daybook_complete_tasks
- [ ] `canCreateNotes()` checks daybook_create_notes
- [ ] `canViewManagerNotes()` checks daybook_view_manager_notes
- [ ] `canManageTasks()` checks daybook_manage_tasks
- [ ] `canManageKPI()` checks daybook_manage_kpi
- [ ] `canUseWhiteboard()` checks daybook_whiteboard
- [ ] `getPermissions()` returns array for frontend
- [ ] `requirePermission()` throws exception if denied
- [ ] Tests pass

---

### Task 3: Create Input Validation Class

**Estimated Complexity**: Medium
**Files**: `userfrosting/lib/DaybookInputValidator.php`

**Acceptance Criteria**:
- [ ] `sanitizeNoteContent()` strips dangerous HTML
- [ ] `validateTaskCompletion()` validates task data
- [ ] `validateNote()` validates note data
- [ ] `validateDate()` validates date format
- [ ] `validateWhiteboardData()` validates canvas JSON
- [ ] All validators return array of errors (empty if valid)
- [ ] XSS prevention working
- [ ] Tests pass

---

### Task 4: Create Employee Session Class

**Estimated Complexity**: Low
**Files**: `userfrosting/lib/EmployeeSession.php`

**Acceptance Criteria**:
- [ ] `setEmployee(int)` stores employee ID in session
- [ ] `getEmployeeId()` returns current employee or null
- [ ] `hasEmployee()` returns boolean
- [ ] `clearEmployee()` removes from session
- [ ] Session key is namespaced to avoid conflicts
- [ ] Tests pass

---

### Task 5: Create Rate Limiter Class

**Estimated Complexity**: Low
**Files**: `userfrosting/lib/DaybookRateLimiter.php`

**Acceptance Criteria**:
- [ ] Uses Redis/PHPFastCache for storage
- [ ] `isRateLimited(key, maxAttempts, window)` method
- [ ] Returns true when limit exceeded
- [ ] Returns false when within limit
- [ ] Increments counter on each check
- [ ] TTL set to window duration
- [ ] Tests pass

---

### Task 6: Add Permission Checks to TasksApiController

**Estimated Complexity**: Low
**Files**: `userfrosting/controllers/Daybook/TasksApiController.php`

**Acceptance Criteria**:
- [ ] `getTaskLists()` requires `daybook_view`
- [ ] `completeTask()` requires `daybook_complete_tasks`
- [ ] `uncompleteTask()` requires `daybook_complete_tasks`
- [ ] `addComment()` requires `daybook_complete_tasks`
- [ ] `createTaskList()` requires `daybook_manage_tasks`
- [ ] `updateTaskList()` requires `daybook_manage_tasks`
- [ ] `deleteTaskList()` requires `daybook_manage_tasks`
- [ ] All endpoints check store access
- [ ] All POST endpoints validate CSRF token
- [ ] All endpoints validate employee session
- [ ] Tests pass

---

### Task 7: Add Permission Checks to NotesApiController

**Estimated Complexity**: Low
**Files**: `userfrosting/controllers/Daybook/NotesApiController.php`

**Acceptance Criteria**:
- [ ] `getNotes()` requires `daybook_view`
- [ ] `getNotes()` filters manager-only notes based on permission
- [ ] `createNote()` requires `daybook_create_notes`
- [ ] `updateNote()` requires `daybook_create_notes` + ownership
- [ ] `deleteNote()` requires `daybook_create_notes` + ownership
- [ ] `addReaction()` requires `daybook_view`
- [ ] `addComment()` requires `daybook_view`
- [ ] Rate limiting on `createNote()` (10 per minute)
- [ ] All endpoints check store access
- [ ] Input validation applied
- [ ] Tests pass

---

### Task 8: Add Permission Checks to WhiteboardApiController

**Estimated Complexity**: Low
**Files**: `userfrosting/controllers/Daybook/WhiteboardApiController.php`

**Acceptance Criteria**:
- [ ] `getCanvas()` requires `daybook_view`
- [ ] `saveCanvas()` requires `daybook_whiteboard`
- [ ] `addItem()` requires `daybook_whiteboard`
- [ ] `updateItem()` requires `daybook_whiteboard`
- [ ] `deleteItem()` requires `daybook_whiteboard`
- [ ] `clearCanvas()` requires `daybook_whiteboard`
- [ ] Rate limiting on canvas updates (60 per minute)
- [ ] Canvas size validation
- [ ] All endpoints check store access
- [ ] Tests pass

---

### Task 9: Add Permission Checks to KPIApiController

**Estimated Complexity**: Low
**Files**: `userfrosting/controllers/Daybook/KPIApiController.php`

**Acceptance Criteria**:
- [ ] `getKPIs()` requires `daybook_view`
- [ ] `getConfig()` requires `daybook_manage_kpi`
- [ ] `updateConfig()` requires `daybook_manage_kpi`
- [ ] All endpoints check store access
- [ ] Tests pass

---

### Task 10: Create Employee Selector API Endpoint

**Estimated Complexity**: Low
**Files**: `userfrosting/controllers/Daybook/EmployeeApiController.php`

**Acceptance Criteria**:
- [ ] `getEmployees()` returns employees for selector
- [ ] `setCurrentEmployee()` stores in session
- [ ] `getCurrentEmployee()` returns current or null
- [ ] `clearCurrentEmployee()` clears session
- [ ] Store access required for all endpoints
- [ ] Tests pass

---

### Task 11: Add Route Middleware for Permission Checks

**Estimated Complexity**: Medium
**Files**: `userfrosting/middleware/DaybookPermissionMiddleware.php`

**Acceptance Criteria**:
- [ ] Middleware can be applied to route groups
- [ ] Checks `daybook_view` for all daybook routes
- [ ] Returns 403 with JSON error on denial
- [ ] Integrates with existing middleware stack
- [ ] Tests pass

---

### Task 12: Pass Permissions to Frontend

**Estimated Complexity**: Low
**Files**: Various route files and templates

**Acceptance Criteria**:
- [ ] DaybookPermissions instantiated in routes
- [ ] `getPermissions()` passed to templates
- [ ] JavaScript receives permissions object
- [ ] `window.daybookPermissions` available
- [ ] UI elements hidden based on permissions

---

### Task 13: Create Audit Log Table and Class (Optional)

**Estimated Complexity**: Medium
**Files**:
- `sql/migrations/daybook_audit_log.sql`
- `userfrosting/lib/DaybookAuditLog.php`

**Acceptance Criteria**:
- [ ] `daybook_audit_log` table created
- [ ] `log(action, employeeId, details)` method
- [ ] Logs IP address
- [ ] Logs timestamp
- [ ] Logs JSON details
- [ ] Integration with controllers
- [ ] Tests pass

---

## Testing Tasks

### Test 1: Permission Unit Tests

**File**: `userfrosting/tests/Daybook/Unit/DaybookPermissionsTest.php`

**Test Cases**:
- [ ] `test_canView_returns_true_for_employee`
- [ ] `test_canCreateNotes_returns_false_for_employee`
- [ ] `test_canCreateNotes_returns_true_for_manager`
- [ ] `test_canManageKPI_returns_true_only_for_owner`
- [ ] `test_getPermissions_returns_all_keys`
- [ ] `test_requirePermission_throws_on_denial`

---

### Test 2: Input Validation Unit Tests

**File**: `userfrosting/tests/Daybook/Unit/InputValidatorTest.php`

**Test Cases**:
- [ ] `test_sanitizeNoteContent_strips_script_tags`
- [ ] `test_sanitizeNoteContent_allows_safe_tags`
- [ ] `test_validateTaskCompletion_requires_taskId`
- [ ] `test_validateTaskCompletion_requires_employeeId`
- [ ] `test_validateNote_requires_title`
- [ ] `test_validateNote_enforces_max_length`
- [ ] `test_validateDate_accepts_valid_format`
- [ ] `test_validateDate_rejects_invalid_format`

---

### Test 3: Rate Limiter Unit Tests

**File**: `userfrosting/tests/Daybook/Unit/RateLimiterTest.php`

**Test Cases**:
- [ ] `test_returns_false_within_limit`
- [ ] `test_returns_true_when_limit_exceeded`
- [ ] `test_limit_resets_after_window`
- [ ] `test_different_keys_have_separate_limits`

---

### Test 4: Employee Session Unit Tests

**File**: `userfrosting/tests/Daybook/Unit/EmployeeSessionTest.php`

**Test Cases**:
- [ ] `test_setEmployee_stores_id`
- [ ] `test_getEmployeeId_returns_stored_id`
- [ ] `test_getEmployeeId_returns_null_when_not_set`
- [ ] `test_hasEmployee_returns_correct_boolean`
- [ ] `test_clearEmployee_removes_id`

---

### Test 5: API Permission Integration Tests

**File**: `userfrosting/tests/Daybook/Integration/PermissionApiTest.php`

**Test Cases**:
- [ ] `test_employee_can_view_daybook`
- [ ] `test_employee_can_complete_tasks`
- [ ] `test_employee_cannot_create_notes`
- [ ] `test_manager_can_create_notes`
- [ ] `test_employee_cannot_see_manager_notes`
- [ ] `test_manager_can_see_manager_notes`
- [ ] `test_non_owner_cannot_manage_kpi`
- [ ] `test_owner_can_manage_kpi`
- [ ] `test_wrong_store_returns_403`
- [ ] `test_missing_csrf_returns_403`
- [ ] `test_missing_employee_returns_400`

---

## Completion Checklist

- [ ] Permission migration created
- [ ] DaybookPermissions class created
- [ ] Input validator created
- [ ] Employee session class created
- [ ] Rate limiter created
- [ ] TasksApiController permission checks added
- [ ] NotesApiController permission checks added
- [ ] WhiteboardApiController permission checks added
- [ ] KPIApiController permission checks added
- [ ] Employee selector API created
- [ ] Permission middleware created
- [ ] Frontend permissions working
- [ ] All unit tests passing
- [ ] All integration tests passing
- [ ] Security review completed
