# Implementation Plan

## Validation Checklist

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

---

## Specification Compliance Guidelines

### How to Ensure Specification Adherence

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

### Deviation Protocol

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

## Metadata Reference

- `[parallel: true]` - Tasks that can run concurrently
- `[component: component-name]` - For multi-component features
- `[ref: document/section; lines: 1, 2-3]` - Links to specifications, patterns, or interfaces and (if applicable) line(s)
- `[activity: type]` - Activity hint for specialist agent selection
- `[depends: TX]` - Explicit dependency on another phase/task

---

## Context Priming

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

**Specification**:

- `docs/specs/046-server-side-goals-forecasting/product-requirements.md` - Product Requirements (13 features, 14 business rules, 14 edge cases)
- `docs/specs/046-server-side-goals-forecasting/solution-design.md` - Solution Design (4 services, 6 API endpoints, 3 tables, 10 ADRs)
- `docs/systems/sync-app-goals-system.md` - Sync app reverse-engineering (formulas, DB tables, known bugs)

**Key Design Decisions**:

- ADR-1: Syncfusion-heavy UI (Tab, NumericTextBox, Schedule month view)
- ADR-2: Server-side AJAX preview (no JS formula duplication)
- ADR-3: Single JSON config table (`goalConfigurations` with `methodSettings` JSON)
- ADR-4: One-row-per-day forecast cache with hourly JSON
- ADR-5: Dedicated `goalConfigAudit` table with full config snapshots
- ADR-6: TaskEngine job for nightly recompute
- ADR-7: Four-service architecture (Config, Calculation, Forecast, Variance)
- ADR-8: New route group `/api/:typeNum/goals/`
- ADR-9: Syncfusion Schedule for Method 2 calendar
- ADR-10: Full page with smart defaults (no wizard)

**Implementation Context**:

- Commands to run:
  ```bash
  ./test.sh --testsuite unit                    # Run all unit tests
  cd userfrosting && ./vendor/bin/phpunit --filter "Goal"  # Targeted goal tests
  cd userfrosting && ./vendor/bin/phpstan analyse src/BuyerKiosk/Goals/  # Static analysis
  php userfrosting/conductor run                # Run migrations
  php userfrosting/conductor build-css --minify # Build CSS
  php userfrosting/bin/task job:dispatch goal-forecast-compute --store=pc00  # Test job
  ```
- Patterns to follow:
  - `[ref: userfrosting/src/BuyerKiosk/StoreConfig/Controllers/StoreConfigController.php]` — API controller pattern
  - `[ref: userfrosting/src/BuyerKiosk/StoreConfig/Controllers/StoreConfigPageController.php]` — Page controller pattern
  - `[ref: userfrosting/src/BuyerKiosk/Scheduling/Repositories/ShiftAuditRepository.php]` — Audit repository pattern
  - `[ref: userfrosting/src/BuyerKiosk/PosDataCatchup/Jobs/PosDataCatchupJob.php]` — TaskEngine job pattern
  - `[ref: userfrosting/src/BuyerKiosk/Workbook/KPIService.php]` — KPI integration target
  - `[ref: userfrosting/src/BuyerKiosk/Workbook/KPIConfig.php]` — Config class pattern
- Interfaces to implement:
  - `[ref: SDD/Internal API Changes; lines: 492-648]` — 6 API endpoint specifications
  - `[ref: SDD/Data Storage Changes; lines: 402-490]` — 3 table schemas
  - `[ref: SDD/Application Data Models; lines: 650-702]` — 3 value objects

**Implementation Gotchas** (from SDD and MEMORY.md):

- Syncfusion components in hidden tabs → destroy + recreate on tab activation
- PDO named parameter reuse → use unique names (`:param1`, `:param2`), bind same value
- LiveFinancials stores goals as integers (cents) → goalForecast uses DECIMAL(12,2) → align formats in KPIService
- Store timezone → always use `$store->getTimezone()`, never server time
- Method 2 per-day values store BOTH sales AND buys: `{"sales": 5000, "buys": 1500}`
- Config save dispatches async recompute via TaskEngine, does NOT block request

---

## Implementation Phases

### Phase Dependency Graph

```
Phase 1 (Foundation) ──┬──> Phase 2 (Calc Engine) ──┐
                       │                             ├──> Phase 4 (Services) ──> Phase 5 (API) ──> Phase 7 (Frontend)
                       └──> Phase 3 (Data Layer) ────┘                     │
                                                                           └──> Phase 6 (Integration)
                                                                                        │
                                                                           Phase 8 (E2E Validation) <──┘
```

---

- [ ] T1 Phase 1: Foundation — Database Migrations, Domain Models, and Enums

    *Delivers: Database tables, value objects, enums. Everything else depends on this.*

    - [ ] T1.1 Prime Context
        - [ ] T1.1.1 Read data storage schema `[ref: SDD/Data Storage Changes; lines: 402-490]`
        - [ ] T1.1.2 Read application data models `[ref: SDD/Application Data Models; lines: 650-702]`
        - [ ] T1.1.3 Read migration system patterns `[ref: userfrosting/migrations/input/]` `[ref: MEMORY.md/Migration System]`
        - [ ] T1.1.4 Read PSR-4 autoloading conventions `[ref: docs/patterns/psr4-autoloading.md]`

    - [ ] T1.2 Write Tests
        - [ ] T1.2.1 Unit tests for GoalConfiguration model — construction, getMethod0/1/2Settings(), toArray(), toJson() `[ref: PRD/Feature 1 - all methods' parameters]` `[activity: write-unit-tests]`
        - [ ] T1.2.2 Unit tests for DailyGoal model — construction, getHourlyGoal(hour), toArray() `[ref: PRD/Feature 2 - confidence indicator]` `[activity: write-unit-tests]`
        - [ ] T1.2.3 Unit tests for GoalVariance model — isOnTrack(), getStatus(), toArray(), zero-goal edge case `[ref: PRD/Feature 5 - variance calculations]` `[activity: write-unit-tests]`
        - [ ] T1.2.4 Unit tests for GoalMethod enum — values, fromInt() `[activity: write-unit-tests]`
        - [ ] T1.2.5 Unit tests for ConfidenceLevel enum — values, comparison `[activity: write-unit-tests]`

    - [ ] T1.3 Implement Domain Models and Enums
        - [ ] T1.3.1 Create `GoalMethod` enum (METHOD_0, METHOD_1, METHOD_2) in `src/BuyerKiosk/Goals/Domain/` `[activity: domain-modeling]`
        - [ ] T1.3.2 Create `ConfidenceLevel` enum (HIGH, MEDIUM, LOW) in `src/BuyerKiosk/Goals/Domain/` `[activity: domain-modeling]`
        - [ ] T1.3.3 Create `GoalConfiguration` value object with JSON-aware getters `[ref: SDD/Application Data Models; lines: 653-671]` `[activity: domain-modeling]`
        - [ ] T1.3.4 Create `DailyGoal` value object with hourly distribution support `[ref: SDD/Application Data Models; lines: 672-687]` `[activity: domain-modeling]`
        - [ ] T1.3.5 Create `GoalVariance` value object with status thresholds and zero-goal handling `[ref: SDD/Application Data Models; lines: 688-702]` `[activity: domain-modeling]`

    - [ ] T1.4 Implement Database Migrations
        - [ ] T1.4.1 Create migration JSON: `goalConfigurations` table in central DB `[ref: SDD/Data Storage Changes; lines: 406-448]` `[activity: data-architecture]`
        - [ ] T1.4.2 Create migration JSON: `goalConfigAudit` table in central DB `[ref: SDD/Data Storage Changes; lines: 460-474]` `[activity: data-architecture]`
        - [ ] T1.4.3 Create migration JSON: `goalForecast` table in store DBs `[ref: SDD/Data Storage Changes; lines: 478-489]` `[activity: data-architecture]`
        - [ ] T1.4.4 Create migration JSON: `goalHourlyTimeBands` placeholder or confirm hourlyTimeBands column is stored in `goalConfigurations.hourlyTimeBands` JSON column (reconcile with SDD directory map entry `20260413_004_goal_hourly_time_bands.json`) `[ref: SDD/Directory Map; line: 397]` `[activity: data-architecture]`
        - [ ] T1.4.5 Run migrations: `php userfrosting/conductor run` and verify tables created `[activity: data-architecture]`

    - [ ] T1.5 Validate
        - [ ] T1.5.1 Run unit tests for all models and enums `[activity: run-tests]`
        - [ ] T1.5.2 Run PHPStan on `src/BuyerKiosk/Goals/` `[activity: lint-code]`
        - [ ] T1.5.3 Verify migration tables exist with correct columns/types in dev DB `[activity: review-code]`
        - [ ] T1.5.4 Verify GoalConfiguration handles Method 2 per-day format `{"sales": X, "buys": Y}` correctly `[activity: business-acceptance]`

---

- [ ] T2 Phase 2: Goal Calculation Engine — Core Math for All 3 Methods `[depends: T1]`

    *Delivers: GoalCalculationEngine with Method 0/1/2 formulas, fallback cascade, confidence determination, hourly distribution. The mathematical heart of the system.*

    - [ ] T2.1 Prime Context
        - [ ] T2.1.1 Read Sync app goal system formulas `[ref: docs/systems/sync-app-goals-system.md; lines: 15-107]`
        - [ ] T2.1.2 Read SDD calculation examples `[ref: SDD/Implementation Examples; lines: 744-823]`
        - [ ] T2.1.3 Read fallback cascade algorithm `[ref: SDD/Complex Logic: Fallback Cascade; lines: 951-977]`
        - [ ] T2.1.4 Read PRD business rules 1-14 `[ref: PRD/Business Rules; lines: 280-293]`
        - [ ] T2.1.5 Read hourly metrics repository for distribution data `[ref: userfrosting/src/BuyerKiosk/Scheduling/Repositories/HourlyMetricsRepository.php]`

    - [ ] T2.2 Write Tests — Method 0
        - [ ] T2.2.1 Test: Method 0 calculates with correct separate growth percentages (bug fix verified) `[ref: PRD/Feature 1 - AC1; SDD/Test Scenario 1]` `[activity: write-unit-tests]`
        - [ ] T2.2.2 Test: Day-of-week + week-of-month matching algorithm (3rd Saturday Oct 2026 → 3rd Saturday Oct 2025) `[ref: PRD/Rule 1]` `[activity: write-unit-tests]`
        - [ ] T2.2.3 Test: Leap year boundary offset (+2 days) `[ref: PRD/Rule 3]` `[activity: write-unit-tests]`
        - [ ] T2.2.4 Test: Feb 29 target → Feb 28 prior year match with confidence downgrade `[ref: PRD/Scenario 7]` `[activity: write-unit-tests]`
        - [ ] T2.2.5 Test: Prior year $0 sales (anomalous) → confidence downgraded to medium `[ref: PRD/Scenario 2; Rule 14]` `[activity: write-unit-tests]`

    - [ ] T2.3 Write Tests — Method 1
        - [ ] T2.3.1 Test: Annual distribution formula ($1M, Oct 11%, Sat 30.5%, 4 Saturdays → $8,387.50) `[ref: PRD/Rule 5; SDD/Test Scenario 2]` `[activity: write-unit-tests]`
        - [ ] T2.3.2 Test: Day-of-week buys are flat amounts (not percentage-derived) `[ref: PRD/Rule 6]` `[activity: write-unit-tests]`
        - [ ] T2.3.3 Test: $0 annual target → all goals = $0, accepted as valid `[ref: PRD/Scenario 9]` `[activity: write-unit-tests]`
        - [ ] T2.3.4 Test: Method 1 confidence is always 'high' (deterministic, no history needed) `[activity: write-unit-tests]`

    - [ ] T2.4 Write Tests — Method 2
        - [ ] T2.4.1 Test: Configured month returns per-day sales AND buys values `[ref: PRD/Feature 1 - AC3]` `[activity: write-unit-tests]`
        - [ ] T2.4.2 Test: Unconfigured month falls back to fallbackMethod (0 or 1) `[ref: PRD/Feature 1 - AC4; Scenario 14]` `[activity: write-unit-tests]`
        - [ ] T2.4.3 Test: Average weekday calculation across a month `[ref: PRD/Rule 8]` `[activity: write-unit-tests]`
        - [ ] T2.4.4 Test: Method 2 day set to $0 (planned closure) returns $0 goal `[ref: PRD/Scenario 10; Rule 13]` `[activity: write-unit-tests]`

    - [ ] T2.5 Write Tests — Fallback Cascade
        - [ ] T2.5.1 Test: 12+ months history → standard lookup, confidence high `[ref: PRD/Feature 3 - AC1]` `[activity: write-unit-tests]`
        - [ ] T2.5.2 Test: 3-11 months history → average same-day data, confidence medium `[ref: PRD/Feature 3 - AC2]` `[activity: write-unit-tests]`
        - [ ] T2.5.3 Test: <3 months → fallback to Method 1 defaults, confidence low `[ref: PRD/Feature 3 - AC3; SDD/Test Scenario 4]` `[activity: write-unit-tests]`
        - [ ] T2.5.4 Test: Zero history (brand new store) → Method 1 defaults used `[ref: PRD/Scenario 1]` `[activity: write-unit-tests]`

    - [ ] T2.6 Write Tests — Hourly Distribution
        - [ ] T2.6.1 Test: Historical pattern normalizes to weights summing to 1.0 `[ref: PRD/Feature 8 - AC2]` `[activity: write-unit-tests]`
        - [ ] T2.6.2 Test: Time-band adjustments interpolate correctly `[ref: PRD/Feature 8 - AC4]` `[activity: write-unit-tests]`
        - [ ] T2.6.3 Test: <30 days hourly history → uniform 1/24 distribution `[ref: PRD/Feature 8 - AC6]` `[activity: write-unit-tests]`
        - [ ] T2.6.4 Test: No time bands → uses pure historical pattern `[activity: write-unit-tests]`

    - [ ] T2.7 Implement GoalCalculationEngine
        - [ ] T2.7.1 Create `GoalCalculationEngine` class skeleton with constructor DI `[ref: SDD/Directory Map; line: 346]` `[activity: backend-implementation]`
        - [ ] T2.7.2 Implement `calculateMethod0()` — prior year matching, growth application, confidence `[ref: SDD/Example: Method 0; lines: 748-788]` `[activity: backend-implementation]`
        - [ ] T2.7.3 Implement helper methods: `getWeekOfMonth()`, `findNthDayOfWeekInMonth()`, `crossesLeapYearBoundary()` `[activity: backend-implementation]`
        - [ ] T2.7.4 Implement `calculateMethod1()` — annual distribution formula `[ref: docs/systems/sync-app-goals-system.md; lines: 82-98]` `[activity: backend-implementation]`
        - [ ] T2.7.5 Implement `calculateMethod2()` — configured month lookup + fallback dispatch `[activity: backend-implementation]`
        - [ ] T2.7.6 Implement `calculateForDate()` — dispatches to correct method based on activeMethod `[activity: backend-implementation]`
        - [ ] T2.7.7 Implement `determineConfidence()` — history depth check, $0 anomaly downgrade, Feb 29 downgrade `[ref: PRD/Rule 14]` `[activity: backend-implementation]`
        - [ ] T2.7.8 Implement `distributeGoalToHours()` — historical pattern + time-band interpolation `[ref: SDD/Example: Hourly Distribution; lines: 794-823]` `[activity: backend-implementation]`
        - [ ] T2.7.9 Implement `calculateAverageForWeekday()` — Method 2 average buttons logic `[activity: backend-implementation]`

    - [ ] T2.8 Validate
        - [ ] T2.8.1 Run all calculation engine unit tests — verify Method 0/1/2 and fallback cascade `[activity: run-tests]`
        - [ ] T2.8.2 Run PHPStan on `src/BuyerKiosk/Goals/Services/GoalCalculationEngine.php` `[activity: lint-code]`
        - [ ] T2.8.3 Verify Method 0 parity: compare output against documented Sync app formulas for known inputs `[ref: PRD/Feature 1 - AC5]` `[activity: business-acceptance]`
        - [ ] T2.8.4 Verify rounding: all results round to 2 decimal places, half-up `[ref: PRD/Rule 12]` `[activity: business-acceptance]`

---

- [ ] T3 Phase 3: Data Access Layer — Repositories `[depends: T1]` `[parallel: true with T2]`

    *Delivers: All 4 repositories for reading/writing goal data. Can be built in parallel with Phase 2.*

    > **Parallel note**: Phase 2 (GoalCalculationEngine) depends on SalesHistoryRepository and HourlyMetricsRepository at runtime, but in test mode uses mocks. Build repos and engine independently; integration is validated when Phase 4 wires them together.

    - [ ] T3.1 SalesHistoryRepository `[parallel: true]` `[component: data-layer]`
        - [ ] T3.1.1 Prime: Read LiveFinancials and dailyCloseReports table structures `[ref: SDD/Data Interfaces; lines: 226-229]`
        - [ ] T3.1.2 Test: `getSalesForDate()` returns netSalesRetail + buysCost for a given date `[activity: write-unit-tests]`
        - [ ] T3.1.3 Test: `getAvailableSameDayHistory()` returns matching day-of-week data across available months `[activity: write-unit-tests]`
        - [ ] T3.1.4 Test: `getHistoryDepthForDayOfWeek()` returns months of available data `[activity: write-unit-tests]`
        - [ ] T3.1.5 Implement: `SalesHistoryRepository` with store DB connection `[activity: data-architecture]`
        - [ ] T3.1.6 Validate: Query returns correct data from dev store (pc00) `[activity: run-tests]`

    - [ ] T3.2 GoalConfigRepository `[parallel: true]` `[component: data-layer]`
        - [ ] T3.2.1 Prime: Read goalConfigurations schema `[ref: SDD/Data Storage Changes; lines: 406-448]`
        - [ ] T3.2.2 Test: `getByStoreId()` returns GoalConfiguration or null `[activity: write-unit-tests]`
        - [ ] T3.2.3 Test: `getByTypeNum()` returns GoalConfiguration or null `[activity: write-unit-tests]`
        - [ ] T3.2.4 Test: `save()` performs INSERT on new, UPDATE on existing (upsert) `[activity: write-unit-tests]`
        - [ ] T3.2.5 Test: `getTimeBands()` returns decoded hourlyTimeBands JSON or null `[activity: write-unit-tests]`
        - [ ] T3.2.6 Implement: `GoalConfigRepository` with central DB connection `[activity: data-architecture]`
        - [ ] T3.2.7 Validate: CRUD operations work against dev central DB `[activity: run-tests]`

    - [ ] T3.3 GoalForecastRepository `[parallel: true]` `[component: data-layer]`
        - [ ] T3.3.1 Prime: Read goalForecast schema `[ref: SDD/Data Storage Changes; lines: 478-489]`
        - [ ] T3.3.2 Test: `getByDate()` returns single forecast row or null `[activity: write-unit-tests]`
        - [ ] T3.3.3 Test: `getByDateRange()` returns array of DailyGoal for date range `[activity: write-unit-tests]`
        - [ ] T3.3.4 Test: `upsert()` inserts or updates by forecastDate `[activity: write-unit-tests]`
        - [ ] T3.3.5 Test: `batchInsert()` efficiently inserts 365 rows `[activity: write-unit-tests]`
        - [ ] T3.3.6 Test: `deleteServerComputed()` only deletes source='server' rows, preserving sync_fallback `[activity: write-unit-tests]`
        - [ ] T3.3.7 Test: `hasServerGoal()` returns bool for DRS route check `[activity: write-unit-tests]`
        - [ ] T3.3.8 Implement: `GoalForecastRepository` with store DB connection `[activity: data-architecture]`
        - [ ] T3.3.9 Validate: Batch insert 365 rows completes in < 1s `[activity: run-tests]`

    - [ ] T3.4 GoalConfigAuditRepository `[parallel: true]` `[component: data-layer]`
        - [ ] T3.4.1 Prime: Read audit pattern `[ref: userfrosting/src/BuyerKiosk/Scheduling/Repositories/ShiftAuditRepository.php]`
        - [ ] T3.4.2 Test: `logCreate()` records initial config with full snapshot `[ref: PRD/Feature 7 - AC1, AC2]` `[activity: write-unit-tests]`
        - [ ] T3.4.3 Test: `logUpdate()` records changed fields, old/new values, and config snapshot `[ref: PRD/Feature 7 - AC1]` `[activity: write-unit-tests]`
        - [ ] T3.4.4 Test: `logMethodSwitch()` records method change as distinct action type `[activity: write-unit-tests]`
        - [ ] T3.4.5 Test: `getHistory()` returns paginated audit entries with actor name joined from users table `[ref: PRD/Feature 7 - AC3]` `[activity: write-unit-tests]`
        - [ ] T3.4.6 Test: `getSnapshotById()` returns full configSnapshotJson for comparison `[ref: PRD/Feature 7 - AC4]` `[activity: write-unit-tests]`
        - [ ] T3.4.7 Test: `compareSnapshots()` returns field-level diff between snapshot and current config `[ref: PRD/Feature 7 - AC4]` `[activity: write-unit-tests]`
        - [ ] T3.4.8 Test: `logCreate()`/`logUpdate()` populates `calculatedGoalForDate` JSON with the save date's computed goal `[ref: PRD/Feature 7 - AC5; SDD/Data Storage Changes; line: 470]` `[activity: write-unit-tests]`
        - [ ] T3.4.9 Implement: `GoalConfigAuditRepository` with central DB connection `[activity: data-architecture]`
        - [ ] T3.4.10 Validate: Audit entries created correctly with snapshot integrity and calculatedGoalForDate populated `[activity: run-tests]`

---

- [ ] T4 Phase 4: Service Layer — Business Logic Orchestration `[depends: T2, T3]`

    *Delivers: GoalConfigService, GoalForecastService, GoalVarianceService. Wires calculation engine to repositories.*

    - [ ] T4.1 GoalConfigService `[component: service-layer]`
        - [ ] T4.1.1 Prime: Read config CRUD + audit flow `[ref: SDD/Runtime View; lines: 866-925]`
        - [ ] T4.1.2 Test: `getConfig()` returns GoalConfiguration for store, creating with defaults if none exists `[activity: write-unit-tests]`
        - [ ] T4.1.3 Test: `updateConfig()` validates inputs, saves config, creates audit entry, dispatches recompute job `[ref: PRD/Feature 4 - AC9]` `[activity: write-unit-tests]`
        - [ ] T4.1.4 Test: `validateSettings()` rejects Method 1 monthly pcts != 100.00 `[ref: PRD/Rule 4; SDD/Test Scenario 3]` `[activity: write-unit-tests]`
        - [ ] T4.1.5 Test: `validateSettings()` rejects Method 1 daily sales pcts != 100.00 `[ref: PRD/Rule 4]` `[activity: write-unit-tests]`
        - [ ] T4.1.6 Test: `validateSettings()` accepts $0 annual target `[ref: PRD/Scenario 9]` `[activity: write-unit-tests]`
        - [ ] T4.1.7 Test: `validateSettings()` rejects negative per-day Method 2 values `[ref: SDD/Validation rules]` `[activity: write-unit-tests]`
        - [ ] T4.1.8 Test: Method switch preserves all settings, only changes activeMethod `[ref: PRD/Rule 9; Scenario 4]` `[activity: write-unit-tests]`
        - [ ] T4.1.9 Test: Switching TO Method 2 auto-sets fallbackMethod to previous activeMethod `[ref: SDD/methodSettings JSON; line: 443-446]` `[activity: write-unit-tests]`
        - [ ] T4.1.10 Test: `updateConfig()` computes today's goal and passes it to audit as `calculatedGoalForDate` `[ref: PRD/Feature 7 - AC5; SDD/goalConfigAudit.calculatedGoalForDate]` `[activity: write-unit-tests]`
        - [ ] T4.1.11 Test: Sequential saves from two admins both create audit entries (concurrent edits — last save wins) `[ref: PRD/Scenario 5]` `[activity: write-unit-tests]`
        - [ ] T4.1.12 Implement: `GoalConfigService` `[activity: backend-implementation]`
        - [ ] T4.1.13 Validate: All config service tests pass `[activity: run-tests]`

    - [ ] T4.2 GoalForecastService `[component: service-layer]`
        - [ ] T4.2.1 Prime: Read forecast cache + recompute flow `[ref: SDD/Runtime View; lines: 927-936]`
        - [ ] T4.2.2 Test: `getDailyGoal(date)` reads from cache, returns DailyGoal `[activity: write-unit-tests]`
        - [ ] T4.2.3 Test: `getDailyGoal(date)` self-heals cache miss for configured store (on-demand calc + cache write) `[ref: SDD/Secondary Flow; line: 934]` `[activity: write-unit-tests]`
        - [ ] T4.2.4 Test: `getDailyGoal(date)` returns null for unconfigured store `[ref: SDD/Secondary Flow; line: 935]` `[activity: write-unit-tests]`
        - [ ] T4.2.5 Test: `getForecast(startDate, endDate)` returns array of DailyGoal within range `[ref: PRD/Feature 9 - AC1]` `[activity: write-unit-tests]`
        - [ ] T4.2.6 Test: `getForecast()` with includeHourly populates hourly distributions `[ref: PRD/Feature 9 - AC3]` `[activity: write-unit-tests]`
        - [ ] T4.2.7 Test: `recomputeFullYear(store)` deletes server rows, computes 365 days, batch inserts `[ref: PRD/Feature 2 - AC1; SDD/Test Scenario 6]` `[activity: write-unit-tests]`
        - [ ] T4.2.8 Test: `previewGoals(method, settings, dates)` calculates without saving `[ref: PRD/Feature 10 - AC4]` `[activity: write-unit-tests]`
        - [ ] T4.2.9 Test: Preview returns both proposed goals and current goals for comparison `[ref: PRD/Feature 10 - AC1, AC3]` `[activity: write-unit-tests]`
        - [ ] T4.2.10 Implement: `GoalForecastService` `[activity: backend-implementation]`
        - [ ] T4.2.11 Validate: All forecast service tests pass `[activity: run-tests]`

    - [ ] T4.3 GoalVarianceService `[component: service-layer]`
        - [ ] T4.3.1 Prime: Read variance endpoint spec `[ref: SDD/Internal API Changes; lines: 589-616]`
        - [ ] T4.3.2 Test: WTD variance — Monday start, correct day count through today `[ref: PRD/Feature 5 - AC1; Rule 11]` `[activity: write-unit-tests]`
        - [ ] T4.3.3 Test: MTD variance — first of month through today `[ref: PRD/Feature 5 - AC2]` `[activity: write-unit-tests]`
        - [ ] T4.3.4 Test: YTD variance — Jan 1 through today `[ref: PRD/Feature 5 - AC3]` `[activity: write-unit-tests]`
        - [ ] T4.3.5 Test: Trailing 7/30/90 — rolling window not aligned to boundaries `[ref: PRD/Feature 5 - AC4, AC5, AC6]` `[activity: write-unit-tests]`
        - [ ] T4.3.6 Test: Same-period-last-year comparison (YoY WTD/MTD/YTD) `[ref: PRD/Feature 5 - AC7]` `[activity: write-unit-tests]`
        - [ ] T4.3.7 Test: Variance with negative actuals (returns exceed sales) `[ref: PRD/Scenario 12]` `[activity: write-unit-tests]`
        - [ ] T4.3.8 Test: Variance with $0 goal → percentage = "N/A" `[ref: PRD/Scenario 9; SDD/Error Handling]` `[activity: write-unit-tests]`
        - [ ] T4.3.9 Test: All calculations use store timezone `[ref: PRD/Rule 11]` `[activity: write-unit-tests]`
        - [ ] T4.3.10 Implement: `GoalVarianceService` `[activity: backend-implementation]`
        - [ ] T4.3.11 Validate: All variance service tests pass `[activity: run-tests]`

    - [ ] T4.4 Phase Validate
        - [ ] T4.4.1 Run all service layer tests `[activity: run-tests]`
        - [ ] T4.4.2 Run PHPStan on `src/BuyerKiosk/Goals/Services/` `[activity: lint-code]`
        - [ ] T4.4.3 Verify service interfaces match SDD contracts `[activity: review-code]`

---

- [ ] T5 Phase 5: API Layer — Routes and Controller `[depends: T4]`

    *Delivers: GoalApiController with 6 endpoints, GoalSettingsPageController, route files.*

    - [ ] T5.1 Prime Context
        - [ ] T5.1.1 Read API endpoint specifications `[ref: SDD/Internal API Changes; lines: 492-648]`
        - [ ] T5.1.2 Read existing controller patterns `[ref: userfrosting/src/BuyerKiosk/StoreConfig/Controllers/StoreConfigController.php]`
        - [ ] T5.1.3 Read admin route patterns `[ref: userfrosting/routes/admin/store-config.php]`
        - [ ] T5.1.4 Read API route patterns `[ref: userfrosting/routes/store-config.php]`
        - [ ] T5.1.5 Read error handling pattern `[ref: SDD/Error Handling Pattern; lines: 1059-1074]`

    - [ ] T5.2 Write Tests — API Controller
        - [ ] T5.2.1 Test: GET /config returns config for store, 200 `[ref: SDD/API - Get Goal Configuration]` `[activity: write-unit-tests]`
        - [ ] T5.2.2 Test: GET /config returns hasServerGoals=false for unconfigured store `[activity: write-unit-tests]`
        - [ ] T5.2.3 Test: PUT /config validates and saves, returns updated config + audit `[ref: SDD/API - Update Goal Configuration]` `[activity: write-unit-tests]`
        - [ ] T5.2.4 Test: PUT /config returns 400 for invalid percentage sums `[ref: SDD/Test Scenario 3]` `[activity: write-unit-tests]`
        - [ ] T5.2.5 Test: PUT /config returns 403 for non-admin user `[activity: write-unit-tests]`
        - [ ] T5.2.6 Test: POST /preview returns preview + current goals without saving `[ref: SDD/API - Preview Goal Calculation]` `[activity: write-unit-tests]`
        - [ ] T5.2.7 Test: GET /forecast returns date range with optional hourly `[ref: SDD/API - Get Goal Forecast; SDD/Test Scenario 7]` `[activity: write-unit-tests]`
        - [ ] T5.2.8 Test: GET /forecast returns 400 for range > 365 days `[activity: write-unit-tests]`
        - [ ] T5.2.9 Test: GET /variance returns requested periods `[ref: SDD/API - Get Goal Variance]` `[activity: write-unit-tests]`
        - [ ] T5.2.10 Test: GET /audit returns paginated history with actor names `[ref: SDD/API - Get Goal Audit History]` `[activity: write-unit-tests]`
        - [ ] T5.2.11 Test: GET /audit with compareToId returns snapshot diff `[ref: PRD/Feature 7 - AC4]` `[activity: write-unit-tests]`
        - [ ] T5.2.12 Test: Manager can GET config and forecast but PUT returns 403 `[ref: PRD/Feature 4 - AC2]` `[activity: write-unit-tests]`
        - [ ] T5.2.13 Test: PUT /config with hourlyTimeBands saves and GET /config returns them `[ref: SDD/API - hourlyTimeBands round-trip; PRD/Feature 8]` `[activity: write-unit-tests]`

    - [ ] T5.3 Implement API Controller
        - [ ] T5.3.1 Create `GoalApiController` with lazy service initialization `[ref: SDD/Directory Map; line: 343]` `[activity: api-development]`
        - [ ] T5.3.2 Implement `getConfig()` action `[activity: api-development]`
        - [ ] T5.3.3 Implement `updateConfig()` action with validation, audit, async recompute dispatch `[activity: api-development]`
        - [ ] T5.3.4 Implement `previewGoals()` action `[activity: api-development]`
        - [ ] T5.3.5 Implement `getForecast()` action with date range validation `[activity: api-development]`
        - [ ] T5.3.6 Implement `getVariance()` action with period parsing `[activity: api-development]`
        - [ ] T5.3.7 Implement `getAuditHistory()` action with pagination and snapshot comparison `[activity: api-development]`

    - [ ] T5.4 Implement Page Controller
        - [ ] T5.4.1 Create `GoalSettingsPageController` following StoreConfigPageController pattern `[ref: SDD/Directory Map; line: 342]` `[activity: backend-implementation]`
        - [ ] T5.4.2 Implement `render()` — load config, pass to template as JSON `[activity: backend-implementation]`

    - [ ] T5.5 Implement Routes
        - [ ] T5.5.1 Create `routes/admin/goals.php` — admin page route with store validation `[ref: SDD/Directory Map; line: 366]` `[activity: api-development]`
        - [ ] T5.5.2 Create `routes/groups/goals-api.php` — REST API routes (6 endpoints) `[ref: SDD/Directory Map; line: 368]` `[activity: api-development]`
        - [ ] T5.5.3 Register both route files in `initialize.php` route loading `[activity: backend-implementation]`

    - [ ] T5.6 Validate
        - [ ] T5.6.1 Run all API controller tests `[activity: run-tests]`
        - [ ] T5.6.2 Run PHPStan on controllers and routes `[activity: lint-code]`
        - [ ] T5.6.3 Verify all 6 endpoints respond correctly via curl/browser `[activity: review-code]`
        - [ ] T5.6.4 Verify permission checks: admin can PUT, manager cannot `[activity: business-acceptance]`
        - [ ] T5.6.5 **Early integration checkpoint**: Run curl/browser tests against all 6 API endpoints with real data from pc00. Verify config CRUD, preview, forecast, variance, and audit all return expected responses. Catch integration issues before frontend work begins. `[activity: review-code]`

---

- [ ] T6 Phase 6: System Integration — DRS Route, KPI Service, TaskEngine Job `[depends: T4]` `[parallel: true with T5]`

    *Delivers: Sync fallback compatibility (DRS), KPI bar integration, nightly forecast job. Can parallelize with Phase 5.*

    - [ ] T6.1 DRS Route Modification `[component: integration]`
        - [ ] T6.1.1 Prime: Read DRS route LiveFinancials upsert code `[ref: userfrosting/routes/groups/drs.php; lines: 1109-1199]`
        - [ ] T6.1.2 Prime: Read SDD DRS integration example `[ref: SDD/Example: DRS Route; lines: 825-860]`
        - [ ] T6.1.3 Test: Server goal exists → Sync push blocked, server goals preserved in LiveFinancials `[ref: PRD/Feature 6 - AC3; SDD/Test Scenario 5]` `[activity: write-integration-tests]`
        - [ ] T6.1.4 Test: No server goal → Sync push accepted, written to goalForecast as sync_fallback `[ref: PRD/Feature 6 - AC2]` `[activity: write-integration-tests]`
        - [ ] T6.1.5 Test: Actuals (salesCurrent, buysCurrent) always update regardless of goal source `[ref: SDD/Test Scenario 5]` `[activity: write-integration-tests]`
        - [ ] T6.1.6 Test: Blocked Sync push is logged for diagnostics `[ref: PRD/Scenario 13]` `[activity: write-integration-tests]`
        - [ ] T6.1.7 Implement: Add server-goal priority check before LiveFinancials upsert `[ref: SDD/Example: DRS Route; lines: 830-860]` `[activity: backend-implementation]`
        - [ ] T6.1.8 Validate: Sync app push still works for unconfigured stores `[ref: PRD/Feature 6 - AC4]` `[activity: business-acceptance]`

    - [ ] T6.2 KPIService Integration `[component: integration]`
        - [ ] T6.2.1 Prime: Read KPIService current goal reading logic `[ref: userfrosting/src/BuyerKiosk/Workbook/KPIService.php]`
        - [ ] T6.2.2 Test: KPIService uses GoalForecastService::getDailyGoal() when available `[activity: write-integration-tests]`
        - [ ] T6.2.3 Test: KPIService falls back to LiveFinancials when GoalForecastService returns null `[activity: write-integration-tests]`
        - [ ] T6.2.4 Test: KPIService handles LiveFinancials integer format vs goalForecast DECIMAL format `[ref: SDD/Implementation Gotchas; line: 1213]` `[activity: write-integration-tests]`
        - [ ] T6.2.5 Test: Goal source indicator ('server' vs 'sync_fallback') propagated to KPI response `[ref: PRD/Feature 6 - AC5]` `[activity: write-integration-tests]`
        - [ ] T6.2.6 Implement: Modify KPIService to check GoalForecastService before LiveFinancials `[activity: backend-implementation]`
        - [ ] T6.2.7 Validate: KPI bar displays correct goal from both sources `[activity: business-acceptance]`

    - [ ] T6.3 TaskEngine Job `[component: integration]`
        - [ ] T6.3.1 Prime: Read BaseJob and PosDataCatchupJob patterns `[ref: userfrosting/src/BuyerKiosk/TaskEngine/Domain/Job/BaseJob.php]` `[ref: userfrosting/src/BuyerKiosk/PosDataCatchup/Jobs/PosDataCatchupJob.php]`
        - [ ] T6.3.2 Test: Job processes a single store — loads config, computes 365 days, writes to cache `[ref: PRD/Feature 2 - AC3]` `[activity: write-unit-tests]`
        - [ ] T6.3.3 Test: Job reports progress during computation `[activity: write-unit-tests]`
        - [ ] T6.3.4 Test: Job skips stores without goalConfigurations `[activity: write-unit-tests]`
        - [ ] T6.3.5 Test: Job handles PDO failure gracefully, returns JobResult::failure `[activity: write-unit-tests]`
        - [ ] T6.3.6 Implement: `GoalForecastComputeJob` extending BaseJob `[ref: SDD/Directory Map; line: 359]` `[activity: backend-implementation]`
        - [ ] T6.3.7 Register job definition in TaskEngine config `[activity: backend-implementation]`
        - [ ] T6.3.8 Validate: Manual dispatch works — `php userfrosting/bin/task job:dispatch goal-forecast-compute --store=pc00` `[activity: run-tests]`

    - [ ] T6.4 Phase Validate
        - [ ] T6.4.1 Run all integration tests `[activity: run-tests]`
        - [ ] T6.4.2 Verify DRS route still functions for non-goal payloads (no regression) `[activity: business-acceptance]`
        - [ ] T6.4.3 Verify KPI bar shows goals from both sources correctly `[activity: business-acceptance]`

---

- [ ] T7 Phase 7: Frontend — Admin Page, JS Controllers, CSS `[depends: T5]`

    *Delivers: Goal settings admin page with Syncfusion components, per-method panels, preview, audit history.*

    - [ ] T7.1 Prime Context
        - [ ] T7.1.1 Read SDD component structure pattern `[ref: SDD/Component Structure Pattern; lines: 1032-1057]`
        - [ ] T7.1.2 Read Syncfusion gotchas from MEMORY.md `[ref: MEMORY.md/Syncfusion EJ2 MultiSelect Gotchas]` `[ref: MEMORY.md/Syncfusion EJ2 Scheduler Gotcha]`
        - [ ] T7.1.3 Read admin page template patterns `[ref: userfrosting/templates/themes/default/admin/event-management/templates.html]`
        - [ ] T7.1.4 Read CSS design system tokens `[ref: public_html/css/admin/tokens.css]`

    - [ ] T7.1.5 **SPIKE**: Prototype Syncfusion Schedule month view with dual-input day cells (sales + buys). Verify cellTemplate renders inline NumericTextBox, cellClick triggers edit, and month navigation works. If Schedule cannot support dual inputs reliably, fall back to custom HTML grid with Syncfusion NumericTextBox per cell. `[ref: ADR-9; SDD/Implementation Gotchas; line: 1210-1211]` `[activity: frontend-implementation]`

    - [ ] T7.2 Implement Templates `[component: frontend]`
        - [ ] T7.2.1 Create `settings.html` — main page layout with Syncfusion Tab container, preview sidebar, meta tags for typeNum/config JSON `[ref: SDD/Directory Map; line: 374]` `[activity: frontend-implementation]`
        - [ ] T7.2.2 Create `method0-panel.html` — sales growth %, buys growth % with NumericTextBox `[ref: PRD/Feature 4 - AC6]` `[activity: frontend-implementation]`
        - [ ] T7.2.3 Create `method1-panel.html` — annual target, 12 monthly pcts, 7 daily pcts, 7 buys amounts with sum validation display `[ref: PRD/Feature 4 - AC7]` `[activity: frontend-implementation]`
        - [ ] T7.2.4 Create `method2-panel.html` — month selector, Syncfusion Schedule container, pre-fill button, average buttons `[ref: PRD/Feature 4 - AC8]` `[activity: frontend-implementation]`
        - [ ] T7.2.5 Create `preview-panel.html` — side-by-side current vs proposed, 7-day table `[ref: PRD/Feature 10 - AC1, AC3]` `[activity: frontend-implementation]`
        - [ ] T7.2.6 Create `audit-history.html` — paginated audit list, snapshot comparison view `[ref: PRD/Feature 7 - AC3, AC4]` `[activity: frontend-implementation]`

    - [ ] T7.3 Implement JavaScript Controllers `[component: frontend]`
        - [ ] T7.3.1 Create `goal-settings.js` — main page controller: Tab init, method switching, save/preview coordination, CSRF token `[ref: SDD/Component Structure Pattern; lines: 1034-1057]` `[activity: frontend-implementation]`
        - [ ] T7.3.2 Create `method0-controller.js` — NumericTextBox init, getValue(), destruction on tab switch `[activity: frontend-implementation]`
        - [ ] T7.3.3 Create `method1-controller.js` — 20+ NumericTextBox fields, real-time sum validation (red/green indicator), $0 target acceptance `[activity: frontend-implementation]`
        - [ ] T7.3.4 Create `method2-controller.js` — core Schedule/grid initialization with month navigation and cellTemplate rendering `[activity: frontend-implementation]`
        - [ ] T7.3.4a Method 2: Implement inline cellClick handler for editing sales+buys per day `[activity: frontend-implementation]`
        - [ ] T7.3.4b Method 2: Implement pre-fill from API (AJAX call to populate from Method 0/1 calculations) `[activity: frontend-implementation]`
        - [ ] T7.3.4c Method 2: Implement average weekday buttons (average all Mondays, all Tuesdays, etc.) `[ref: PRD/Rule 8; Scenario 6]` `[activity: frontend-implementation]`
        - [ ] T7.3.5 Create `preview-controller.js` — AJAX POST to /preview endpoint with 300ms debounce, render comparison table `[activity: frontend-implementation]`
        - [ ] T7.3.6 Implement audit history tab — paginated list, "Compare to current" button per entry `[activity: frontend-implementation]`

    - [ ] T7.4 Implement Styles
        - [ ] T7.4.1 Create `goals.css` — page layout, method panels, preview panel, validation indicators, confidence badges `[ref: SDD/Directory Map; line: 391]` `[activity: frontend-implementation]`
        - [ ] T7.4.2 Build CSS: `php userfrosting/conductor build-css --minify` `[activity: frontend-implementation]`

    - [ ] T7.5 Validate
        - [ ] T7.5.1 Manual test: Navigate to `/admin/pc00/goals`, verify page renders `[activity: business-acceptance]`
        - [ ] T7.5.2 Manual test: Tab switching initializes/destroys Syncfusion components correctly `[activity: business-acceptance]`
        - [ ] T7.5.3 Manual test: Method 1 sum validation shows red when != 100%, disables save `[ref: PRD/Scenario 3]` `[activity: business-acceptance]`
        - [ ] T7.5.4 Manual test: Method 2 Schedule month view renders, inline edit works for sales+buys `[activity: business-acceptance]`
        - [ ] T7.5.5 Manual test: Preview updates on parameter change with debounce `[ref: PRD/Feature 10 - AC2]` `[activity: business-acceptance]`
        - [ ] T7.5.6 Manual test: Save triggers toast, audit entry created `[activity: business-acceptance]`
        - [ ] T7.5.7 Manual test: Audit history displays, snapshot comparison works `[ref: PRD/Feature 7 - AC4]` `[activity: business-acceptance]`
        - [ ] T7.5.8 Manual test: Manager sees read-only view (save button hidden) `[ref: PRD/Feature 4 - AC2]` `[activity: business-acceptance]`
        - [ ] T7.5.9 Manual test: Confidence indicator badge visible in preview `[ref: PRD/Feature 3 - AC4]` `[activity: business-acceptance]`
        - [ ] T7.5.10 Manual test: Settings preserved on method switch `[ref: PRD/Rule 9; Scenario 4]` `[activity: business-acceptance]`
        - [ ] T7.5.11 Manual test: Method 2 "Average Saturdays" recalculates all Saturday cells including previously edited ones `[ref: PRD/Scenario 6; Rule 8]` `[activity: business-acceptance]`
        - [ ] T7.5.12 Manual test: Method 2 day set to $0 for planned closure, verify $0 goal saved and forecasted `[ref: PRD/Scenario 10; Rule 13]` `[activity: business-acceptance]`

---

- [ ] T8 Phase 8: Integration & End-to-End Validation `[depends: T5, T6, T7]`

    *Delivers: Full system validation — cross-component testing, performance, security, PRD acceptance.*

    - [ ] T8.1 Cross-Component Testing
        - [ ] T8.1.1 All unit tests pass (calculation engine, services, repositories, models) `[activity: run-tests]`
        - [ ] T8.1.2 All integration tests pass (DRS route, KPI bar, TaskEngine job) `[activity: run-tests]`
        - [ ] T8.1.3 PHPStan clean on entire `src/BuyerKiosk/Goals/` directory `[activity: lint-code]`

    - [ ] T8.2 End-to-End Flows
        - [ ] T8.2.1 E2E: First-time setup — navigate to goals page, see smart defaults, configure Method 0, save, verify forecast computed `[ref: PRD/Feature 4]` `[activity: write-e2e-tests]`
        - [ ] T8.2.2 E2E: Method switch — change from Method 0 to Method 1, verify settings preserved, preview shows comparison, save triggers recompute `[ref: PRD/Rule 9; Feature 10]` `[activity: write-e2e-tests]`
        - [ ] T8.2.3 E2E: Method 2 calendar — select month, pre-fill from Method 0, edit days, use average button, save, verify forecast uses per-day values `[ref: PRD/Feature 1 - AC3]` `[activity: write-e2e-tests]`
        - [ ] T8.2.4 E2E: Sync fallback — new store with no config, Sync pushes goals, verify accepted. Then configure server goals, verify Sync push blocked `[ref: PRD/Feature 6; SDD/Test Scenario 5]` `[activity: write-e2e-tests]`
        - [ ] T8.2.5 E2E: KPI bar integration — configure goals, load workbook, verify KPI bar shows server-calculated goal with source badge `[ref: PRD/Feature 5 - AC9]` `[activity: write-e2e-tests]`
        - [ ] T8.2.6 E2E: Variance display — configure goals, wait for actuals, verify WTD/MTD variance calculations `[ref: PRD/Feature 5]` `[activity: write-e2e-tests]`
        - [ ] T8.2.7 E2E: Forecast API — call /api/:typeNum/goals/forecast with date range and includeHourly=true, verify response structure `[ref: PRD/Feature 9; SDD/Test Scenario 7]` `[activity: write-e2e-tests]`
        - [ ] T8.2.8 E2E: Audit trail — make config changes, view audit history, compare snapshot to current `[ref: PRD/Feature 7]` `[activity: write-e2e-tests]`

    - [ ] T8.3 Performance Validation
        - [ ] T8.3.1 Forecast API response < 200ms for 7-day range (cached reads) `[ref: SDD/Quality Requirements - Performance]` `[activity: run-tests]`
        - [ ] T8.3.2 Preview endpoint response < 100ms `[ref: SDD/Quality Requirements - Performance]` `[activity: run-tests]`
        - [ ] T8.3.3 Full 365-day recompute < 5s per store `[ref: SDD/Quality Requirements - Performance]` `[activity: run-tests]`
        - [ ] T8.3.4 Batch insert 365 forecast rows < 1s `[activity: run-tests]`

    - [ ] T8.4 Security Validation
        - [ ] T8.4.1 Admin-only endpoints (PUT /config, GET /audit) reject non-admin users `[ref: SDD/Cross-Cutting - Security]` `[activity: security-review]`
        - [ ] T8.4.2 Manager view-only endpoints return data but no edit capability `[ref: PRD/Feature 4 - AC2]` `[activity: security-review]`
        - [ ] T8.4.3 CSRF token validated on admin page form submissions `[activity: security-review]`
        - [ ] T8.4.4 SQL injection prevention — all inputs use parameterized queries `[activity: security-review]`
        - [ ] T8.4.5 Store scoping — checkStoreGroup prevents cross-store access `[activity: security-review]`

    - [ ] T8.5 Edge Case Validation
        - [ ] T8.5.1 Brand new store with zero history → Method 0 cascades to defaults `[ref: PRD/Scenario 1]` `[activity: business-acceptance]`
        - [ ] T8.5.2 Prior year holiday ($0 sales) → $0 goal with confidence flag `[ref: PRD/Scenario 2]` `[activity: business-acceptance]`
        - [ ] T8.5.3 Feb 29 target date → maps to Feb 28, confidence downgraded `[ref: PRD/Scenario 7]` `[activity: business-acceptance]`
        - [ ] T8.5.4 $0 annual target → all goals $0, variance shows "N/A" percentage `[ref: PRD/Scenario 9]` `[activity: business-acceptance]`
        - [ ] T8.5.5 Negative actuals → variance dollars negative, percentage computed correctly `[ref: PRD/Scenario 12]` `[activity: business-acceptance]`
        - [ ] T8.5.6 Method 2 unconfigured month → falls back to fallbackMethod `[ref: PRD/Scenario 14]` `[activity: business-acceptance]`
        - [ ] T8.5.7 DST transition day → daily goals unaffected, hourly absorbs the delta `[ref: PRD/Scenario 11]` `[activity: business-acceptance]`
        - [ ] T8.5.8 Config save mid-day → today's goal updates on next KPI bar refresh `[ref: PRD/Scenario 8]` `[activity: business-acceptance]`

    - [ ] T8.6 Final Acceptance
        - [ ] T8.6.1 All PRD Must Have features (1-7) acceptance criteria verified `[ref: PRD/Feature Requirements; lines: 108-188]` `[activity: business-acceptance]`
        - [ ] T8.6.2 All PRD Should Have features (8-10) acceptance criteria verified `[ref: PRD/Feature Requirements; lines: 189-220]` `[activity: business-acceptance]`
        - [ ] T8.6.3 All PRD business rules (1-14) verified `[ref: PRD/Business Rules; lines: 280-293]` `[activity: business-acceptance]`
        - [ ] T8.6.4 Implementation follows SDD architecture (4 services, 4 repos, 2 controllers) `[activity: review-code]`
        - [ ] T8.6.5 All 10 ADRs honored `[ref: SDD/Architecture Decisions; lines: 1131-1182]` `[activity: review-code]`
        - [ ] T8.6.6 Test coverage > 80% for `src/BuyerKiosk/Goals/` `[activity: run-tests]`
        - [ ] T8.6.7 No PHPStan errors at configured level `[activity: lint-code]`
        - [ ] T8.6.8 CSS build passes: `php userfrosting/conductor build-css --minify` `[activity: run-tests]`
        - [ ] T8.6.9 Nightly cron job runs successfully for at least 3 stores `[activity: business-acceptance]`
        - [ ] T8.6.10 Mobile API documentation updated in `docs/api/` for forecast and variance endpoints `[activity: review-code]`

---

## PRD → Implementation Traceability Matrix

| PRD Feature | Phase(s) | Key Tasks |
|-------------|----------|-----------|
| F1: Goal Calculation Engine | T2 | T2.2-T2.7 (all methods), T2.8 (parity) |
| F2: 365-Day Forecasting | T4.2, T6.3 | T4.2.7 (recompute), T6.3.2-T6.3.6 (job) |
| F3: Smart Fallback | T2.5 | T2.5.1-T2.5.4 (cascade tiers) |
| F4: Admin Page | T5.4, T7 | T5.4.1-T5.4.2 (controller), T7.2-T7.3 (UI) |
| F5: Variance Suite | T4.3 | T4.3.2-T4.3.9 (all periods) |
| F6: Sync Fallback | T6.1 | T6.1.3-T6.1.7 (DRS mod) |
| F7: Audit Trail | T3.4, T5.2.10-T5.2.11, T7.3.6 | T3.4.2-T3.4.8 (repo), T5.3.7 (API), T7.2.6 (UI) |
| F8: Hourly Distribution | T2.6, T2.7.8 | T2.6.1-T2.6.4 (tests), T2.7.8 (impl) |
| F9: Forecast API | T5.2.7-T5.2.8, T5.3.5 | T5.2.7 (test), T5.3.5 (impl) |
| F10: Preview | T4.2.8-T4.2.9, T5.2.6, T7.3.5 | T4.2.8 (service), T5.3.4 (API), T7.3.5 (JS) |
| F11-13: Deferred | — | Noted as excluded in SDD scope |
