Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a61768c
Upgrade to Next.js 16 — fix critical bugs & DB initialization race
GMSoudersJr Apr 17, 2026
6b1e6ec
fix(skip): build skipped day payload inside handler — eliminates shar…
GMSoudersJr Apr 17, 2026
19d41ae
fix(past-workouts): copy array before reversing to avoid in-place sta…
GMSoudersJr Apr 17, 2026
b4185e3
fix(charts): clear SVG children before re-rendering to prevent DOM ac…
GMSoudersJr Apr 17, 2026
9f20b0a
fix(review): remove circular dataToGet state — use params directly in…
GMSoudersJr Apr 17, 2026
88c1843
fix(timer): set audio volume before play — silence autoplay errors
GMSoudersJr Apr 17, 2026
8b793ae
fix(a11y): add role=dialog, aria-modal, aria-label, and Escape key to…
GMSoudersJr Apr 17, 2026
f600435
fix(save): add saving state, prevent double-save, fix prop mutation, …
GMSoudersJr Apr 17, 2026
00b2505
chore: remove unused /api/program/review route
GMSoudersJr Apr 17, 2026
9aef13a
chore: remove duplicate makeTransaction from index.ts
GMSoudersJr Apr 17, 2026
c41fc0a
test: add skip day-advancement and Escape key modal tests
GMSoudersJr Apr 17, 2026
f64b040
test: increase timer modal wait timeout from 91s to 95s — add margin …
GMSoudersJr Apr 17, 2026
89ea555
fix(review): show skipped days in day history — add SKPD rendering ca…
GMSoudersJr Apr 19, 2026
871bc40
fix(tests): resolve flaky and failing Playwright tests — timer race, …
GMSoudersJr Apr 19, 2026
ec30b0b
test: fix E2E anti-patterns and improve CI observability
GMSoudersJr Apr 20, 2026
eddd041
test: add GitHub Actions reporter for live CI test progress
GMSoudersJr Apr 20, 2026
4ded1b3
test: switch CI reporter to list for visible per-test progress in Act…
GMSoudersJr Apr 20, 2026
d889c45
test: revert closeTimerModal self-contained change — caused CI hangs
GMSoudersJr Apr 20, 2026
d658222
ci: restrict CI to Mobile Chrome only
GMSoudersJr Apr 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
run: npx playwright test --project="Mobile Chrome"
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
Expand Down
48 changes: 48 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

```bash
npm run dev # Start development server
npm run build # Production build
npm run lint # ESLint
npx playwright test # Run all E2E tests (builds first)
npx playwright test tests/dayOnePage.spec.ts # Run a single test file
npx playwright test --ui # Open Playwright UI
```

Pre-commit hooks run Prettier on all staged files via husky + lint-staged.

## Architecture

**Stack:** Next.js 14 (App Router), React 18, TypeScript, CSS Modules, D3, Serwist (PWA/service worker).

**Local-first:** All user data is stored in IndexedDB — no backend, no user accounts. The app works offline as a PWA. Two IndexedDB object stores live in `armstrong_pullup_program_db` (v4):
- `workoutsStore` — completed workout records (`TDayComplete`), keyed by `id` (UUID string)
- `weeksStore` — week progress records (`TWeek`), keyed by `number`

All IDB logic is in `src/app/lib/data/indexedDB/`. Components that use IndexedDB must be client components with `ssr: false` via `next/dynamic`.

**Route groups:**
- `src/app/(app)/program/` — the workout program pages (days 1–5) and review modal
- `src/app/(marketing)/` — landing page
- `src/app/(privacy)/privacy/` — privacy policy

**Parallel routes:** The program layout (`(app)/program/layout.tsx`) uses a `@modal` slot for the review modal, implemented as a Next.js intercepting route at `(.)review/[getData]/[index]`.

**Day types** (`TDayAbbreviation`):
- `5MES` — Five Max Effort Sets (Day 1 / Day 5 option)
- `PYRA` — Pyramid (Day 2 / Day 5 option)
- `3S3G` — Three Training Sets, Three Grips (Day 3 / Day 5 option)
- `MXTS` — Max Training Sets (Day 4 / Day 5 option)
- `SKPD` — Skipped day

Each day type has its own component subdirectory under `src/components/program/` (e.g., `fiveMaxEffortSets/`, `pyramid/`, `threeTrainingSetsThreeGrips/`, `maxTrainingSets/`).

**Program flow:** `Program.tsx` reads from IndexedDB to determine the current week and last completed day, then renders the appropriate day component. On completion, it writes a `TDayComplete` record to `workoutsStore` and updates `weeksStore`. `PastWorkouts.tsx` renders D3-based data visualizations of prior workouts.

**Path aliases:** `@/` maps to `src/app/lib/` (see tsconfig). E.g., `@/definitions` → `src/app/lib/definitions.ts`, `@/indexedDBConstants` → `src/app/lib/data/indexedDB/constants.ts`.

**Tests:** Playwright E2E tests in `tests/`, running against Desktop Firefox and Mobile Chrome (Pixel 5). Tests require a production build (`npm run build && npm run start`).
Loading
Loading