# 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 store operators to forecast, track, and optimize sales and buys goals entirely from the server — enabling forward-looking scheduling, reporting, and performance management without dependency on the desktop Sync app.

### Problem Statement

Today, daily sales and buys goals are calculated exclusively by the BuyerKioskSync desktop app and pushed to the server as simple numbers. This creates three critical limitations:

1. **No future forecasting**: The server only knows today's goal. It cannot answer "What is our sales target for next Saturday?" — making demand-based scheduling impossible. The scheduling solver (specs 026/038) needs daily revenue targets to optimize staffing, but has no goal data to work with.

2. **Desktop dependency**: If the Sync app isn't running (hardware failure, no master register online, new store setup), no goals are calculated. The server becomes a blind receiver with no fallback.

3. **No historical goal analysis**: When goal settings change, the old configuration is lost. Managers cannot compare "What was our target vs actual when we used 5% growth?" versus "How did we perform after switching to 10% growth?" Year-end retrospectives lack goal context.

4. **No variance trending**: The Sync app shows WTD/MTD/YTD variance on hover, but this data isn't available in server-side reports, mobile apps, or dashboards.

### Value Proposition

Moving goal calculations to the server transforms goals from a "display today's number" feature into a **strategic planning tool**:

- **Scheduling integration**: The solver can staff to revenue targets, not just availability
- **365-day forecasting**: Plan inventory, staffing, and promotions quarters ahead
- **Hourly granularity**: Know that "Saturday 11am-1pm should do 22% of daily sales" — optimize shifts to peak hours
- **Full variance suite**: WTD, MTD, YTD plus trailing periods and year-over-year comparisons
- **Goal accountability**: Audit trail and version snapshots answer "who changed what, when, and what impact did it have?"
- **Mobile access**: Mobile apps can display and forecast goals without the desktop app

---

## User Personas

### Primary Persona: Store Manager (Admin)

- **Demographics:** Store operator or general manager with full admin access. Moderate technical comfort. Uses BuyerKiosk daily for operations.
- **Goals:** Set realistic sales and buys targets that motivate staff without being unachievable. Understand performance trends to adjust strategy. Plan staffing and inventory based on expected demand.
- **Pain Points:**
  - Currently must ensure the master register's Sync app is running to get goals
  - Cannot see goals for future dates to plan staffing
  - Loses historical goal context when adjusting settings
  - No way to preview the impact of changing goal parameters before committing

### Secondary Personas

#### Assistant Manager / Shift Lead (Manager-level)
- **Demographics:** Team lead with manager permissions. On the floor daily. Uses workbook and KPI bar frequently.
- **Goals:** See today's goal and variance. Understand if the team is on track. View forecasted goals for upcoming shifts they're managing.
- **Pain Points:** Can see current goal numbers but has no context on how they're calculated. Cannot access variance trending or forecasts.

#### Scheduling Administrator
- **Demographics:** Person responsible for building weekly/monthly schedules. May be the store manager or a dedicated scheduler.
- **Goals:** Schedule staff aligned with expected demand. Ensure peak hours have adequate coverage. Keep labor costs proportional to revenue.
- **Pain Points:** Builds schedules blindly without revenue target context. The solver optimizes for coverage and hours but not revenue alignment.

---

## User Journey Maps

### Primary User Journey: Goal Configuration

1. **Awareness:** Store manager receives quarterly directive to update growth targets, or realizes current goals feel too high/low compared to actual performance.
2. **Consideration:** Manager navigates to the Goals admin page. Reviews current method and settings. Uses the method comparison preview to see how today's goal would change under different methods or parameters.
3. **Adoption:** Manager selects the appropriate method (Method 0, 1, or 2), enters parameters, previews the resulting daily goal, and saves. Audit trail captures the change with old/new values.
4. **Usage:** Server pre-computes 365 days of goals. KPI bar shows today's goal with variance. Scheduling solver uses forecasted goals for shift optimization. Reports show goal attainment trends.
5. **Retention:** Manager reviews weekly/monthly variance reports. Adjusts settings when performance consistently over/under-shoots. Goal snapshots enable retrospective analysis.

### Secondary User Journey: Goal-Informed Scheduling

1. **Awareness:** Scheduling administrator opens the schedule builder for next week.
2. **Consideration:** The solver displays forecasted daily revenue targets alongside open shifts. Administrator sees "Saturday forecast: $8,388 sales — suggest 6 staff on floor."
3. **Adoption:** Administrator runs the solver with revenue-aware optimization. Solver allocates shifts proportional to hourly revenue distribution.
4. **Usage:** Schedule publishes with revenue context. During the week, actual vs forecasted revenue informs real-time staffing adjustments.
5. **Retention:** Post-week review shows "Staffing was 85% aligned with revenue peaks" — improving over time as historical data refines hourly distributions.

### Tertiary User Journey: Variance Analysis

1. **Awareness:** Manager notices the KPI bar showing "danger" status on sales halfway through the month.
2. **Consideration:** Manager expands the variance panel. Sees MTD is -12% off goal. Checks trailing 7-day trend to see if the dip is recent.
3. **Adoption:** Manager compares current period to same-period-last-year. Discovers a local event boosted last year's numbers. Adjusts expectations.
4. **Usage:** Manager uses the goal comparison preview to model "What if I lower growth from 10% to 5%?" — sees the impact across remaining month.
5. **Retention:** End-of-quarter review uses goal snapshots to identify which parameter changes correlated with performance improvements.

---

## Feature Requirements

### Must Have Features

#### Feature 1: Goal Calculation Engine (3 Methods)

- **User Story:** As a store manager, I want the server to calculate daily sales and buys goals using the same methods as the Sync app so that goals are available without desktop dependency.
- **Acceptance Criteria:**
  - [ ] Method 0 (% of Prior Year): Calculates goals by finding the same day-of-week from prior year and applying growth percentage. Uses separate growth percentages for sales and buys (fixing the Sync app bug where both used salesGrowth%).
  - [ ] Method 1 (Annual Target Distribution): Distributes annual dollar target using monthly allocation percentages (must sum to 100%) and day-of-week percentages (must sum to 100%). Buys goals set as flat dollar amounts per day-of-week.
  - [ ] Method 2 (Monthly Target Calendar): Displays a calendar grid for the selected month. Pre-fills each day using Method 0 or Method 1 calculations. Allows manual per-day override. Saves all values (unlike the incomplete Sync app version).
  - [ ] Method 2 forecasting: When Method 2 is active, months with saved calendar configurations use those per-day values. Unconfigured months automatically fall back to the store's previous active method (Method 0 or Method 1) for goal calculation. This allows managers to override only the months they care about while the rest auto-fill.
  - [ ] Calculated goals match Sync app output for identical inputs (Method 0 and Method 1 parity test with known data)
  - [ ] Day-of-week matching for prior year uses same algorithm as Sync: matches by day-of-week AND week-of-month, not calendar date

#### Feature 2: 365-Day Goal Forecasting

- **User Story:** As a scheduling administrator, I want to see forecasted daily goals for any date up to one year ahead so that I can plan staffing aligned with expected demand.
- **Acceptance Criteria:**
  - [ ] Server pre-computes daily sales and buys goals for the next 365 days
  - [ ] Forecasted goals update automatically when goal settings change (invalidate and recompute affected range)
  - [ ] Nightly cron job refreshes the full forecast to incorporate any new historical data
  - [ ] API endpoint returns goals for any date range within the forecast window
  - [ ] Each forecasted goal includes a confidence indicator (high: 12+ months of history, medium: 3-11 months, low: <3 months or fallback data)

#### Feature 3: Smart Fallback for Missing Historical Data

- **User Story:** As a new store manager, I want reasonable goal estimates even before I have a full year of sales history so that I can start using goals from day one.
- **Acceptance Criteria:**
  - [ ] 12+ months of history: Uses standard prior-year same-day-of-week comparison
  - [ ] 3-11 months of history: Averages available same-day-of-week data and applies growth percentage
  - [ ] <3 months or no history: Falls back to Method 1 with system-default monthly and day-of-week distributions
  - [ ] UI displays a clear notice indicating data confidence level (e.g., "Limited historical data — using estimated distribution")
  - [ ] Confidence level is exposed in the API response for downstream consumers (e.g., scheduling solver)

#### Feature 4: Goal Settings Admin Page

- **User Story:** As a store manager, I want a dedicated admin page to configure my goal method and parameters with a preview of the impact before saving.
- **Acceptance Criteria:**
  - [ ] Accessible at `/admin/:typeNum/goals` with `uri_store_settings` permission (admin only)
  - [ ] Managers with view permission can see current settings and forecasts but cannot edit
  - [ ] Method selector (0, 1, 2) with method-specific settings panel
  - [ ] All three methods' settings are preserved when switching between methods (no data loss)
  - [ ] Side-by-side preview shows today's goal under current method vs selected method before confirming a switch
  - [ ] Method 0 panel: Sales growth %, Buys growth % (two separate fields)
  - [ ] Method 1 panel: Annual target, 12 monthly percentages (validated sum = 100%), 7 day-of-week sales percentages (validated sum = 100%), 7 day-of-week buys dollar amounts
  - [ ] Method 2 panel: Month selector, calendar grid with per-day targets, pre-fill button (from Method 0 or 1), day-of-week average buttons (average a weekday's values across the month)
  - [ ] Save button triggers audit log entry and cache invalidation/recompute

#### Feature 5: Variance Calculations (Full Period Suite)

- **User Story:** As a store manager, I want to see how my store is performing against goals across multiple time periods so that I can identify trends and take corrective action.
- **Acceptance Criteria:**
  - [ ] Week-to-Date (WTD): Sum of daily goals vs actual sales/buys for current week through today
  - [ ] Month-to-Date (MTD): Sum of daily goals vs actual for current month through today
  - [ ] Year-to-Date (YTD): Sum of daily goals vs actual for current year through today
  - [ ] Trailing 7 days: Rolling 7-day goal vs actual (not aligned to week boundaries)
  - [ ] Trailing 30 days: Rolling 30-day goal vs actual
  - [ ] Trailing 90 days: Rolling 90-day goal vs actual
  - [ ] Same-period-last-year: Compare current WTD/MTD/YTD to last year's equivalent period
  - [ ] Variance displayed as both dollar amount and percentage
  - [ ] Integrates with existing KPI bar using `workbook_kpi_config` visibility settings

#### Feature 6: Sync App Fallback Compatibility

- **User Story:** As a store using both the Sync app and the web platform, I want the server to calculate goals by default but gracefully accept Sync app pushes as a fallback so that there's no disruption during transition.
- **Acceptance Criteria:**
  - [ ] Server-calculated goals are the primary source of truth
  - [ ] If the server has not yet calculated goals for today (e.g., new store, system startup), the Sync app's pushed values are accepted as-is
  - [ ] When server-calculated goals exist, Sync app pushes do not overwrite them (server wins)
  - [ ] Stores that haven't configured server-side goals continue to work with Sync-pushed values
  - [ ] A clear indicator in the KPI bar shows whether the displayed goal is server-calculated or Sync-pushed

#### Feature 7: Audit Trail and Config Snapshots

- **User Story:** As a store manager, I want a complete record of all goal setting changes with full configuration snapshots so that I can review what changed, who changed it, and what the impact was.
- **Acceptance Criteria:**
  - [ ] Every goal settings save creates an audit log entry: who, when, what field(s) changed, old value, new value
  - [ ] Each audit entry includes a full JSON snapshot of the complete goal configuration at that point in time
  - [ ] Audit history is viewable from the goal settings admin page
  - [ ] Snapshots can be compared side-by-side (selected snapshot vs current settings)
  - [ ] Audit entries include the resulting calculated goal for the save date (so you can see "When we were at 5% growth, today's goal was $X")

### Should Have Features

#### Feature 8: Hourly Goal Distribution

- **User Story:** As a scheduling administrator, I want daily goals broken down by hour using historical sales patterns so that I can optimize shift timing to match expected peak and off-peak demand.
- **Acceptance Criteria:**
  - [ ] System analyzes `hourlyStaffingMetrics.salesVolume` history (90-day lookback by default) to learn the store's hourly sales distribution pattern per day-of-week
  - [ ] Daily goal is distributed across operating hours proportionally to the historical pattern
  - [ ] Managers can adjust distributions using time-band controls (e.g., "Morning 9-12: 25%, Midday 12-3: 35%, Afternoon 3-6: 25%, Evening 6-9: 15%")
  - [ ] Time-band adjustments interpolate into hourly weights using the historical pattern as a shape guide
  - [ ] Hourly distribution data is exposed via API for the scheduling solver
  - [ ] If insufficient hourly history exists (<30 days), uses a uniform distribution with a warning

#### Feature 9: Goal Forecasting API for Scheduling Solver

- **User Story:** As the scheduling solver, I want an API endpoint that returns daily and hourly revenue targets for any date range so that I can optimize shift assignments proportional to expected demand.
- **Acceptance Criteria:**
  - [ ] Endpoint accepts store typeNum, start date, end date
  - [ ] Returns daily sales goal, buys goal, and confidence level per date
  - [ ] Optionally returns hourly sales distribution per date when requested
  - [ ] Returns goal method metadata (which method generated this goal)
  - [ ] Response time under 200ms for a 7-day range (reads from pre-computed cache)
  - [ ] Authenticated with existing API auth mechanism

#### Feature 10: Method Comparison Preview

- **User Story:** As a store manager, I want to preview how my goals would change under different methods or parameters before committing to a change so that I can make informed decisions.
- **Acceptance Criteria:**
  - [ ] From the goal settings page, selecting a different method shows a live preview of today's goal under that method alongside the current method's goal
  - [ ] Adjusting parameters (growth %, annual target, monthly allocations) updates the preview in real-time (no page reload)
  - [ ] Preview includes a 7-day forward view showing each day's goal under current vs proposed settings
  - [ ] Preview is read-only — does not affect live goals until explicitly saved

### Could Have Features

#### Feature 11: Goal Attainment Report

- **User Story:** As a store manager, I want a dedicated report showing goal attainment over time so that I can identify patterns and improve my goal-setting accuracy.
- **Acceptance Criteria:**
  - [ ] Report shows daily, weekly, and monthly goal vs actual with attainment percentage
  - [ ] Filterable by date range and goal method that was active during the period
  - [ ] Visual trend line showing attainment percentage over time
  - [ ] Highlights periods where goal method or parameters changed (from config snapshots)
  - [ ] Exportable to CSV

#### Feature 12: Goal Configuration Import from Sync App

- **User Story:** As a store migrating from Sync-only to server-side goals, I want to import my existing Sync app goal settings so that I don't have to manually re-enter them.
- **Acceptance Criteria:**
  - [ ] API endpoint accepts Sync app CONFIG and GOALSETTINGS table data
  - [ ] Automatically maps Sync fields to server-side goal configuration
  - [ ] Handles the Method 0 bug transparently (separates sales/buys growth % during import)
  - [ ] Presents import preview before committing

#### Feature 13: Cross-Store Goal Benchmarking

- **User Story:** As a multi-store operator, I want to compare goal settings and attainment across my stores so that I can identify best practices and underperformers.
- **Acceptance Criteria:**
  - [ ] Dashboard showing all stores' goal methods, targets, and attainment side-by-side
  - [ ] Ranking by attainment percentage
  - [ ] Filterable by time period and store type

### Won't Have (This Phase)

- **AI-driven goal suggestions**: Automatically recommending optimal growth percentages or annual targets based on market data. Future enhancement once we have enough historical goal attainment data.
- **Goal notifications/alerts**: Push notifications when variance exceeds a threshold (e.g., "MTD sales are 20% below goal"). Can be built as a TaskEngine job in a future phase.
- **Department/category-level goals**: Breaking goals down by product category (e.g., "$2,000 in electronics, $3,000 in clothing"). Current system is store-level only.
- **Customer-facing goals**: Displaying goals or performance to customers. Goals are internal-only.
- **Real-time goal broadcasting**: Ably real-time push of goal changes. Server calculates, clients fetch on demand. Sync app's `updateGoals` Ably message pattern is not replicated.
- **Corporate-level goal management**: Company-wide default settings that stores inherit. All configuration is per-store only.

---

## Detailed Feature Specifications

### Feature: Goal Calculation Engine (Feature 1)

**Description:** The core calculation engine that replicates and improves upon the Sync app's three goal methods. This is the foundation that all other features depend on.

**User Flow:**
1. Admin navigates to `/admin/:typeNum/goals`
2. System loads current goal method and settings for the store
3. Admin selects goal method from Method 0, 1, or 2 tabs
4. Admin configures method-specific parameters
5. System validates inputs (percentage sums, required fields)
6. Admin clicks "Preview" to see calculated goals under new settings
7. Admin clicks "Save" to apply changes
8. System creates audit entry + config snapshot, invalidates goal cache, triggers recompute

**Business Rules:**

- Rule 1: Method 0 — Prior year matching uses day-of-week + week-of-month, not calendar date. For example, "3rd Saturday of October 2026" matches "3rd Saturday of October 2025" regardless of calendar dates.
- Rule 2: Method 0 — Growth percentages are applied separately: `salesGoal = priorYearSales * (1 + salesGrowth/100)`, `buysGoal = priorYearBuys * (1 + buysGrowth/100)`. This fixes the Sync app bug where both used salesGrowth%.
- Rule 3: Method 0 — Leap year handling: When the prior year lookup crosses a leap year boundary, offset by +2 days (matching Sync app behavior).
- Rule 4: Method 1 — Monthly percentages must sum to exactly 100.00%. Day-of-week sales percentages must sum to exactly 100.00%. Validation prevents save if sums are incorrect.
- Rule 5: Method 1 — Daily sales formula: `monthlySalesGoal = annualGoal * monthPct / 100; numWeekdays = count of [target day-of-week] in target month; dailySalesGoal = monthlySalesGoal * dayPct / 100 / numWeekdays`
- Rule 6: Method 1 — Daily buys goals are flat dollar amounts per day-of-week, not derived from annual target.
- Rule 7: Method 2 — Calendar grid pre-fills using the store's previous active method (Method 0 or Method 1). Manual edits override the pre-fill for that specific day. Only months with explicitly saved configurations use per-day values; unconfigured months fall back to Method 0/1 calculations for forecasting.
- Rule 8: Method 2 — "Average" buttons calculate the mean of a specific weekday across the month and set all instances of that weekday to the average. (e.g., Average all Saturdays in October)
- Rule 9: All methods — When switching methods, previous method settings are preserved. Only the active method flag changes.
- Rule 10: Fallback cascade for missing prior year data (Method 0): 12+ months history → standard lookup; 3-11 months → average available same-day data; <3 months → fall back to Method 1 defaults.
- Rule 11: Time boundaries — All goal and variance calculations use the store's configured timezone (from `stores.timezone`). "Today" is defined as midnight-to-midnight in store local time. Weeks start on Monday.
- Rule 12: Rounding — All currency calculations round to the nearest cent (2 decimal places, half-up). Percentage validations accept exactly 100.00% (no tolerance band). Display values truncate to whole dollars for goals, show cents for variance.
- Rule 13: Store closed days — If a store has a known closure (holiday, renovation), the daily goal for that date is $0. If the closure is unplanned (no data in advance), the goal stands and variance shows the shortfall. Method 2 calendar allows manual $0 override for planned closures.
- Rule 14: Confidence indicator thresholds — High: 12+ months of non-zero same-day-of-week history available. Medium: 3-11 months of data. Low: <3 months or using fallback distribution. If the matched prior-year day had $0 sales (anomalous), confidence downgrades by one level.

**Edge Cases:**

- Scenario 1: Store has zero historical sales data (brand new store) → Expected: Method 0 falls back to Method 1 with system defaults. Confidence indicator shows "low". UI displays notice about limited data.
- Scenario 2: Prior year had a holiday/closure on the matching day ($0 sales) → Expected: System returns $0 * (1 + growth%) = $0. This is technically correct but misleading. The confidence indicator flags unusual prior-year data. Manager can use Method 2 calendar to manually override that day.
- Scenario 3: Method 1 monthly percentages don't sum to 100% → Expected: Validation error. Save button disabled. Subtotal displays in red. No partial save allowed.
- Scenario 4: Store switches from Method 1 to Method 0 and back → Expected: Method 1 settings (annual target, monthly/daily percentages) are fully preserved. No data loss on switch.
- Scenario 5: Two admins edit goal settings simultaneously → Expected: Last save wins. Both saves are recorded in the audit trail. No silent data loss.
- Scenario 6: Method 2 calendar has some days manually edited, then user clicks "Average Saturdays" → Expected: All Saturday cells (including previously edited ones) are recalculated to the Saturday average. User can undo by re-editing individual cells.
- Scenario 7: Leap year target date (Feb 29) has no prior year equivalent → Expected: System uses Feb 28 of prior year as the closest match. Confidence indicator notes the adjustment.
- Scenario 8: Goal settings saved mid-day → Expected: Today's forecasted goal updates immediately. Already-displayed KPI values refresh on next poll/load. Historical actual-vs-goal records are unaffected.
- Scenario 9: Annual target set to $0 → Expected: System accepts it (valid for seasonal/closed stores). All daily goals calculate to $0. Variance calculations still function, showing actual as "over goal."
- Scenario 10: Store is closed on a scheduled day (e.g., holiday) → Expected: If Method 2, manager sets that day to $0. If Method 0/1, the system calculates the normal goal (no automatic holiday detection). Manager can use Method 2 to override closures.
- Scenario 11: DST transition day (spring forward / fall back) → Expected: Goals are date-based, not hour-count-based, so DST has no impact on daily totals. Hourly distributions adjust proportionally — the "missing" or "extra" hour in the transition is absorbed by the store's operating hours.
- Scenario 12: Negative or voided sales (returns exceed sales for a period) → Expected: Actual sales can be negative. Variance displays the negative actual against the positive goal, resulting in a large negative variance. Goals are never negative — they represent targets.
- Scenario 13: Late Sync app push arrives after server already calculated today's goal → Expected: Server-calculated goal takes priority. The Sync push is ignored but logged for diagnostics. No overwrite occurs.
- Scenario 14: Method 2 active, manager has configured Oct-Dec but requests forecast for January → Expected: January is not configured in Method 2. System falls back to the store's previous method (Method 0 or 1) for January's goals. Confidence indicator reflects the fallback.

---

## Success Metrics

### Key Performance Indicators

- **Adoption:** 80% of active stores configure server-side goals within 60 days of launch (vs remaining on Sync-only)
- **Engagement:** Goal settings page visited at least once per month by store admins. Variance panel expanded at least weekly by managers.
- **Quality:** Server-calculated goals match Sync app output within $1 for identical inputs on Method 0 and Method 1 (parity validation). API response time < 200ms for 7-day forecast.
- **Business Impact:** Scheduling solver produces 15% better revenue-alignment scores when using goal data vs without. Goal attainment tracking enables stores to hit within 5% of targets more consistently over time.

### Tracking Requirements

| Event | Properties | Purpose |
|-------|------------|---------|
| `goal_settings_viewed` | typeNum, goalMethod, hasServerGoals | Track adoption — who's using the admin page |
| `goal_settings_saved` | typeNum, goalMethod, changedFields[], previousMethod | Track configuration changes and method preferences |
| `goal_method_switched` | typeNum, fromMethod, toMethod | Understand method migration patterns |
| `goal_preview_used` | typeNum, previewMethod, currentMethod | Measure preview feature engagement |
| `goal_forecast_requested` | typeNum, dateRange, includeHourly, source(api/ui) | Track forecast API usage by consumers |
| `goal_variance_viewed` | typeNum, periods[], expandedDetail | Measure variance feature adoption |
| `goal_fallback_triggered` | typeNum, fallbackReason, confidenceLevel | Monitor data quality and fallback frequency |
| `goal_sync_app_override_blocked` | typeNum | Track how often Sync push is blocked by server-calculated goals |

---

## Constraints and Assumptions

### Constraints

- **Historical data dependency**: Method 0 quality depends on having prior year sales data in the server. Stores without imported history will rely on fallback calculations until they accumulate enough data organically.
- **POS data format**: The server receives POS sales data via the DRS API route (`drs.php`). Goal calculations depend on this data being accurate and timely.
- **Hourly metrics availability**: Hourly goal distribution requires `hourlyStaffingMetrics` data, which is collected by the `HourlyMetricsCollectorJob`. Stores without this job running will get uniform hourly distributions.
- **Existing KPI infrastructure**: The variance and display features build on the existing `KPIService` and `workbook_kpi_config` system. Changes must be backward-compatible with current KPI bar behavior.
- **Migration system**: All database changes must go through the existing migration system (conductor). No direct SQL on store databases.
- **Permission system**: Uses existing UserFrosting permission system (`checkAccess`). New permissions follow existing patterns.

### Assumptions

- Stores have or will have at least one year of historical POS sales data for optimal Method 0 performance. The smart fallback system handles cases where this assumption doesn't hold.
- The `hourlyStaffingMetrics` job is running at most stores. Stores without it can still use daily-level goals but won't get hourly distributions.
- Store managers understand growth percentages and annual target concepts from their experience with the Sync app. The server UI will use the same terminology.
- The scheduling solver (specs 026/038) will be updated to consume the goal forecasting API. This is a separate development effort that depends on this spec's API being available.
- Goal settings are changed infrequently (monthly or quarterly). The pre-compute + invalidate strategy is efficient because recomputes are rare.

---

## Risks and Mitigations

| Risk | Impact | Likelihood | Mitigation |
|------|--------|------------|------------|
| Server-calculated goals differ from Sync app goals for the same inputs, causing confusion | High | Medium | Parity test suite comparing server output to documented Sync app formulas. Fix the Method 0 bug transparently with clear release notes. |
| Insufficient historical data for new stores makes goals unreliable | Medium | Medium | Smart fallback cascade with confidence indicators. Managers see exactly how much data backs their goal. |
| Goal settings cache becomes stale, showing outdated goals | High | Low | Hybrid compute: pre-compute nightly + invalidate on save. Cache miss triggers on-demand calculation. |
| Admin page complexity overwhelms managers unfamiliar with Method 1's 20+ fields | Medium | Medium | Method-specific panels with sensible defaults. Method 1 ships with the same default monthly/daily percentages as the Sync app. Tooltips and inline help. |
| Scheduling solver integration delayed, reducing value of forecasting API | Medium | Medium | Goal forecasting has standalone value (reports, KPI bar, admin visibility) even without solver integration. |
| Audit trail and snapshots create storage bloat over years | Low | Low | Goal settings change infrequently. Even with 100 stores changing settings monthly for 5 years, total storage is negligible (<100MB). |
| Method 2 calendar UI is complex to build and test across all months/years | Medium | Medium | Pre-fill from existing methods reduces the "blank canvas" problem. Average buttons reduce manual entry. Start with current month +-3 and expand later if needed. |

---

## Open Questions

- [x] Which goal methods to support → All 3, with Method 0 bug fix and Method 2 completion
- [x] Forecast horizon → Full year (365 days)
- [x] Data source priority → Server primary, Sync fallback
- [x] Goal scope → Per-store only (cross-store benchmarking future phase)
- [x] Hourly granularity → Yes, using historical patterns + time-band adjustments
- [x] Permission model → Admin edit, Manager view
- [x] Audit requirements → Full audit trail with config snapshots
- [x] Compute strategy → Hybrid pre-compute + invalidate on change
- [x] Real-time broadcasting → No, clients fetch on demand
- [x] UI location → Standalone page at `/admin/:typeNum/goals`
- [x] Missing data handling → Smart cascade fallback with confidence indicators
- [x] Method switching → Preserve all settings, preview before switch
- [x] Visibility toggles → Use existing `workbook_kpi_config` system

---

## Supporting Research

### Competitive Analysis

The approach of server-side goal management with configurable methods is standard in retail POS ecosystems. Systems like Lightspeed, Vend, and Square offer similar "annual target -> monthly distribution -> daily goals" workflows. The differentiator here is the tight integration with demand-based scheduling and hourly distribution, which most competitors don't offer.

### User Research

Based on the existing Sync app usage patterns:
- Method 0 (% of prior year) is the most commonly used due to simplicity
- Method 1 (annual target) is preferred by stores with seasonal variation who want more control
- Method 2 was never fully functional, so usage is unknown — but the concept of per-day manual targets fills a gap for stores with irregular sales patterns (events, local promotions)
- Over/Short variance is frequently checked (the Sync app refreshes it every 2 minutes), indicating strong demand for variance analytics

### Market Data

Resale/consignment retail industry averages suggest 3-7% year-over-year growth for established stores. The default growth percentage for Method 0 should be configurable but can default to 5%. Method 1's default monthly distributions from the Sync app (ranging from 6.5% to 11%) reflect typical resale retail seasonality with peaks in summer (back-to-school) and fall (holiday prep).

### System Default Distributions (Method 1 / Fallback)

These defaults match the Sync app's GOALSETTINGS defaults and are used for new stores, fallback calculations, and Method 1 initialization:

**Monthly allocation percentages (must sum to 100.00%):**

| Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
| 6.50 | 7.00 | 9.00 | 8.00 | 9.50 | 8.00 | 9.00 | 10.00 | 9.00 | 11.00 | 6.50 | 6.50 |

**Day-of-week sales percentages (must sum to 100.00%):**

| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|-----|-----|-----|-----|-----|-----|-----|
| 13.00 | 10.00 | 10.00 | 9.00 | 11.00 | 16.50 | 30.50 |

**Day-of-week buys defaults (flat dollar amounts):**

| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|-----|-----|-----|-----|-----|-----|-----|
| $1,000 | $1,000 | $1,000 | $1,000 | $1,000 | $2,000 | $2,000 |

**Default annual target:** $500,000 (used only when no target has been set)
**Default growth percentages (Method 0):** Sales: 5.00%, Buys: 5.00%
