# 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 statement is based on reasonable business assumptions and existing app usage patterns
- [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
Enable store managers and owners to review daily close reports directly from their mobile devices, providing instant access to end-of-day financial performance data and enabling trend analysis through report comparison.

### Problem Statement
Store managers currently lack mobile access to their daily close reports. When closing numbers are posted each night, managers must wait until they can access a desktop computer to review the day's financial performance. This delay means:
- Managers cannot review close reports while commuting or during off-hours
- Critical discrepancies (cash shortages, goal misses) may not be identified until the next business day
- Week-over-week or day-over-day performance comparisons require manual calculation
- Franchise owners managing multiple stores cannot efficiently review all stores' daily performance

The backend API for close reports is now complete (5 endpoints documented in `docs/backend-api-updates.md`), creating an immediate opportunity for frontend implementation.

### Value Proposition
The Close Reports feature brings end-of-day financial visibility to managers' fingertips by:
- **Immediate access**: View close reports as soon as they're posted, from anywhere
- **Historical navigation**: Browse past reports using an intuitive calendar interface
- **Comparative insights**: See side-by-side comparisons with automatic variance highlighting
- **Seamless integration**: Access close reports directly from the existing store detail screen

## User Personas

### Primary Persona: Store Manager (Emily)
- **Demographics:** 28-45 years old, manages daily store operations, moderate technical proficiency, uses smartphone daily for personal and work tasks
- **Goals:** Ensure daily financial targets are met, identify performance trends, quickly spot and address discrepancies, provide accurate reporting to franchise owner
- **Pain Points:** Cannot check close reports until at a computer, manual comparison between days is tedious, no mobile alerts when reports are posted, has to remember to check reports rather than being notified

### Secondary Persona: Franchise Owner (Marcus)
- **Demographics:** 40-60 years old, owns 2-8 stores, limited time for daily operations, high business acumen, relies on mobile for multi-store oversight
- **Goals:** Monitor financial health across all locations, identify underperforming stores quickly, track labor efficiency trends, make data-driven decisions about store operations
- **Pain Points:** Must check each store individually on desktop, no consolidated view of multi-store performance, critical variances buried in detailed reports, time-consuming to compare stores' performance

### Tertiary Persona: Shift Lead (Jordan)
- **Demographics:** 22-35 years old, aspiring manager, comfortable with mobile apps, wants to understand business metrics
- **Goals:** Learn how daily operations translate to financial results, understand what makes a "good" day, prepare for management responsibilities
- **Pain Points:** Limited visibility into how their shift contributes to overall results, no context for what numbers mean (good vs. bad)

## User Journey Maps

### Primary User Journey: Daily Report Review (Emily)
1. **Trigger:** Emily opens the app the next morning to check yesterday's close
2. **Navigation:** From the store detail screen, Emily taps "Close Reports" in the Quick Actions section
3. **Initial View:** The Close Reports screen opens showing the latest report summary - key metrics at a glance (net sales, buys, labor %)
4. **Deep Dive:** Emily taps to expand sections for detailed breakdowns - sales summary, buy details, returns, labor costs
5. **Comparison:** If she notices concerning numbers, Emily taps "Compare" to view against yesterday or last week
6. **Action:** Variance highlights show her exactly where performance differed, helping her identify what to address today
7. **Completion:** Emily closes the app with a clear understanding of yesterday's performance and what needs attention

### Secondary User Journey: Historical Analysis (Marcus)
1. **Trigger:** Marcus wants to review this week's close reports for all stores during his Sunday planning session
2. **Navigation:** Marcus opens each store and navigates to Close Reports
3. **Calendar Access:** He taps the calendar icon to select specific dates, seeing which days have reports available
4. **Date Selection:** Marcus selects Monday's report, then uses "Compare" to compare against the previous Monday
5. **Pattern Recognition:** The variance highlights reveal consistent patterns - labor percentage trending up
6. **Multi-Store:** Marcus repeats for other stores, building a mental picture of weekly performance trends
7. **Planning:** Armed with comparative data, Marcus plans next week's staffing adjustments

### Tertiary User Journey: Learning Mode (Jordan)
1. **Trigger:** Jordan's manager mentions "we had a great close last night" and Jordan wants to understand why
2. **Navigation:** With appropriate permissions, Jordan accesses Close Reports from store detail
3. **Exploration:** Jordan views the latest report, examining each metric
4. **Context Building:** The report shows sales at 115% of goal - Jordan learns this is "great"
5. **Comparison:** Jordan compares to an average day to understand the difference
6. **Growth:** Over time, Jordan builds intuition for what numbers indicate healthy store performance

### Franchise Owner Journey: Multi-Store Morning Review (Marcus)
1. **Trigger:** Marcus starts his morning coffee and wants to review all stores' performance from yesterday
2. **Navigation:** Marcus opens the dashboard and selects his first store, then navigates to Close Reports
3. **Quick Assessment:** The latest report loads immediately with key metrics visible - Marcus notes net sales and labor %
4. **Discrepancy Check:** Marcus sees a discrepancy indicator on this store and taps to view details
5. **Store Switching:** Marcus uses back navigation to return to dashboard and selects the next store
6. **Pattern Recognition:** After reviewing 4 stores, Marcus identifies that Store 3 consistently has higher labor %
7. **Action Planning:** Marcus makes a note to discuss staffing efficiency with Store 3's manager

### Shift Lead Journey: Post-Shift Learning (Jordan)
1. **Trigger:** Jordan finished a busy shift and wants to see how the day's numbers looked
2. **Navigation:** Jordan opens the app and navigates to Close Reports from store detail
3. **Permission Check:** Jordan's Shift Lead access grants read-only access to close reports
4. **Metric Review:** Jordan views net sales and sees the store hit 108% of goal
5. **Personal Context:** Jordan recalls the busy afternoon rush and connects it to the numbers
6. **Learning:** Jordan starts to understand the relationship between floor activity and financial results

## Feature Requirements

### Must Have Features

#### Feature 1: View Latest Close Report
- **User Story:** As a store manager, I want to view the most recent close report so that I can quickly assess yesterday's financial performance.
- **Acceptance Criteria:**
  - [ ] Close Reports screen displays the latest report immediately upon opening
  - [ ] Report displays key summary metrics: net sales, sales vs. goal %, buys count, buys total, labor %, discrepancy flag
  - [ ] Detail sections are expandable: Sales Summary, Buys, Returns, Labor
  - [ ] Monetary values display in dollars (converted from cents returned by API)
  - [ ] Report date and posted timestamp are clearly visible
  - [ ] Loading state shows while fetching report
  - [ ] Error state shows if report fetch fails with retry option
  - [ ] Empty state shows if no reports exist for the store

#### Feature 2: Navigate Close Reports by Date
- **User Story:** As a store manager, I want to view close reports from previous days so that I can review historical performance.
- **Acceptance Criteria:**
  - [ ] Date picker allows selection of any date with an available report
  - [ ] Calendar view indicates which dates have reports available (highlighted/dotted)
  - [ ] Selecting a date loads that day's report
  - [ ] User cannot select dates without reports (disabled dates)
  - [ ] Calendar defaults to current month, can navigate to previous months
  - [ ] Previously viewed date is remembered during session
  - [ ] Loading indicator displayed during navigation, toast notification on error

#### Feature 3: List Recent Reports
- **User Story:** As a store manager, I want to see a list of recent close reports so that I can quickly navigate to any recent day.
- **Acceptance Criteria:**
  - [ ] List view shows recent reports with key metrics (date, net sales, sales %)
  - [ ] List is paginated, loading more reports on scroll
  - [ ] Each list item shows: report date, net sales, sales vs. goal %, discrepancy indicator
  - [ ] Tapping a list item opens the full report detail
  - [ ] Pull-to-refresh reloads the list
  - [ ] Visual indicator for reports with discrepancies

#### Feature 4: Compare Two Reports
- **User Story:** As a store manager, I want to compare two close reports side-by-side so that I can understand performance trends and variances.
- **Acceptance Criteria:**
  - [ ] "Compare" action available from report detail view
  - [ ] User can select a comparison date from calendar
  - [ ] Comparison view shows primary and comparison report metrics side-by-side
  - [ ] Delta values displayed (difference between reports)
  - [ ] Percentage changes displayed for key metrics
  - [ ] Variance highlights flag significant changes (>10% warning, >25% critical)
  - [ ] Clear labels indicating which report is primary vs. comparison
  - [ ] Quick comparison shortcuts: "vs. Yesterday", "vs. Last Week"

#### Feature 5: Navigation Integration
- **User Story:** As a store manager, I want to access Close Reports from the store detail screen so that I can easily navigate to this feature.
- **Acceptance Criteria:**
  - [ ] "Close Reports" action button appears in Quick Actions section of store detail
  - [ ] Button shows appropriate icon (document/chart icon)
  - [ ] Navigation follows existing app patterns (go_router)
  - [ ] Back navigation returns to store detail screen
  - [ ] Store name and typeNum carry through to Close Reports screen

### Should Have Features

#### Feature 6: Report Section Expansion/Collapse
- **User Story:** As a store manager, I want to expand and collapse report sections so that I can focus on the metrics that matter most to me.
- **Acceptance Criteria:**
  - [ ] Each report section (Sales, Buys, Returns, Labor) is collapsible
  - [ ] Section expansion state persists within the session
  - [ ] Clear visual indicator of expanded vs. collapsed state
  - [ ] Animation duration 200-300ms using standard Material easing curves when expanding/collapsing

#### Feature 7: Discrepancy Highlighting
- **User Story:** As a store manager, I want discrepancies prominently highlighted so that I can immediately identify days that need attention.
- **Acceptance Criteria:**
  - [ ] Reports with discrepancies show warning icon and amber background color in header area
  - [ ] In list view, discrepancy indicator icon and badge shown in list item
  - [ ] In detail view, discrepancy status displayed in header with warning icon and "Cash Discrepancy" label
- **API Limitation:** The backend API only provides a boolean `hasDiscrepancy` field. Discrepancy type details (cash over/short, amount) are not available in the current API. The UI displays a generic "Cash Discrepancy" label when `hasDiscrepancy: true`.

### Could Have Features

#### Feature 8: Performance Trend Indicators
- **User Story:** As a store manager, I want to see trend indicators so that I can quickly assess if performance is improving or declining.
- **Acceptance Criteria:**
  - [ ] Arrow indicators (up/down) show trend vs. recent average
  - [ ] Color coding: green for positive trends, red for negative
  - [ ] Trend based on 7-day rolling average comparison

#### Feature 9: Quick Date Navigation
- **User Story:** As a store manager, I want quick-access buttons for common date selections so that I can navigate faster.
- **Acceptance Criteria:**
  - [ ] "Today" button jumps to most recent report
  - [ ] "Yesterday" button for quick access
  - [ ] "Last Week" shows same day last week
  - [ ] Swipe gestures for next/previous day navigation

### Won't Have (This Phase)

- **Multi-store consolidated view**: Viewing all stores' reports in a single dashboard (future phase)
- **Push notifications for new reports**: Alerting when new reports are posted (requires backend push integration)
- **Export/share functionality**: Exporting reports as PDF or sharing via email
- **Custom comparison periods**: Comparing against custom date ranges or averages
- **Annotation/notes on reports**: Adding manager notes to specific reports
- **Goal editing**: Modifying sales/buy goals from mobile app
- **Drill-down to individual transactions**: Viewing transaction-level detail from reports

## Detailed Feature Specifications

### Feature: Compare Two Reports

**Description:** Enables managers to view two close reports side-by-side with calculated deltas and variance highlights. This is the most complex feature as it requires fetching two reports, calculating differences, and presenting the comparison in an intuitive format.

**User Flow:**
1. User views a close report detail
2. User taps "Compare" button (available in app bar or as floating action)
3. System presents comparison date selector with quick options ("vs. Yesterday", "vs. Last Week") and calendar
4. User selects comparison date
5. System fetches comparison data from `/compare` endpoint
6. System displays comparison view with:
   - Primary report metrics (left column)
   - Comparison report metrics (right column)
   - Delta values (center or below)
   - Variance highlights for significant changes
7. User can tap any metric row for more detail
8. User can tap "Swap" to reverse primary/comparison
9. User can tap "Change Date" to select different comparison

**Business Rules:**
- Rule 1: Primary date must have a report available (validated before comparison request)
- Rule 2: Comparison date must have a report available (show error if not)
- Rule 3: Variance thresholds: >10% = warning (amber), >25% = critical (red)
- Rule 4: Positive deltas show green/up arrow, negative show red/down arrow (except for metrics where lower is better, like labor %)
- Rule 5: Labor % comparison: lower is better, so negative delta = green, positive = red
- Rule 6: If only primary report exists (no comparison report), show primary with "No comparison available" message

**Edge Cases:**
- Scenario 1: No report exists for comparison date -> Show toast "No report available for [date]" and return to date picker
- Scenario 2: Network error during comparison fetch -> Show error state with retry option, preserve primary report view
- Scenario 3: Primary report deleted while viewing comparison -> Navigate back to report list with refresh
- Scenario 4: Both dates are the same -> Show validation error "Please select a different date for comparison"
- Scenario 5: Comparison date is more recent than primary -> Swap dates automatically (newer is always primary)
- Scenario 6: List pagination fails mid-scroll -> Show inline error with "Tap to retry" in list footer, preserve already-loaded items
- Scenario 7: Calendar shows gap in available dates (e.g., store was closed) -> Disabled dates clearly indicated, no error on tap
- Scenario 8: User crosses timezone boundary (e.g., traveling) -> Dates displayed in store's local timezone, not device timezone

## Success Metrics

### Key Performance Indicators

- **Adoption:** 60% of active store managers access Close Reports within 30 days of launch
- **Engagement:** Average 3+ report views per manager per week
- **Quality:** <2% error rate on report fetch operations
- **Business Impact:** 15% reduction in time from report posting to manager review
  - **Definition:** "Time to review" = timestamp of `close_report_detail_viewed` event minus `postedAt` timestamp from the report data
  - **Measurement:** Calculated from analytics events correlated with report metadata

### Tracking Requirements

| Event | Properties | Purpose |
|-------|------------|---------|
| `close_reports_viewed` | typeNum, source (quick_action, deep_link) | Track how users access feature |
| `close_report_detail_viewed` | typeNum, reportDate, isLatest | Measure which reports are viewed |
| `close_report_date_changed` | typeNum, fromDate, toDate, method (calendar, list, quick_nav) | Understand navigation patterns |
| `close_report_comparison_started` | typeNum, primaryDate | Track comparison feature usage |
| `close_report_comparison_completed` | typeNum, primaryDate, comparisonDate, deltaSeconds | Measure comparison completion |
| `close_report_section_toggled` | typeNum, section, action (expand, collapse) | Understand which sections matter |
| `close_report_error` | typeNum, errorType, endpoint | Monitor reliability |
| `close_report_calendar_opened` | typeNum, currentMonth | Track calendar usage |

---

## Constraints and Assumptions

### Constraints
- **API availability**: Backend close reports API is ready and documented (confirmed in `docs/backend-api-updates.md`)
- **Platform**: Must work on both iOS and Android with consistent behavior
- **Authentication**: Requires valid JWT token (uses existing unified auth system from spec 003)
- **Permissions**: Access controlled by existing permission system - requires Shift Lead (3) or higher access level
- **Monetary format**: API returns cents (integers), frontend must convert to dollars for display
- **Date format**: API uses YYYY-MM-DD format, frontend displays in user-friendly format

### Assumptions
- Users have reliable internet connectivity when viewing reports
- Close reports are posted nightly after store closes (typically 9-11 PM)
- Most users will view reports on the following morning
- Users understand basic retail financial metrics (sales, buys, labor %)
- The existing store detail screen is the primary entry point for this feature
- Calendar widget is sufficient for date navigation (no need for infinite scroll timeline)

## Risks and Mitigations

| Risk | Impact | Likelihood | Mitigation |
|------|--------|------------|------------|
| Large report data causes slow load times | Medium | Low | Implement loading states, consider caching latest report |
| Users confused by cents-to-dollars conversion errors | High | Low | Thorough testing of monetary formatting, unit tests for conversion |
| Calendar widget date selection is cumbersome | Medium | Medium | Include quick navigation shortcuts and list view alternative |
| Comparison view too complex for mobile screen | Medium | Medium | Design for mobile-first, use vertical layout for comparison on small screens |
| Discrepancy details not available in API | Low | N/A | API only provides boolean flag; display generic "Cash Discrepancy" label. Future API enhancement could add type details. |
| Permission confusion (who can see reports) | Low | Low | Follow existing permission patterns, document access requirements |

## Open Questions

- [x] **Resolved**: What permission level should be required? -> Shift Lead (AccessLevel.shiftLead) or higher, consistent with Store Metrics and Buyer Stats
- [x] **Resolved**: Should close reports be added to AppPage enum? -> Yes, add `AppPage.closeReports` with route pattern `/store/:typeNum/close-reports`
- [x] **Resolved**: How should monetary values be formatted? -> Use existing currency formatting from Store Metrics, convert cents to dollars with 2 decimal places
- [x] **Resolved**: What icon represents Close Reports? -> Use `Icons.assessment_rounded` or `Icons.summarize_rounded` (financial document theme)

---

## Supporting Research

### Competitive Analysis
- **Toast POS Mobile**: Provides end-of-day summaries with key metrics, uses card-based layout
- **Square Dashboard**: Shows daily sales totals with comparison to previous periods, uses simple list view
- **Lightspeed Analytics**: Offers detailed reports with drill-down, may be overly complex for mobile

Key insight: Successful mobile reporting apps prioritize summary views with optional detail expansion, rather than showing all data at once.

### User Research
- Based on existing app usage patterns from Store Metrics and Buyer Stats screens (similar feature analogues)
- Managers consistently access performance data in the morning (7-9 AM) reviewing previous day
- Quick access to "vs. goal" percentage is the most requested metric
- Labor % is increasingly important for cost-conscious franchise owners

**Evidence Basis Note:** These observations are derived from:
1. Analogous feature usage in the existing Live app (Store Metrics, Buyer Stats)
2. General retail management workflow patterns
3. Business stakeholder interviews during initial app development

Formal user research specific to close reports has not been conducted; these are reasonable business assumptions based on the existing user base behavior.

### Market Data
- Mobile-first management tools show 40% higher daily engagement than desktop-only
- Retail managers check business metrics 2-3x daily on average
- Time to action on discrepancies reduces by 50% with mobile alerting (future phase opportunity)

---

## Appendix: API Reference Summary

The following endpoints are available (full documentation in `docs/backend-api-updates.md`):

| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/:typeNum/list` | POST | List reports with pagination |
| `/:typeNum/detail` | POST | Get full report for specific date |
| `/:typeNum/latest` | POST | Get most recent report |
| `/:typeNum/calendar` | POST | Get dates with available reports |
| `/:typeNum/compare` | POST | Compare two reports with deltas |

**Base URL**: `https://api.buyerkiosk.com/api/mobile/close-reports`
**Authentication**: JWT Bearer Token

**Key Data Types**:
- All monetary values in **cents** (integers)
- Dates in **YYYY-MM-DD** format
- Percentages as **floats** (e.g., 105.5 for 105.5%)

---

## Appendix: Metric Definitions Glossary

| Metric | Definition |
|--------|------------|
| **Net Sales** | Total sales revenue minus returns, refunds, and discounts for the reporting period |
| **Sales vs. Goal %** | Net sales divided by the daily sales goal, expressed as a percentage (100% = met goal) |
| **Buys Count** | Number of individual buy transactions (items purchased from customers) |
| **Buys Total** | Total dollar amount paid to customers for bought items |
| **Labor %** | Total labor cost divided by net sales, expressed as a percentage (lower is better) |
| **Discrepancy** | Any variance between expected and actual values (API provides boolean flag only, type details not available) |

---

## Appendix: Navigation State Behavior

**State Persistence Rules:**
- Selected report date persists within a single app session
- Section expansion states (collapsed/expanded) persist within a single app session
- Comparison date selection does NOT persist (user must re-select for each comparison)
- On app backgrounding >5 minutes or app restart, all state resets to default (latest report)
- Filter selections in list view persist within session only
