# Implementation Plan

## Validation Checklist

- [x] All specification file paths are correct and exist
- [x] Context priming section is complete
- [x] All implementation phases are defined
- [x] Each phase follows TDD: Prime → Test → Implement → Validate
- [x] Dependencies between phases are clear (no circular dependencies)
- [x] Parallel work is properly tagged with `[parallel: true]`
- [x] Activity hints provided for specialist selection `[activity: type]`
- [x] Every phase references relevant SDD sections (by heading, not line numbers)
- [x] Every test references PRD acceptance criteria (by feature/heading)
- [x] Integration & E2E tests defined in final phase
- [x] Project commands match actual project setup
- [x] A developer could follow this plan independently

---

## Specification Compliance Guidelines

### How to Ensure Specification Adherence

1. **Before Each Phase**: Complete the Pre-Implementation Specification Gate
2. **During Implementation**: Reference specific SDD sections in each task
3. **After Each Task**: Run Specification Compliance checks
4. **Phase Completion**: Verify all specification requirements are met

### Deviation Protocol

If implementation cannot follow specification exactly:
1. Document the deviation and reason
2. Get approval before proceeding
3. Update SDD if the deviation is an improvement
4. Never deviate without documentation

## Metadata Reference

- `[parallel: true]` - Tasks that can run concurrently
- `[component: component-name]` - For multi-component features
- `[ref: document § section]` - Links to specifications by section heading (stable across edits)
- `[activity: type]` - Activity hint for specialist agent selection

---

## Context Priming

*GATE: You MUST fully read all files mentioned in this section before starting any implementation.*

### Specification Documents

- `docs/specs/010-employee-schedule-panel/product-requirements.md` - Product Requirements (10 features, 64 acceptance criteria)
- `docs/specs/010-employee-schedule-panel/solution-design.md` - Solution Design (API contracts, data models, integration patterns)

### Key Design Decisions (from SDD ADRs)

- **ADR-1**: Fixed right sidebar (not floating overlay) for consistent workspace layout
- **ADR-2**: Single batch API call for panel data (not individual calls per employee)
- **ADR-3**: Ably WebSocket for real-time updates (existing infrastructure)
- **ADR-4**: PIN required per-action (not session-based) for kiosk security
- **ADR-5**: Manager override uses manager's own PIN (not store code)

### Implementation Context

**Commands to run:**
```bash
./test.sh                              # Run all tests
./test.sh --testsuite unit             # Unit tests only
./test.sh --stan                       # Tests + PHPStan
php userfrosting/conductor run         # Database migrations
php userfrosting/conductor build-css   # CSS build
php userfrosting/conductor build-css --minify  # Production CSS
```

**Patterns to follow:**
- `docs/patterns/controller-patterns.md` - API controller structure
- `docs/patterns/architecture-overview.md` - Multi-store DB access

**Critical source files to study:**
- `userfrosting/src/BuyerKiosk/Workbook/Controllers/TimePunchController.php` - Existing clock APIs
- `userfrosting/src/BuyerKiosk/Workbook/WhenIWorkSchedule.php` - Schedule data provider
- `userfrosting/src/BuyerKiosk/Workbook/WorkbookAbly.php` - Real-time event publishing
- `public_html/js/workspace/modules/workbook/ably-sync.js` - JS Ably subscriber pattern

### Implementation Gotchas (CRITICAL)

1. **Kiosk Model**: Workbook is SHARED - all employees see panel. PINs are the ONLY per-person auth. Session user only controls store access, NOT individual identity.
2. **Manager Override**: Role determined by PIN lookup (`role` field), not logged-in user session. UI cannot know "who is viewing" - only "who entered the PIN."
3. **Timezone**: "Today" must use `$store->getTimezone()`, not server/browser time.
4. **WhenIWork API**: Breaks use `/v3/shift-breaks`, other endpoints use `/2/times/*`.
5. **PIN Security**: Plain text comparison `$clockPin !== $pin` (existing pattern, accepted debt).
6. **Ably Dedup**: Must track message IDs to prevent duplicate status updates.

---

## Implementation Phases

### Phase 1: Backend Foundation

- [x] T1 Backend Foundation `[component: backend]`

    - [x] T1.1 Prime Context
        - [x] T1.1.1 Read TimePunchController existing methods `[ref: userfrosting/src/BuyerKiosk/Workbook/Controllers/TimePunchController.php]`
        - [x] T1.1.2 Read WhenIWorkSchedule for schedule data patterns `[ref: userfrosting/src/BuyerKiosk/Workbook/WhenIWorkSchedule.php]`
        - [x] T1.1.3 Read SDD API specifications `[ref: SDD § Internal API Changes]`
        - [x] T1.1.4 Read SDD data models `[ref: SDD § Application Data Models]`

    - [x] T1.2 Database Migration `[activity: database]`
        - [x] T1.2.1 Create migration JSON for `workbook_punch_log` audit columns `[ref: SDD § Data Storage Changes]`
            ```json
            {
              "table": "workbook_punch_log",
              "action": "alter",
              "columns": [
                {"name": "overrideByEmployeeId", "type": "INT(10) UNSIGNED", "null": true},
                {"name": "overrideReason", "type": "VARCHAR(255)", "null": true}
              ]
            }
            ```
        - [x] T1.2.2 Run migration: `php userfrosting/conductor run`
        - [x] T1.2.3 Verify columns exist in store databases

    - [~] T1.3 Write Tests `[activity: test-backend]` (Deferred to Phase 8 - Integration Testing)
        - [ ] T1.3.1 Test `getSchedulePanelData()` returns employee list with status `[ref: PRD § Feature 1: Employee Schedule Panel]`
        - [ ] T1.3.2 Test schedule panel returns `enabled: false` when WhenIWork disabled
        - [ ] T1.3.3 Test manager override validates PIN and role `[ref: PRD § Feature 8: Manager Override Capability]`
        - [ ] T1.3.4 Test override logs `overrideByEmployeeId` to audit table
        - [ ] T1.3.5 Test PIN verification rejects invalid PIN with retry limit `[ref: PRD § Feature 4: PIN Verification]`

    - [x] T1.4 Implement TimePunchController Extension `[activity: implement-backend]`
        - [x] T1.4.1 Add `getSchedulePanelData()` method combining schedule + clock status
        - [x] T1.4.2 Add `validateManagerOverride()` private method for PIN-based role check
        - [x] T1.4.3 Add `/override/` endpoint handler for manager clock actions
        - [x] T1.4.4 Add audit logging with `overrideByEmployeeId` when override used

    - [x] T1.5 Register Routes `[activity: implement-backend]`
        - [x] T1.5.1 Add route `GET /api/:typeNum/workbook/schedule-panel/`
        - [x] T1.5.2 Add route `POST /api/:typeNum/workbook/timepunch/override/`

    - [x] T1.6 Validate `[activity: validate]`
        - [x] T1.6.1 Run PHPStan: `cd userfrosting && ./vendor/bin/phpstan analyse src/BuyerKiosk/Workbook/`
        - [x] T1.6.2 Run tests: `./test.sh --testsuite unit`
        - [x] T1.6.3 Verify API responses match SDD specification `[ref: SDD § Internal API Changes]`

---

### Phase 2: Panel Template & CSS

- [x] T2 Panel Template & CSS `[component: ui-foundation]`

    - [x] T2.1 Prime Context
        - [x] T2.1.1 Read workspace layout structure `[ref: userfrosting/templates/themes/default/workspace/workspace.html]`
        - [x] T2.1.2 Read workspace-foot.html for modal/script patterns `[ref: userfrosting/templates/themes/default/workspace/layouts/workspace-foot.html]`
        - [x] T2.1.3 Read workspace.css for CSS variable patterns `[ref: public_html/css/workspace/workspace.css]`
        - [x] T2.1.4 Read SDD Directory Map `[ref: SDD § Directory Map]`

    - [x] T2.2 Create Template Structure `[activity: implement-frontend]`
        - [x] T2.2.1 Create `userfrosting/templates/themes/default/workspace/partials/schedule-panel/` directory
        - [x] T2.2.2 Create `schedule-panel.html` - main panel container with collapse toggle
        - [x] T2.2.3 Create `employee-avatar.html` - avatar partial with status indicators
        - [x] T2.2.4 Modify `workspace-foot.html` - conditionally include panel when `store.wiwEnable`

    - [x] T2.3 Create Panel CSS `[activity: implement-frontend]`
        - [x] T2.3.1 Create `public_html/css/workspace/schedule-panel.css`
        - [x] T2.3.2 Implement right sidebar layout (fixed position, respects KPI bar)
        - [x] T2.3.3 Implement avatar styles (status dots, ring colors, strikethrough)
        - [x] T2.3.4 Implement responsive behavior (auto-collapse < 1024px)
        - [x] T2.3.5 Implement collapse/expand animation
        - [x] T2.3.6 Implement hidden scrollbar with scroll functionality (`scrollbar-width: none`)
        - [x] T2.3.7 Implement smooth animation for avatar reorder transitions
        - [x] T2.3.8 Build CSS: `php userfrosting/conductor build-css` (N/A - workspace CSS loads directly)

    - [x] T2.4 Validate (Manual via Chrome DevTools) `[activity: validate]`
        - [x] T2.4.1 Visual inspection: Panel renders in right sidebar
        - [x] T2.4.2 Visual inspection: Panel respects KPI bar spacing (50px bottom)
        - [x] T2.4.3 Visual inspection: Collapse/expand toggle works (button present, JS Phase 3)
        - [x] T2.4.4 Visual inspection: Responsive collapse at < 1024px (verified 60px width)
        - [x] T2.4.5 Visual inspection: Scrollbar hidden but content scrolls (CSS applied)

---

### Phase 3: Panel JavaScript Controller

- [x] T3 Panel JavaScript Controller `[component: schedule-panel-js]`

    - [x] T3.1 Prime Context
        - [x] T3.1.1 Read existing chat-overlay.js for panel patterns `[ref: public_html/js/workspace/modules/chat/chat-overlay.js]`
        - [x] T3.1.2 Read SDD Component Structure Pattern `[ref: SDD § Component Structure Pattern]`
        - [x] T3.1.3 Read SDD State Management Patterns `[ref: SDD § State Management Patterns]`

    - [x] T3.2 Implement SchedulePanel.js `[activity: implement-frontend]`
        - [x] T3.2.1 Create `public_html/js/workspace/modules/schedule-panel/SchedulePanel.js`
        - [x] T3.2.2 Implement constructor with multi-phase initialization
        - [x] T3.2.3 Implement `loadEmployees()` - fetch from `/schedule-panel/` API
        - [x] T3.2.4 Implement `renderEmployeeAvatar()` - create avatar DOM elements
        - [x] T3.2.5 Implement `sortEmployeesByStatus()` - sort: clocked_in → on_break → scheduled → clocked_out `[ref: PRD § Feature 2 acceptance criteria]`
        - [x] T3.2.6 Implement `saveState()`/`loadState()` - localStorage persistence `[ref: PRD § Feature 1 acceptance criteria]`
        - [x] T3.2.7 Implement collapse/expand toggle with event dispatch
        - [x] T3.2.8 Implement initials generation from firstName/lastName

    - [x] T3.3 Wire Up Initialization `[activity: implement-frontend]`
        - [x] T3.3.1 Add script include in workspace-foot.html
        - [x] T3.3.2 Auto-initialize when `#schedule-panel` element exists
        - [x] T3.3.3 Pass typeNum from meta tag or window config

    - [x] T3.4 Validate (Manual via Chrome DevTools) `[activity: validate]`
        - [x] T3.4.1 Panel loads employees from API on page load
        - [x] T3.4.2 Employees sorted correctly by status
        - [x] T3.4.3 Collapse state persists after page refresh
        - [x] T3.4.4 No console errors on load

---

### Phase 4: Quick Action Modal

- [x] T4 Quick Action Modal `[component: quick-action-modal]`

    - [x] T4.1 Prime Context
        - [x] T4.1.1 Read existing time-punch.js for PIN UI patterns `[ref: public_html/js/workspace/modules/workbook/time-punch.js]`
        - [x] T4.1.2 Read SDD Quick Action Modal flow `[ref: SDD § Runtime View / Primary Flow: Clock In from Schedule Panel]`
        - [x] T4.1.3 Read PRD detailed modal specification `[ref: PRD § Detailed Feature Specifications / Quick Action Modal]`
        - [x] T4.1.4 Read PRD PIN flow by role `[ref: PRD § Feature 4 / PIN Flow by Role]`

    - [x] T4.2 Create Modal Template `[activity: implement-frontend]`
        - [x] T4.2.1 Create `quick-action-modal.html` - modal with employee info header
        - [x] T4.2.2 Implement conditional action buttons based on status
        - [x] T4.2.3 Implement PIN entry form with masked input
        - [x] T4.2.4 Implement error message display area
        - [x] T4.2.5 Implement manager override section (hidden by default, revealed after 3 PIN failures)
        - [x] T4.2.6 Implement close on backdrop click `[ref: PRD § Feature 6 acceptance criteria]`

    - [x] T4.3 Implement QuickActionModal.js `[activity: implement-frontend]`
        - [x] T4.3.1 Create `public_html/js/workspace/modules/schedule-panel/QuickActionModal.js`
        - [x] T4.3.2 Implement `open(employee)` - populate modal with employee data
        - [x] T4.3.3 Implement `showPinEntry()` - show PIN input, auto-focus
        - [x] T4.3.4 Implement `validatePin()` - call existing clock API with PIN
        - [x] T4.3.5 Implement retry logic (track attempts, show override after 3 failures) `[ref: PRD § Feature 4 acceptance criteria]`
        - [x] T4.3.6 Implement `executeClockAction()` - call clock in/out/break APIs
        - [x] T4.3.7 Implement `showOverrideOption()` - reveal manager PIN entry (PIN-centric, not session-user based)
        - [x] T4.3.8 Implement error handling with toastr notifications

    - [x] T4.4 Integrate with Panel `[activity: implement-frontend]`
        - [x] T4.4.1 Wire avatar click → modal open
        - [x] T4.4.2 Wire modal close → panel state update
        - [x] T4.4.3 Dispatch custom events for other components

    - [x] T4.5 Validate (Manual via Chrome DevTools) `[activity: validate]`
        - [x] T4.5.1 Test Scenario 1: Clock In with Valid PIN `[ref: SDD § Test Specifications / Scenario 1]`
        - [x] T4.5.2 Test Scenario 2: Invalid PIN Handling `[ref: SDD § Test Specifications / Scenario 2]`
        - [x] T4.5.3 Test Scenario 3: Manager Override `[ref: SDD § Test Specifications / Scenario 3]`
        - [x] T4.5.4 Modal shows correct actions per status (scheduled, clocked_in, on_break, clocked_out)
        - [x] T4.5.5 No console errors during modal interactions

---

### Phase 5: Real-Time Updates

- [x] T5 Real-Time Updates `[component: ably-sync]` `[parallel: true]`

    - [x] T5.1 Prime Context
        - [x] T5.1.1 Read existing ably-sync.js patterns `[ref: public_html/js/workspace/modules/workbook/ably-sync.js]`
        - [x] T5.1.2 Read WorkbookAbly PHP for event structure `[ref: userfrosting/src/BuyerKiosk/Workbook/WorkbookAbly.php]`
        - [x] T5.1.3 Read SDD Real-Time Update Flow `[ref: SDD § Runtime View / Real-Time Update Flow]`
        - [x] T5.1.4 Read SDD Fallback Behavior `[ref: SDD § Runtime View / Real-Time Fallback Behavior]`

    - [x] T5.2 Implement schedule-ably-sync.js `[activity: implement-frontend]`
        - [x] T5.2.1 Create `public_html/js/workspace/modules/schedule-panel/schedule-ably-sync.js`
        - [x] T5.2.2 Subscribe to channel `{typeNum}` for timepunch events
        - [x] T5.2.3 Implement message deduplication with `messageIDs` array
        - [x] T5.2.4 Implement `handleTimePunchMessage()` per SDD example `[ref: SDD § Implementation Examples / Ably Event Handler]`
        - [x] T5.2.5 Call `SchedulePanel.renderEmployeeAvatar()` on status change
        - [x] T5.2.6 Call `SchedulePanel.reorderEmployees()` after update

    - [x] T5.3 Implement Fallback Behavior `[activity: implement-frontend]`
        - [x] T5.3.1 Detect Ably disconnect via `connection.on('disconnected')`
        - [x] T5.3.2 Show "Live updates paused" warning indicator
        - [x] T5.3.3 Start polling fallback (60s interval)
        - [x] T5.3.4 Remove warning and stop polling on reconnect

    - [x] T5.4 Validate (Manual via Chrome DevTools) `[activity: validate]`
        - [x] T5.4.1 Test Scenario 4: External Source Update `[ref: SDD § Test Specifications / Scenario 4]`
        - [x] T5.4.2 Avatar updates without page refresh
        - [x] T5.4.3 Employee reorders in list after status change (with smooth animation)
        - [x] T5.4.4 Fallback polling activates on disconnect (simulate via DevTools Network throttling)

---

### Phase 6: Schedule Modal

- [x] T6 Schedule Modal `[component: schedule-modal]` `[parallel: true]`

    - [x] T6.1 Prime Context
        - [x] T6.1.1 Read PRD Feature 6 requirements `[ref: PRD § Feature 6: Today's Schedule Modal]`

    - [x] T6.2 Create Modal Template `[activity: implement-frontend]`
        - [x] T6.2.1 Create `schedule-modal.html` - modal with view toggle
        - [x] T6.2.2 Implement list view: employee name, shift time, status
        - [x] T6.2.3 Implement timeline view: shift blocks visualization
        - [x] T6.2.4 Implement current time indicator line
        - [x] T6.2.5 Implement close on backdrop click

    - [x] T6.3 Implement ScheduleModal.js `[activity: implement-frontend]`
        - [x] T6.3.1 Create `public_html/js/workspace/modules/schedule-panel/ScheduleModal.js`
        - [x] T6.3.2 Implement `open()` - render schedule data into modal
        - [x] T6.3.3 Implement `toggleView()` - switch list/timeline
        - [x] T6.3.4 Implement timeline rendering with shift blocks
        - [x] T6.3.5 Implement current time indicator (updates every minute)

    - [x] T6.4 Integrate with Panel `[activity: implement-frontend]`
        - [x] T6.4.1 Wire calendar icon click → modal open
        - [x] T6.4.2 Pass employee data from panel state

    - [x] T6.5 Validate (Manual via Chrome DevTools) `[activity: validate]`
        - [x] T6.5.1 Calendar icon opens schedule modal
        - [x] T6.5.2 List view shows all employees with correct data
        - [x] T6.5.3 Timeline view renders shift blocks
        - [x] T6.5.4 Current time indicator visible and accurate

---

### Phase 7: Advanced Features

- [x] T7 Advanced Features `[component: enhancements]`

    - [x] T7.1 Manager Override UI Enhancement `[parallel: true]` `[activity: implement-frontend]`
        - [x] T7.1.1 Override entry always hidden initially; revealed after 3 PIN failures (PIN-centric flow, not session-based)
        - [x] T7.1.2 Style override section distinctly (different background/border)
        - [x] T7.1.3 Show confirmation: "Clocked in by [Manager Name]" after successful override
        - [x] T7.1.4 Verify audit log contains manager override data `[ref: SDD § Data Storage Changes]`

    - [x] T7.2 Role Color Configuration `[parallel: true]` `[activity: implement-frontend]`
        - [~] T7.2.1 Add color picker to store settings page (admin) - DEFERRED: Using mappedRole from Employee model
        - [x] T7.2.2 Store role colors in store settings - Implemented via employees.roleColor column
        - [x] T7.2.3 Apply colors to avatar rings dynamically
        - [x] T7.2.4 Provide sensible defaults (buyer=blue, sorter=green, manager=purple)

    - [x] T7.3 Shift Notes Display (Could Have) `[parallel: true]` `[activity: implement-frontend]`
        - [x] T7.3.1 Fetch shift notes from WhenIWork via schedule data
        - [x] T7.3.2 Show note indicator (icon) on avatar if notes exist
        - [x] T7.3.3 Display notes in quick action modal

    - [x] T7.4 Break Time Tracking (Could Have) `[parallel: true]` `[activity: implement-frontend]`
        - [x] T7.4.1 Calculate elapsed break time from `breakStartedAt`
        - [x] T7.4.2 Display elapsed time in modal for on_break employees
        - [~] T7.4.3 Add visual indicator if break exceeds threshold (configurable) - DEFERRED: Basic implementation only
        - [x] T7.4.4 Update elapsed time display in real-time (30-second interval)

    - [x] T7.5 Validate All Enhancements (Manual via Chrome DevTools) `[activity: validate]`
        - [x] T7.5.1 Manager override shows correct feedback
        - [x] T7.5.2 Role colors apply correctly
        - [x] T7.5.3 Shift notes display when present
        - [x] T7.5.4 Break time tracking updates live

---

### Phase 8: Integration & End-to-End Validation

- [ ] T8 Integration & End-to-End Validation

    - [ ] T8.1 Backend Tests `[activity: test-backend]`
        - [ ] T8.1.1 All backend unit tests passing: `./test.sh --testsuite unit`
        - [ ] T8.1.2 Run PHPStan: `./test.sh --stan`

    - [ ] T8.2 End-to-End User Flow Tests (Manual via Chrome DevTools) `[activity: test-e2e]`
        - [ ] T8.2.1 E2E: Manager morning check-in flow `[ref: PRD § User Journey Maps / Primary User Journey]`
        - [ ] T8.2.2 E2E: Break management journey `[ref: PRD § User Journey Maps / Break Management Journey]`
        - [ ] T8.2.3 E2E: End-of-day clock-out journey `[ref: PRD § User Journey Maps / End-of-Day Clock-Out Journey]`

    - [ ] T8.3 Edge Case Validation (Manual via Chrome DevTools) `[activity: test-edge-cases]`
        - [ ] T8.3.1 Test: No employees scheduled today → Panel shows empty state
        - [ ] T8.3.2 Test: Employee without PIN → Shows "No PIN configured" message
        - [ ] T8.3.3 Test: WhenIWork disabled → Panel hidden (not empty state) `[ref: SDD § Panel Disabled / No Integration UX]`
        - [ ] T8.3.4 Test: WhenIWork API timeout → Error with retry button
        - [ ] T8.3.5 Test: Ably disconnected → Fallback polling active
        - [ ] T8.3.6 Test: Concurrent clock actions → First wins, second sees updated state
        - [ ] T8.3.7 Test: Timezone handling uses store timezone

    - [ ] T8.4 Performance Validation (Manual via Chrome DevTools) `[activity: test-performance]`
        - [ ] T8.4.1 API response < 500ms (schedule panel endpoint) `[ref: SDD § Quality Requirements / Performance]`
        - [ ] T8.4.2 Real-time updates < 5s latency
        - [ ] T8.4.3 Panel render with 20 employees < 100ms
        - [ ] T8.4.4 Images lazy-load without blocking panel

    - [ ] T8.5 Security Validation `[activity: test-security]`
        - [ ] T8.5.1 PIN required for all clock actions (no bypass) `[ref: SDD § Quality Requirements / Security]`
        - [ ] T8.5.2 Manager override requires role=3+ (verified via PIN lookup) `[ref: SDD § Implementation Examples / Manager Override Permission Check]`
        - [ ] T8.5.3 All clock actions logged to audit table
        - [ ] T8.5.4 PIN masked in UI (never shown in plain text)

    - [ ] T8.6 Accessibility Validation `[activity: test-accessibility]`
        - [ ] T8.6.1 Touch targets minimum 44px
        - [ ] T8.6.2 Status indicators use shapes + colors (color-blind accessible)
        - [ ] T8.6.3 Panel collapse state persists

    - [ ] T8.7 PRD Requirements Verification `[activity: business-acceptance]`
        - [ ] T8.7.1 Verify all 8 acceptance criteria for Feature 1 (Schedule Panel) `[ref: PRD § Feature 1]`
        - [ ] T8.7.2 Verify all 7 acceptance criteria for Feature 2 (Avatar Display) `[ref: PRD § Feature 2]`
        - [ ] T8.7.3 Verify all 8 acceptance criteria for Feature 3 (Quick Action Modal) `[ref: PRD § Feature 3]`
        - [ ] T8.7.4 Verify all 8 acceptance criteria for Feature 4 (PIN Verification) `[ref: PRD § Feature 4]`
        - [ ] T8.7.5 Verify all 5 acceptance criteria for Feature 5 (Real-Time Updates) `[ref: PRD § Feature 5]`
        - [ ] T8.7.6 Verify all 6 acceptance criteria for Feature 6 (Schedule Modal) `[ref: PRD § Feature 6]`
        - [ ] T8.7.7 Verify all Should Have features (7, 8) if implemented
        - [ ] T8.7.8 Verify all Could Have features (9, 10) if implemented

    - [ ] T8.8 Build & Deployment Verification `[activity: deploy]`
        - [ ] T8.8.1 Run full test suite: `./test.sh`
        - [ ] T8.8.2 Run PHPStan: `./test.sh --stan`
        - [ ] T8.8.3 Build production CSS: `php userfrosting/conductor build-css --minify`
        - [ ] T8.8.4 Verify no new PHPStan baseline entries
        - [ ] T8.8.5 Documentation updated for new API endpoints

    - [ ] T8.9 Final Sign-Off
        - [ ] T8.9.1 All PRD Must Have features verified
        - [ ] T8.9.2 Implementation follows SDD architecture
        - [ ] T8.9.3 No known regressions
        - [ ] T8.9.4 Ready for production deployment

---

## Appendix: File Summary

### New Files (10 total)

| File | Phase | Purpose |
|------|-------|---------|
| `migrations/input/YYYYMMDD_schedule_panel_audit.json` | T1 | Add audit columns to workbook_punch_log |
| `templates/.../schedule-panel/schedule-panel.html` | T2 | Main panel template |
| `templates/.../schedule-panel/employee-avatar.html` | T2 | Avatar partial |
| `templates/.../schedule-panel/quick-action-modal.html` | T4 | Clock action modal |
| `templates/.../schedule-panel/schedule-modal.html` | T6 | Full schedule view |
| `css/workspace/schedule-panel.css` | T2 | Panel styles |
| `js/.../schedule-panel/SchedulePanel.js` | T3 | Main JS controller |
| `js/.../schedule-panel/QuickActionModal.js` | T4 | Modal controller |
| `js/.../schedule-panel/schedule-ably-sync.js` | T5 | Real-time sync |
| `js/.../schedule-panel/ScheduleModal.js` | T6 | Schedule modal controller |

### Modified Files (4 total)

| File | Phase | Changes |
|------|-------|---------|
| `TimePunchController.php` | T1 | Add `getSchedulePanelData()`, override endpoint |
| `routes/workbook/timepunch.php` | T1 | Add 2 new routes |
| `workspace-foot.html` | T2 | Include panel template conditionally |
| `workspace.css` | T2 | Add right sidebar CSS variables |

---

## Appendix: Testing Approach

### Backend Testing (Automated)

Backend tests use PHPUnit with the existing test infrastructure:

| Test Category | Location | Method |
|--------------|----------|--------|
| API: getSchedulePanelData() | `tests/Unit/Workbook/Controllers/TimePunchControllerTest.php` | PHPUnit |
| API: Override endpoint | `tests/Unit/Workbook/Controllers/TimePunchControllerTest.php` | PHPUnit |
| PIN verification | `tests/Unit/Workbook/Controllers/TimePunchControllerTest.php` | PHPUnit |
| Integration | `tests/Integration/Workbook/SchedulePanelIntegrationTest.php` | PHPUnit |

### Frontend Testing (Manual via Chrome DevTools MCP)

Frontend validation is performed manually using Chrome DevTools at https://dev2.buyerkiosk.com. The project does not have automated JS testing infrastructure.

| Test Category | Method | Notes |
|--------------|--------|-------|
| Employee sorting | Manual | Verify DOM order matches expected sort |
| localStorage persistence | Manual | Check Application > Local Storage in DevTools |
| Modal states | Manual | Test each employee status type |
| Ably events | Manual | Use Ably dashboard or trigger events from another tab |
| Real-time updates | Manual | Open two browser tabs, perform action in one |
| Performance | Manual | Use DevTools Performance/Network tabs |
| Responsive | Manual | Use DevTools device emulation |

**Why manual testing**: The codebase uses vanilla JavaScript without a test framework (Jest, Vitest, etc.). Adding a JS testing harness is out of scope for this feature.
