# Specification: 043-pos-data-catchup

## Status

| Field | Value |
|-------|-------|
| **Created** | 2026-04-01 |
| **Current Phase** | Implementation Plan Complete — Ready for Implementation |
| **Last Updated** | 2026-04-01 |

## Documents

| Document | Status | Notes |
|----------|--------|-------|
| product-requirements.md | completed | Codex-reviewed and refined (2026-04-01) |
| solution-design.md | completed | All 6 ADRs confirmed |
| implementation-plan.md | completed | 5 phases, 13 new files, TDD approach |

**Status values**: `pending` | `in_progress` | `completed` | `skipped`

## Decisions Log

| Date | Decision | Rationale |
|------|----------|-----------|
| 2026-04-01 | Transaction data only (no metadata) | Metadata changes rarely, no date-based gaps to detect |
| 2026-04-01 | Filter stores by drsApiKey | Existing column indicates DRS integration — no new config needed |
| 2026-04-01 | Configurable lookback per store, default 365 days | Need full year of data for Y-o-Y goals and forecasting |
| 2026-04-01 | Use buyQueue + storeOperatingHours | buyQueue is independent verifier of store activity; hours tables provide fallback |
| 2026-04-01 | Desktop app already has Ably listener | Extending existing channel, not building new communication path |
| 2026-04-01 | New stores get FULL backfill (not skipped) | Every store needs 1 year of data for realistic goals |
| 2026-04-01 | Desktop reports "earliest available date" | Prevents infinite false-positive gaps for newer stores |
| 2026-04-01 | Desktop ack moved to Could Have | Desktop may be offline; just re-send commands each cycle |
| 2026-04-01 | Large backfills chunked into 30-day batches | Prevents overwhelming desktop app with 365-day requests |
| 2026-04-01 | Ably messages are ephemeral — server re-publishes | No reliance on Ably history/replay; gap state persisted in DB |
| 2026-04-01 | DST: date boundaries use store timezone midnight-to-midnight | Calendar dates, not hour counts; DST transitions handled by timezone |

## Reviews

### PRD Review (Codex) — 2026-04-01

**Reviewer**: Codex (o3) via `mcp__codex__codex`

**Findings Summary**:
- 2 items flagged as "Blocker" by Codex — both already resolved (open questions answered in SDD, delivery model now clarified)
- 5 "Important" items — all addressed with PRD edits
- 3 "Enhancement" items — 1 addressed (checklist alignment), 2 deferred (no baseline data exists)

**Changes Made**:
1. Added explicit Ably delivery model: ephemeral messages, server re-publishes each cycle (not history-dependent)
2. Tightened vague acceptance criteria: "batched sensibly" → "30-day configurable chunks", timeout → "600 seconds"
3. Added "unavailable" gap status and 7-day persistent threshold default to Feature 3
4. Clarified progress formula in Feature 6 (phase-based percentage + specific metrics in result)
5. Added DST edge case for timezone day boundaries
6. Added explicit Dependencies section (6 dependencies with owners and status)
7. Updated open questions to cross-reference SDD decisions (all 4 now resolved)
8. Added Ably ephemeral messaging assumption to Assumptions section
9. Updated checklist to acknowledge intentional system references in PRD

**Rejected/Deferred**:
- "Add baseline gap frequency quantification" — No baseline exists; this IS the problem (no gap detection today)
- "Add current data completeness baseline" — Same reason; we're building the measurement system

**Verdict**: PRD is SDD-ready (SDD already completed with all ADRs confirmed)

## Context

**User Request:** Implement a method of catchup on data APIs to communicate with the desktop POS integration app. Need to backfill data for missed days using TaskEngine for gap detection and Ably for signaling the desktop app to retrieve and post missing data.

**Key Systems Identified:**
- **TaskEngine**: Full job infrastructure with per-store scope, scheduling, progress tracking, retry logic
- **Ably**: Pub/sub messaging already used for store-scoped events on `{typeNum}` channels
- **POS Data APIs**: Sales, Buys, Metadata, Daily Close endpoints already accept date-ranged data via JSON
- **Desktop App (DRS)**: Pull-based integration using API key auth, no existing push/command mechanism
- **Data Tables**: `kiosk_sales.sales`, `kiosk_sales.buys`, per-store `drsDailySFileData`, metadata tables

**Key Architecture Insight:** Currently the desktop app is 100% pull-based (it initiates all requests). This feature introduces a server-initiated push model via Ably to tell the desktop app "go fetch data for these dates."

---
*This file is managed by the specification-management skill.*
