# S03: Homepage Stats Scorecard — UAT

**Milestone:** M015
**Written:** 2026-04-03T04:30:55.043Z

## UAT: Homepage Stats Scorecard

### Preconditions
- Chrysopedia stack running on ub01 (API + web containers healthy)
- At least 1 technique page and 1 creator exist in PostgreSQL

### Test 1: Stats API returns valid data
1. Run: `curl -s http://ub01:8096/api/v1/stats`
2. **Expected:** JSON response `{"technique_count": N, "creator_count": N}` where both N > 0
3. Verify HTTP status: `curl -s -o /dev/null -w '%{http_code}' http://ub01:8096/api/v1/stats` → `200`

### Test 2: Scorecard visible on homepage
1. Open http://ub01:8096 in a browser
2. Scroll to the section between the how-it-works cards and the "Random Technique" button
3. **Expected:** A scorecard section shows two metrics — article count (e.g., "21") and creator count (e.g., "7")
4. Numbers should be in cyan/accent color, labels ("ARTICLES", "CREATORS") in muted text below
5. Section should have a subtle dark surface background with a border

### Test 3: Scorecard uses live data
1. Note the current technique_count from the API
2. Add a new technique page via the pipeline (or verify count matches DB: `SELECT count(*) FROM technique_pages`)
3. Refresh the homepage
4. **Expected:** The article count matches the current database count

### Test 4: Frontend build succeeds
1. Run: `cd frontend && npm run build`
2. **Expected:** Build completes with exit code 0, no TypeScript errors

### Test 5: Scorecard handles empty state gracefully
1. If stats fetch fails (API down), the scorecard section should not render (no empty/broken UI)
2. The rest of the homepage should remain functional

### Edge Cases
- **API unavailable:** Scorecard section is conditionally rendered — hidden when stats are null
- **Zero counts:** Would display "0" — acceptable but unlikely in production (data always exists)
