# Product Requirements Document

## Validation Checklist

- [x] All required sections are complete
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Problem statement is specific and measurable
- [x] Problem is validated by evidence (not assumptions)
- [x] Context -> Problem -> Solution flow makes sense
- [x] Every persona has at least one user journey
- [x] All MoSCoW categories addressed (Must/Should/Could/Won't)
- [x] Every feature has testable acceptance criteria
- [x] Every metric has corresponding tracking events
- [x] No feature redundancy (check for duplicates)
- [x] No contradictions between sections
- [x] No technical implementation details included
- [x] A new team member could understand this PRD

---

## Product Overview

### Vision

Empower retail store managers with a mobile-first scheduling command center that gives them instant visibility into team status, one-tap request approvals, and full shift management — all from a single app they already use daily for store operations.

### Problem Statement

Store managers currently have **no functional scheduling interface** in the BuyerKiosk Live mobile app despite the backend having 54+ scheduling API endpoints fully implemented and ready. The existing scheduling module was built speculatively against assumed API contracts and has never been validated against the actual backend. This means:

1. **Zero scheduling visibility on mobile**: Managers cannot see who's working, who's late, or who's absent from their phone — they must log into a desktop application or physically check the store.
2. **Time-off requests pile up**: Without mobile approval capability, pending time-off, shift swap, and clock override requests go unreviewed for hours or days, frustrating employees and creating scheduling gaps.
3. **Labor cost surprises**: Managers discover overtime and budget overruns after the pay period closes, not in real time while they can still adjust schedules.
4. **No shift management on the go**: Creating, editing, or deleting shifts requires desktop access, which is impractical for managers who spend most of their day on the store floor.
5. **Disconnected tools**: Managers already use BuyerKiosk Live for queues, notes, tasks, backstock, and metrics — but must switch to a separate tool for scheduling, breaking their workflow.

**Evidence**: The backend scheduling engine (50+ endpoints across 11 feature categories) was built and deployed because these needs were validated through customer requests. The API is production-ready but has zero mobile consumers.

### Value Proposition

BuyerKiosk Live becomes the **single app for everything store managers need** by integrating scheduling alongside existing store operations features. Managers get:

- **Instant team visibility**: See who's working, who's late, who's absent — at a glance
- **One-tap approvals**: Approve or deny time-off and shift swap requests from a push notification
- **Real-time labor tracking**: See labor costs and budget variance as the week unfolds
- **Full shift control**: Create, edit, delete, copy, and publish shifts from anywhere
- **No new app to learn**: Scheduling lives inside the same app managers use 10+ times daily

---

## User Personas

### Primary Persona: Store Manager (Maria)
- **Demographics**: 28-45 years old, retail store manager at a franchise location (Plato's Closet, Once Upon A Child, etc.), moderate technical expertise, uses iPhone or Android daily
- **Goals**:
  - Know at any moment who's scheduled, who's clocked in, and who's missing
  - Process pending requests quickly so employees aren't left waiting
  - Keep labor costs within weekly budget targets
  - Build and publish next week's schedule without sitting at a desktop
  - Handle scheduling emergencies (no-shows, call-outs) from the store floor
- **Pain Points**:
  - Currently switches between BuyerKiosk Live (store ops) and desktop tools (scheduling)
  - Pending requests accumulate because she can't approve from her phone
  - Discovers overtime issues after paychecks are processed, not in real time
  - Can't quickly find a replacement when someone calls out sick
  - Has to walk to the back office to check the schedule

### Secondary Persona: Multi-Store Owner (David)
- **Demographics**: 35-55 years old, owns 2-5 franchise locations, high business acumen, needs oversight across stores
- **Goals**:
  - Monitor labor costs and budget variance across all locations
  - Ensure adequate staffing at every store
  - Review and approve manager-escalated scheduling decisions
  - Spot attendance patterns (chronic tardiness, no-shows) across stores
- **Pain Points**:
  - No consolidated view of scheduling status across stores
  - Relies on individual managers to flag staffing issues
  - Labor cost data is only available after payroll processing
  - Can't verify that schedules are published on time
- **Feature Usage**: David uses the **exact same scheduling features** as Maria (no owner-exclusive screens). He differentiates by using the **store switcher** to check each store sequentially. His primary workflows are Dashboard review and Labor Cost monitoring across stores. He occasionally approves requests or publishes schedules when a store manager is unavailable.

---

## User Journey Maps

### Primary Journey: Daily Manager Check-In

1. **Trigger**: Maria arrives at the store and opens BuyerKiosk Live (or receives a push notification about a pending request)
2. **Dashboard glance**: She sees the scheduling dashboard — today's stats (8 scheduled, 6 clocked in, 1 late, 1 absent), 3 pending requests, and this week's labor at $3,200 of $4,400 budget
3. **Address urgency**: She taps the "1 Late" card to see who's late — it's Jake, 15 minutes late. She decides to wait (no action needed yet)
4. **Process requests**: She taps "3 Pending Requests" — sees 2 time-off requests and 1 shift swap. She approves the time-off for next week, denies one that conflicts with a busy weekend, and approves the swap
5. **Check labor**: She glances at labor costs — under budget by $200. Good. She notes Tuesday is heavy and considers adjusting next week
6. **Continue with store ops**: She switches to the Buy Queue tab to check customer flow — all from the same app

### Secondary Journey: Weekly Schedule Building

1. **Trigger**: It's Thursday and Maria needs to publish next week's schedule by end of day
2. **Copy previous week**: She opens the schedule view, navigates to next week, and copies last week's schedule as a template
3. **Review and adjust**: She sees 24 shifts copied. She edits 3 shifts to account for a staff member's approved time-off and adjusts hours for a new part-timer
4. **Create open shifts**: She creates 2 open shifts for Saturday coverage (no employee assigned)
5. **Check conflicts**: The app warns her about 1 conflict — an employee assigned to a shift during their unavailable hours. She reassigns the shift
6. **Publish**: She taps "Publish Schedule" — the app confirms 24 shifts published and 8 employees notified via push notification
7. **Verify**: She sees the schedule is marked as published with a green checkmark

### Tertiary Journey: Emergency Coverage

1. **Trigger**: Maria receives a push notification — "Override request: Sarah couldn't clock out (system issue)"
2. **Quick action**: She taps the notification, sees the override request details, and approves with a note "System issue confirmed"
3. **Check coverage**: She notices the "Who's Working" dashboard shows only 4 of 6 expected employees. Someone called out
4. **Find replacement**: She checks tomorrow's daily schedule to see who's available, then creates a new shift for an available team member
5. **Notify**: She sends a team notification "Extra coverage needed Saturday 2-6pm" to the team

### Multi-Store Journey: Owner Oversight

1. **Trigger**: David opens BuyerKiosk Live and switches between his 3 stores using the store switcher
2. **Per-store check**: For each store, he checks the scheduling dashboard — pending request counts, labor cost vs budget, attendance status
3. **Spot issues**: Store #2 has 5 pending requests (managers slow to approve) and is 10% over labor budget. He notes this for his weekly call
4. **Drill down**: He checks Store #2's labor cost breakdown — Tuesday and Wednesday are heavy. He reviews the daily schedule to understand why

---

## Feature Requirements

### Must Have Features

#### Feature 1: Manager Dashboard
- **User Story**: As a store manager, I want to see an at-a-glance summary of today's scheduling status so that I can immediately identify issues requiring my attention.
- **Acceptance Criteria**:
  - [ ] Shows today's stats: Scheduled count, Clocked In count, Late count, Absent count
  - [ ] Shows pending request summary: Total count with breakdown by type (Time-Off, Shift Swap, Override)
  - [ ] Shows this week's labor summary: Scheduled hours, labor cost, budget variance (if budget exists)
  - [ ] Each section is tappable to navigate to detailed view
  - [ ] Pull-to-refresh updates all sections
  - [ ] Displays store name and allows store switching for multi-store managers
  - [ ] Shows contextual empty/zero states: "No pending requests — all caught up!" for zero requests, "0" values in stats cards (not hidden), "No budget set" for null budget target

#### Feature 2: Pending Request Approval
- **User Story**: As a store manager, I want to review and approve or deny employee requests so that employees get timely responses and the schedule stays accurate.
- **Acceptance Criteria**:
  - [ ] Lists all pending requests (time-off, shift swaps, clock overrides) sorted by submission date
  - [ ] Filter by request type (All / Time-Off / Swap / Override) with count badges
  - [ ] Each request card shows: employee name, request type, key details (dates/shifts/times), submission time, urgency indicator
  - [ ] Tapping a request opens a detail view with full information
  - [ ] Approve and Deny buttons on detail view with optional note field
  - [ ] Denial note is optional (not required)
  - [ ] Confirmation feedback after action (success toast or error message)
  - [ ] Request disappears from pending list after processing
  - [ ] Handles already-processed requests gracefully (shows "already processed" if another manager acted)

#### Feature 3: Batch Request Processing
- **User Story**: As a store manager, I want to approve or deny multiple requests at once so that I can efficiently clear a backlog of pending requests.
- **Acceptance Criteria**:
  - [ ] Long-press on a request enters selection mode
  - [ ] Checkboxes appear on all request cards for selection
  - [ ] "Select All" and "Clear" buttons available
  - [ ] Maximum 10 requests per batch (enforced in UI with explanatory message)
  - [ ] Batch action bar shows selected count and Approve All / Deny All buttons
  - [ ] Optional note field for batch decisions
  - [ ] Partial success handling: if some fail, show which succeeded and which failed with reasons
  - [ ] Exit selection mode after batch action completes

#### Feature 4: Who's Working
- **User Story**: As a store manager, I want to see who is currently working, who's late, and who hasn't shown up so that I can manage real-time staffing.
- **Acceptance Criteria**:
  - [ ] Summary header showing: total scheduled today, clocked in, late, absent
  - [ ] Employee list grouped by status: Clocked In, Late, Scheduled (not yet arrived), On Leave, Clocked Out
  - [ ] Each employee tile shows: name, position, scheduled time, clock-in time (if clocked in), minutes late (if late)
  - [ ] Status color-coding: green (clocked in), orange/amber (late), blue (scheduled), gray (clocked out), purple (on leave)
  - [ ] Tapping an employee shows detail sheet with full shift info
  - [ ] Pull-to-refresh updates all statuses
  - [ ] Empty state for "No one scheduled today"

#### Feature 5: Weekly Schedule View
- **User Story**: As a store manager, I want to see the team schedule for any week so that I can understand staffing coverage and identify gaps.
- **Acceptance Criteria**:
  - [ ] Week navigation (previous/next week arrows with date range display)
  - [ ] Shows all shifts for the selected week organized by day
  - [ ] Each shift shows: employee name (or "Open Shift"), time range, position, position color
  - [ ] Published vs unpublished indicator for each week
  - [ ] Daily shift count summary (e.g., "8 shifts, 2 open")
  - [ ] Tapping a shift opens detail/edit view
  - [ ] Tapping a day header shows the daily schedule view for that date
  - [ ] Open shifts visually distinguished (dashed border or different style)

#### Feature 6: Labor Cost Tracking
- **User Story**: As a store manager, I want to see weekly labor costs and budget status so that I can control overtime and stay within budget.
- **Acceptance Criteria**:
  - [ ] Week navigation (previous/next with date range)
  - [ ] Summary cards: Total scheduled hours, Total labor cost
  - [ ] Budget section (if budget target exists): Budget variance (over/under), percentage of budget used, progress bar
  - [ ] Daily breakdown: Each day shows hours and cost
  - [ ] Visual chart showing daily hours across the week
  - [ ] Today's day highlighted in chart
  - [ ] "No budget set" message if budget target is null
  - [ ] Pull-to-refresh updates data

#### Feature 7: Shift CRUD (Create, Edit, Delete)
- **User Story**: As a store manager, I want to create, modify, and remove shifts so that I can build and adjust the weekly schedule.
- **Acceptance Criteria**:
  - [ ] Create shift form: date picker, start/end time pickers, employee picker (optional — null for open shift), position picker, notes field
  - [ ] Employee picker shows only employees assigned to this store
  - [ ] Edit shift: same form pre-populated with existing shift data
  - [ ] Delete shift: confirmation dialog with required reason note (audit trail)
  - [ ] Conflict warnings shown after creation/edit (non-blocking — shift is still created)
  - [ ] Shift detail view accessible from schedule view
  - [ ] Success feedback via SnackBar toast ("Shift created successfully"); error feedback via SnackBar with red background and retry action

#### Feature 8: Schedule Publishing
- **User Story**: As a store manager, I want to publish a week's schedule so that employees are notified and can see their shifts.
- **Acceptance Criteria**:
  - [ ] Publish button available on weekly schedule view (when schedule is unpublished)
  - [ ] Confirmation dialog showing: number of shifts to publish, number of employees to notify
  - [ ] After publishing: success SnackBar showing "Schedule published — X employees notified". Notification counts (push/SMS) shown in detail if backend provides them; omit SMS count if SMS not configured for the store
  - [ ] Published schedule shows visual indicator (badge or checkmark)
  - [ ] Cannot un-publish (one-way operation per the backend)

#### Feature 9: Clock Override (Manager)
- **User Story**: As a store manager, I want to manually create clock entries for employees so that I can correct system issues or handle special cases.
- **Acceptance Criteria**:
  - [ ] Override form: employee picker, type (Clock In / Clock Out), timestamp picker, required reason note
  - [ ] Confirmation dialog showing override details before submission
  - [ ] Success feedback with punch ID
  - [ ] Override visible in employee's punch history
  - [ ] Accessible from Who's Working screen or separate menu

#### Feature 10: Request History
- **User Story**: As a store manager, I want to see past request decisions so that I can review my approval history and reference previous decisions.
- **Acceptance Criteria**:
  - [ ] Lists approved and denied requests with decision date
  - [ ] Shows: employee name, request type, decision (approved/denied), manager who processed, decision date, manager note
  - [ ] Filter by status (Approved / Denied / All)
  - [ ] Sorted by most recent decision first
  - [ ] Scrollable list with sufficient history (at least 30 days)

### Should Have Features

#### Feature 11: Schedule Copy (Week Template)
- **User Story**: As a store manager, I want to copy a previous week's schedule to a new week so that I can quickly build recurring schedules.
- **Acceptance Criteria**:
  - [ ] "Copy Week" action available on weekly schedule view
  - [ ] Source week picker (defaults to current/previous week)
  - [ ] Target week picker
  - [ ] Confirmation showing: number of shifts to copy
  - [ ] Result showing: shifts copied, conflicts skipped (if any)
  - [ ] Copied shifts are in unpublished state (require explicit publish)

#### Feature 12: Daily Schedule View (Team Grid)
- **User Story**: As a store manager, I want to see all shifts for a specific day so that I can understand that day's complete staffing picture.
- **Acceptance Criteria**:
  - [ ] Date picker to select any date
  - [ ] Shows all shifts for selected date: employee name, time range, position, position color
  - [ ] Open shifts shown separately or visually distinguished
  - [ ] Summary: total shifts, assigned shifts, open shifts, unique employees
  - [ ] Tapping a shift opens detail/edit view

#### Feature 13: Employee Schedule View
- **User Story**: As a store manager, I want to view an individual employee's schedule so that I can understand their hours and availability.
- **Acceptance Criteria**:
  - [ ] Employee picker to select team member
  - [ ] Shows employee's shifts for current/selected week
  - [ ] Total hours for the week
  - [ ] Pending time-off shown alongside schedule
  - [ ] Navigation to previous/next weeks

#### Feature 14: Notification Preferences
- **User Story**: As a store manager, I want to control which scheduling notifications I receive so that I get alerted about important events without being overwhelmed.
- **Acceptance Criteria**:
  - [ ] Shows all notification categories: Schedule Published, Shift Changes, Request Approvals, Swap Requests, Shift Reminders
  - [ ] Toggle per category per channel: Push, SMS, Email
  - [ ] Changes saved immediately on toggle (optimistic UI with rollback on failure)
  - [ ] "Reset to Defaults" option with confirmation dialog
  - [ ] Current preference state clearly shown (on/off for each toggle)
  - [ ] Preferences are **per-user per-store** — switching stores loads that store's preferences
  - [ ] Managers can only edit their own notification preferences (not other managers' or employees')

### Could Have Features

#### Feature 15: Team Notifications
- **User Story**: As a store manager, I want to send a notification to my team or specific employees so that I can communicate schedule changes or urgent coverage needs.
- **Acceptance Criteria**:
  - [ ] Target selection: All team, specific employees, or shift-specific
  - [ ] Template options: Schedule Change, Urgent Coverage, Meeting Reminder, Custom
  - [ ] Custom message field for custom template
  - [ ] Confirmation showing recipient count before sending
  - [ ] Delivery summary after sending (push/SMS counts)

#### Feature 16: Open Shift Management
- **User Story**: As a store manager, I want to create open shifts that employees can claim so that I can fill coverage gaps without assigning specific people.
- **Acceptance Criteria**:
  - [ ] Create open shift (shift with no employee assigned)
  - [ ] View list of unclaimed open shifts
  - [ ] See when an employee claims an open shift (notification)
  - [ ] Convert open shift to assigned shift if needed

### Won't Have (This Phase)

- **Auto-scheduling / AI schedule building**: Requires complex availability matching algorithms and demand forecasting — deferred to future phase
- **Drag-and-drop schedule editing**: Complex gesture handling on mobile adds risk; standard form-based editing is more reliable
- **Offline schedule editing**: Backend requires real-time conflict checking; offline mutations introduce sync complexity
- **Employee self-service features**: Clock in/out, time-off submission, availability setting, shift swap initiation — these are employee-facing features for a separate Team App, not the Manager app
- **Payroll integration**: Out of scope for scheduling module
- **Break management**: Backend supports breaks but the UX complexity is deferred
- **Compliance checking**: Labor law compliance (min rest between shifts, max weekly hours) is deferred

---

## Detailed Feature Specifications

### Feature: Pending Request Approval (Most Complex)

**Description**: The request approval workflow is the highest-frequency manager action in the scheduling module. Managers receive push notifications about new requests and need to quickly review context (employee, dates, conflicts) and make approve/deny decisions, often in batches during morning check-in.

**User Flow**:
1. Manager sees "3 Pending Requests" on dashboard (or receives push notification)
2. Taps to open pending requests list
3. Sees 3 requests sorted by submission date, filtered to "All" by default
4. Taps first request (time-off for vacation, Feb 25-28)
5. Detail sheet opens showing: employee name, request type badge, dates, day count, reason, submitted time
6. Manager taps "Approve" — optional note field appears briefly
7. Manager confirms — success toast, request animates off list
8. For the remaining 2 requests (same type), manager long-presses to enter batch mode
9. Selects both, taps "Approve All" in batch bar
10. Confirms batch — both processed, batch bar dismisses

**Business Rules**:
- Rule 1: Requests sorted by submission date (oldest first) — ensures FIFO processing
- Rule 2: Only one decision per request — if another manager processes it first, show "Already processed" feedback
- Rule 3: Batch operations limited to 10 requests maximum — backend constraint for server-side transaction safety
- Rule 4: Partial batch failure is possible — some requests may fail (expired, already processed) while others succeed. UI must show which succeeded and which failed
- Rule 5: Denial note is optional — manager can deny without explanation, but UI should encourage a note
- Rule 6: Approved time-off blocks future shift assignment — backend enforces this, app doesn't need to
- Rule 7: Override approvals create a punch record immediately — the approval itself is the clock action
- Rule 8: Swap requests follow a 3-step flow (employee proposes -> coworker accepts -> manager approves) — manager only sees requests in "pending_manager" state

**Edge Cases**:
- Scenario 1: Manager opens request that was just approved by another manager -> Expected: Show "This request has already been processed" message with the decision details
- Scenario 2: Network fails during batch approve -> Expected: Show partial results — which succeeded, which failed, offer retry for failed ones
- Scenario 3: Request expires while manager is viewing detail -> Expected: Show "This request has expired" when they try to act on it
- Scenario 4: Manager denies and immediately regrets -> Expected: No undo available (server-side action is final). Manager must coordinate with employee offline
- Scenario 5: 50+ pending requests accumulated -> Expected: List loads all requests (no pagination in initial build); list must render at 60fps during scrolling. If performance degrades with 100+ items, implement lazy loading as a follow-up

### Feature: Weekly Schedule View

**Description**: The schedule view is the manager's primary tool for understanding team coverage. It shows all shifts for a week, organized by day, with visual indicators for published status, open shifts, and shift counts.

**User Flow**:
1. Manager opens schedule from dashboard or bottom nav
2. Sees current week with 7 day sections
3. Each day shows shift cards: employee name, time, position (color-coded)
4. Open shifts shown with dashed styling and "Open Shift" label
5. Navigates to next week using arrow button
6. Sees "Unpublished" banner — schedule exists but hasn't been published
7. Taps "Publish" button — confirmation dialog shows 24 shifts, 8 employees
8. Confirms — success feedback with notification delivery counts

**Business Rules**:
- Rule 1: Default view is current week (Monday to Sunday)
- Rule 2: Published schedules show green "Published" indicator; unpublished show amber "Draft" indicator
- Rule 3: Open shifts (no employee assigned) are visually distinct from assigned shifts
- Rule 4: Tapping a shift navigates to edit form
- Rule 5: Creating a new shift from schedule view pre-fills the date from the selected day
- Rule 6: Week navigation has no limit (can view past and future weeks)
- Rule 7: Shift position colors come from the backend (hex codes) — must render faithfully

**Edge Cases**:
- Scenario 1: Week has no shifts -> Expected: Show "No shifts scheduled" with "Create First Shift" call to action
- Scenario 2: Manager publishes then realizes a mistake -> Expected: Publishing is one-way per the backend; edits to individual shifts are still possible after publishing
- Scenario 3: Backend returns shifts without position colors -> Expected: Use a default color (primary) as fallback

### Feature: Clock Override

**Description**: Managers need to manually create clock entries when the normal clock-in/out process fails (system outage, employee forgot phone, etc.). Every override requires an explanation note for the audit trail.

**User Flow**:
1. Manager sees "1 Override Request" in pending requests (employee requested manual override)
2. OR manager initiates override from Who's Working screen (employee is late, needs manual clock-in)
3. Override form shows: employee picker, punch type (Clock In / Clock Out), timestamp, reason field
4. Manager fills in details and confirms
5. Success — punch record created with audit trail showing manager, device, timestamp, reason

**Business Rules**:
- Rule 1: Reason note is REQUIRED for all overrides (audit trail compliance)
- Rule 2: Override creates a real punch record (appears in employee's time sheet)
- Rule 3: Timestamp defaults to current time but can be adjusted to past (e.g., "should have clocked in at 9:00")
- Rule 4: Only managers can create overrides — access check enforced both client and server side

**Edge Cases**:
- Scenario 1: Manager tries to override for employee at another store -> Expected: Employee picker only shows employees for current store
- Scenario 2: Duplicate override (employee already clocked in) -> Expected: Backend returns 409 ALREADY_CLOCKED_IN error, shown as user-friendly message

---

## Success Metrics

### Key Performance Indicators

- **Adoption**: 80% of store managers use the scheduling module within 30 days of release (measured by at least 1 scheduling screen view per week). **Baseline**: 0% (no mobile scheduling exists today). **Aggregation**: Weekly active users / total managers.
- **Engagement**: Average manager processes pending requests within 4 hours of submission (measured by time between request submission and decision). **Baseline**: ~18 hours (industry average without mobile tools, per market research). **Aggregation**: Monthly average across all stores.
- **Efficiency**: 60% of request approvals happen via batch processing (measured by batch vs single approve actions). **Baseline**: 0% (no batch capability exists). **Aggregation**: Monthly ratio.
- **Quality**: <2% error rate on scheduling operations (measured by API error responses / total API calls, excluding 401s which trigger token refresh). **Baseline**: N/A (new system). **Aggregation**: Weekly rolling.
- **Business Impact**: 90% of schedules published on time (by Thursday for the following week, measured by publish action timestamp). **Baseline**: Unknown (not tracked today). **Aggregation**: Weekly per store.

### Tracking Requirements

| Event | Properties | Purpose |
|-------|------------|---------|
| `scheduling.dashboard.viewed` | `typeNum`, `pendingCount`, `clockedInCount`, `lateCount` | Track dashboard usage frequency and state when viewed |
| `scheduling.request.viewed` | `typeNum`, `requestId`, `requestType` | Track which requests managers inspect |
| `scheduling.request.approved` | `typeNum`, `requestId`, `requestType`, `hasNote`, `isBatch`, `batchSize` | Measure approval patterns and batch usage |
| `scheduling.request.denied` | `typeNum`, `requestId`, `requestType`, `hasNote`, `isBatch`, `batchSize` | Measure denial patterns and note usage |
| `scheduling.request.latency` | `typeNum`, `requestId`, `secondsSinceSubmission` | Measure time-to-decision |
| `scheduling.whos_working.viewed` | `typeNum`, `scheduledCount`, `clockedInCount`, `lateCount` | Track real-time status monitoring |
| `scheduling.schedule.viewed` | `typeNum`, `weekOffset`, `isPublished`, `shiftCount` | Track schedule review frequency |
| `scheduling.schedule.published` | `typeNum`, `shiftCount`, `employeeCount` | Track publish timeliness |
| `scheduling.shift.created` | `typeNum`, `isOpenShift`, `hasConflicts` | Track shift creation patterns |
| `scheduling.shift.edited` | `typeNum`, `shiftId`, `fieldsChanged` | Track edit frequency |
| `scheduling.shift.deleted` | `typeNum`, `shiftId` | Track deletion frequency |
| `scheduling.labor.viewed` | `typeNum`, `weekOffset`, `hasBudget`, `isOverBudget` | Track labor cost monitoring |
| `scheduling.override.created` | `typeNum`, `punchType` | Track override frequency |
| `scheduling.schedule.copied` | `typeNum`, `shiftsCopied`, `conflictsSkipped` | Track template usage |
| `scheduling.notification.sent` | `typeNum`, `template`, `recipientCount` | Track team communication |
| `scheduling.error` | `typeNum`, `endpoint`, `errorCode`, `errorMessage` | Track error patterns |

---

## Constraints and Assumptions

### Constraints
- **Backend is fixed**: All 54+ API endpoints are production-ready and cannot be modified for this phase. The Flutter app must adapt to the existing API contracts
- **All endpoints use POST**: Even read operations use POST method with JSON body (backend convention)
- **JWT authentication**: Uses the main app's unified auth tokens (Spec 003). No separate scheduling login
- **Manager-only access**: Scheduling features are restricted to users with `roleId <= 2` (Owner or Manager)
- **Geofence not needed**: Clock override (manager action) doesn't require GPS. Normal clock in/out is employee-only and out of scope
- **Maximum batch size**: 10 requests per batch (backend enforced)
- **No offline support**: All operations require network connectivity
- **Push notification infrastructure**: Already exists via Ably + FCM. Scheduling push notifications are backend-triggered
- **Platform**: iOS and Android via Flutter

### Assumptions
- **Managers have internet**: Retail stores have WiFi or cellular coverage sufficient for API calls
- **Managers check the app multiple times daily**: Based on existing usage patterns for queue/notes/metrics features
- **Backend responses are fast**: API response times under 2 seconds for all scheduling endpoints
- **Store timezone handling**: Backend returns all times in store timezone; app displays as-is without conversion
- **Employee data is available**: Backend provides employee lists, names, and photos via existing endpoints
- **Position colors are hex codes**: Backend returns position colors as hex strings (e.g., "#4CAF50")
- **Budget targets may not exist**: Some stores don't have labor budget configured — UI handles null gracefully

---

## Permissions Matrix

Both Owners (roleId=1) and Managers (roleId=2) have access to all scheduling features. There is no per-action differentiation between Owner and Manager within the scheduling module — the backend enforces `roleId <= 2` uniformly across all manager endpoints.

| Action | Owner (1) | Manager (2) | Shift Lead (3) | Employee (4) |
|--------|-----------|-------------|-----------------|--------------|
| View Dashboard | Yes | Yes | No | No |
| View Who's Working | Yes | Yes | No | No |
| Approve/Deny Requests | Yes | Yes | No | No |
| Batch Process Requests | Yes | Yes | No | No |
| View Weekly Schedule | Yes | Yes | No | No |
| View Daily Schedule | Yes | Yes | No | No |
| View Employee Schedule | Yes | Yes | No | No |
| View Labor Costs | Yes | Yes | No | No |
| Create/Edit/Delete Shifts | Yes | Yes | No | No |
| Publish Schedule | Yes | Yes | No | No |
| Copy Week Schedule | Yes | Yes | No | No |
| Clock Override | Yes | Yes | No | No |
| View Request History | Yes | Yes | No | No |
| Manage Notification Prefs | Yes | Yes | No | No |
| Send Team Notifications | Yes | Yes | No | No |
| Access Schedule Tab (Nav) | Yes | Yes | No | No |

**Note**: The multi-store owner persona (David) uses the same features as a single-store manager, but switches between stores via the store switcher. There are no owner-exclusive features in this phase.

---

## Dependencies

### API Documentation
- **Primary**: Backend API documentation at `../buyerkiosk-team/docs/backend-api-updates.md` — canonical source for all 54+ endpoint contracts
- **OpenAPI Spec**: `docs/api/mobile-scheduling-openapi.yaml` — structured endpoint reference
- **Owner**: Backend team (buyerkiosk-web repository)

### API Endpoint-to-Feature Mapping

| Feature | Endpoints Used |
|---------|---------------|
| F1: Dashboard | `POST /{typeNum}/manager/dashboard` |
| F2: Request Approval | `POST /{typeNum}/manager/requests`, `POST /{typeNum}/manager/requests/{id}/decision` |
| F3: Batch Processing | `POST /{typeNum}/manager/requests/batch` |
| F4: Who's Working | `POST /{typeNum}/manager/whos-working` |
| F5: Weekly Schedule | `POST /{typeNum}/schedule/weekly`, `POST /{typeNum}/schedule/daily` |
| F6: Labor Cost | `POST /{typeNum}/manager/labor-cost` |
| F7: Shift CRUD | `POST /{typeNum}/manager/shifts/create`, `POST /{typeNum}/manager/shifts/{id}/update`, `POST /{typeNum}/manager/shifts/{id}/delete` |
| F8: Publish Schedule | `POST /{typeNum}/manager/schedule/publish` |
| F9: Clock Override | `POST /{typeNum}/manager/clock/override` |
| F10: Request History | `POST /{typeNum}/manager/requests` (with status filter) |
| F11: Copy Week | `POST /{typeNum}/manager/schedule/copy-week` |
| F12: Daily Schedule | `POST /{typeNum}/schedule/daily` |
| F13: Employee Schedule | `POST /{typeNum}/schedule` (with employee filter), employee list endpoint |
| F14: Notification Prefs | `POST /{typeNum}/notifications/preferences`, `POST /{typeNum}/notifications/preferences/update`, `POST /{typeNum}/notifications/preferences/update-batch`, `POST /{typeNum}/notifications/preferences/reset`, `POST /{typeNum}/notifications/categories` |
| F15: Team Notifications | `POST /{typeNum}/manager/notify` |
| F16: Open Shifts | `POST /{typeNum}/open-shifts`, shift create with null employeeId |

### Authentication
- **Dependency**: Unified JWT auth system (Spec 003) — provides access tokens for all scheduling API calls
- **Integration point**: `SchedulingContextProvider` bridges main auth state to scheduling module
- **Token lifecycle**: 15-minute access token with proactive refresh at 5 minutes remaining

### Analytics Pipeline
- **Destination**: Existing app analytics infrastructure (same as queue/notes/metrics analytics)
- **Event schema**: All events prefixed with `scheduling.` to namespace within existing pipeline
- **Properties**: Standard properties (`typeNum`, `timestamp`) plus feature-specific properties per tracking table above

### Push Notifications
- **Infrastructure**: Ably + Firebase Cloud Messaging (already configured for the app)
- **Payload format**: Backend sends scheduling notifications in standard FCM format with `data.type` field for routing
- **Scheduling notification types**: `scheduling:request_submitted`, `scheduling:request_decided`, `scheduling:schedule_published`, `scheduling:shift_changed`
- **Deep link handling**: Push tap navigates to relevant scheduling screen based on `data.type` and `data.typeNum`

### Design System
- **Style guide**: `STYLE_GUIDE.md` — color tokens, typography, spacing, border radius
- **Theme**: `AppColors`, `AppTheme` from `lib/core/theme/`
- **Components**: Existing common widgets (ErrorDisplay, LoadingIndicator, EmptyState, MetricCard)

### Store Navigation
- **Integration**: Schedule tab in bottom navigation bar (NavigationCategory from Spec 005)
- **Tab visibility**: Controlled by `hasSchedulingAccess` flag per store

---

## Additional Edge Cases

### Shift CRUD Edge Cases
- **Overnight shifts** (e.g., 10 PM - 6 AM): Backend handles cross-midnight shifts; app must display correctly with date context (e.g., "Feb 19 10:00 PM - Feb 20 6:00 AM")
- **Overlapping shifts for same employee**: Backend returns conflict warning (non-blocking); app shows warning but allows creation. Manager decides if intended (e.g., split shift)
- **End time before start time**: Form validation prevents submission; show inline error "End time must be after start time"
- **Daylight savings transitions**: Backend stores times in store timezone; during DST transitions, some shifts may appear 1 hour shorter/longer. App displays as received — no client-side adjustment
- **Shift with no position**: If position is optional and omitted, display shift without color coding; use default primary color

### Copy Week Edge Cases
- **Target week already has shifts**: Backend handles merge behavior — copies into the target, skipping conflicts. Result shows `conflictsSkipped` count. App shows "X shifts copied, Y skipped due to conflicts"
- **Copy from empty week**: Backend returns `shiftsCopied: 0`. App shows "No shifts to copy from that week"
- **Copy from published to unpublished**: Copied shifts are always unpublished regardless of source state

### Publish Edge Cases
- **Publish with conflicts existing**: Publishing proceeds regardless of conflicts. Conflicts are warnings, not blockers. App shows publish success even if unresolved conflicts exist
- **Publish empty week**: Backend may return error or publish 0 shifts. App should prevent publishing if `shiftCount == 0` with message "No shifts to publish"
- **Already published week**: Publish button hidden for already-published weeks. If user somehow triggers publish on published week, backend returns appropriate response

### Labor Cost Edge Cases
- **Missing wage data**: Some employees may not have hourly rates configured. Backend returns labor cost based on available data; missing rates show as $0. App displays totals as-is
- **Mixed hourly rates**: Different positions/employees have different rates. Daily breakdown reflects aggregate cost per day
- **No shifts scheduled for a week**: Show "No shifts scheduled" with $0 labor cost and empty chart
- **Budget variance is null**: Show "No budget target set" instead of variance section

### Notification Preferences Edge Cases
- **SMS not configured for store**: Channel toggle for SMS still shown but backend may silently ignore. App treats toggles as user preference regardless of store configuration
- **Preferences are per-user per-store**: Each store can have different preference settings for the same user. Preferences load when store context changes

---

## Risks and Mitigations

| Risk | Impact | Likelihood | Mitigation |
|------|--------|------------|------------|
| Backend API response format differs from documentation | High | Medium | Build comprehensive integration tests; add defensive JSON parsing with fallbacks |
| Managers don't discover scheduling features | Medium | Medium | Badge counts on Schedule tab; push notifications drive engagement; onboarding prompt |
| Batch operations fail partially | Medium | Low | UI shows per-request results; failed requests remain actionable; retry mechanism |
| High pending request volume (100+) | Medium | Low | Implement virtual scrolling if performance degrades; consider future pagination |
| Push notification delays cause stale dashboard | Medium | Low | Pull-to-refresh on all screens; auto-refresh on return to foreground |
| Store timezone handling errors | High | Low | Display times as received from backend; never convert client-side |
| Concurrent manager actions (two managers approve same request) | Medium | Medium | Handle 409 (already processed) gracefully; show "processed by [name]" feedback |
| Complex shift form overwhelms managers on mobile | Medium | Low | Progressive disclosure; required fields first, optional fields expandable |

---

## Open Questions

- [x] ~~Should denial notes be required or optional?~~ **Decision: Optional** — Backend accepts both; forcing notes would slow down the workflow
- [x] ~~What is the maximum batch size?~~ **Decision: 10** — Backend enforces this limit
- [x] ~~Should we support employee self-service features (clock in/out, request submission)?~~ **Decision: No** — This is a Manager app; employee features belong in the Team App
- [x] ~~How far back should request history go?~~ **Decision: Backend returns available history** — No client-side date filtering needed initially
- [x] ~~Should schedule view support month/day toggles?~~ **Decision: Week view primary, day view secondary** — Month view deferred for complexity
- [x] ~~What happens when a store doesn't have the scheduling module enabled?~~ **Decision: Graceful degradation** — Schedule tab hidden from bottom nav when `hasSchedulingAccess` is false for the store. If user deep-links to a scheduling route for a non-enabled store, redirect to "Scheduling not available for this store" screen with a back button. The `hasSchedulingAccess` flag is derived from the store's feature configuration returned at login (via `stores[].hasSchedulingAccess` or role-based check `roleId <= 2`)

---

## Supporting Research

### Competitive Analysis

Leading retail scheduling platforms (HotSchedules/Fourth, Homebase, When I Work, Deputy, Sling, 7shifts) were analyzed. Key findings:

- **Mobile-first is table stakes**: All competitors offer full scheduling functionality on mobile. Managers expect to manage schedules from their phone
- **"Who's Working" is a hero feature**: Top apps prominently display real-time staffing status as the first thing managers see. Card-based layouts with color-coded status indicators (green = clocked in, orange = late, red = absent) are the standard
- **Time-off approval speed matters**: Competitors optimize for one-tap approvals from push notifications. Average target: decisions within 4 hours of submission
- **Week view dominates**: Week view is the primary schedule visualization across all platforms. Day view for detail, month view for planning (deferred here)
- **Batch operations differentiate**: Mid-tier and above platforms support batch approve/deny for efficiency during morning check-in routines
- **Labor cost visibility drives value**: Real-time budget tracking (not just after-the-fact reporting) is a premium feature that managers consistently cite as their top need
- **Color coding reduces cognitive load**: Position colors, status colors, and urgency indicators are universal patterns that managers learn quickly

### User Research

Based on existing BuyerKiosk Live usage patterns:
- Managers open the app 10-15 times per day for queue monitoring, notes, and metrics
- Peak usage: 8-10 AM (morning check-in) and 4-6 PM (end-of-day review)
- Average session duration: 2-3 minutes (quick glance, take action, move on)
- Store managers strongly prefer single-app solutions over tool-switching
- Multi-store owners check each store sequentially using the store switcher

### Market Data

- Retail workforce scheduling software market is projected to reach $4.8B by 2027 (CAGR 14.2%)
- 73% of retail managers cite "mobile schedule access" as their top technology need
- Time-off request processing time averages 18 hours without mobile tools vs 3 hours with mobile approval capability
- Stores using mobile scheduling tools report 23% reduction in scheduling-related labor cost overruns
