- Add scripts/setup-db.ts to programmatically create missing PocketBase
collections (period_logs, dailyLogs) with proper relation fields
- Fix dark mode visibility across settings, login, calendar, and dashboard
components by using semantic CSS tokens and dark: variants
- Add db:setup npm script and document usage in AGENTS.md
- Update vitest config to include scripts directory tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Users without a lastPeriodDate can now set it via a modal opened from
the onboarding banner. The dashboard now fetches user data independently
so the banner shows even when /api/today fails due to missing period date.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Per dashboard.md spec requirements:
- RED background and text for REST decisions
- YELLOW background and text for GENTLE/LIGHT/REDUCED decisions
- GREEN background and text for TRAIN decisions
Added 8 new tests for color-coded backgrounds (19 total).
Updated IMPLEMENTATION_PLAN.md to mark spec gap as complete.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CRITICAL BUG FIX:
- Phase boundaries were hardcoded for 31-day cycle, breaking correct
phase calculations for users with different cycle lengths (28, 35, etc.)
- Added getPhaseBoundaries(cycleLength) function in cycle.ts
- Updated getPhase() to accept cycleLength parameter (default 31)
- Updated all callers (API routes, components) to pass cycleLength
- Added 13 new tests for phase boundaries with 28, 31, and 35-day cycles
ICS IMPROVEMENTS:
- Fixed emojis to match calendar.md spec: 🩸🌱🌸🌙🌑
- Added CATEGORIES field for calendar app colors per spec:
MENSTRUAL=Red, FOLLICULAR=Green, OVULATION=Pink,
EARLY_LUTEAL=Yellow, LATE_LUTEAL=Orange
- Added 5 new tests for CATEGORIES
Updated IMPLEMENTATION_PLAN.md with discovered issues and test counts.
825 tests passing (up from 807)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement keyboard navigation for MonthView calendar:
- ArrowLeft/Right: navigate to previous/next day
- ArrowUp/Down: navigate to previous/next week (7 days)
- Home/End: navigate to first/last day of month
- Boundary navigation triggers month change
Features:
- Added role="grid" for proper ARIA semantics
- Added data-day attribute to DayCell for focus management
- Wrapped navigation handlers in useCallback for stability
Tests: 9 new tests for keyboard navigation (790 total)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add skip navigation link to root layout
- Add semantic HTML landmarks (main element) to login and settings pages
- Add aria-labels to calendar day buttons with date, cycle day, and phase info
- Add id="main-content" to dashboard main element for skip link target
- Fix pre-existing type error in auth-middleware.test.ts
Tests: 781 passing (11 new accessibility tests)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement OnboardingBanner component that prompts new users to complete
setup with contextual banners for:
- Garmin connection (links to /settings/garmin)
- Period date (button with callback for date picker)
- Notification time (links to /settings)
Banners display at the top of the dashboard when setup is incomplete,
with icons and styled action buttons. Each banner uses role="alert"
for accessibility.
- Add OnboardingBanner component (16 tests)
- Integrate into dashboard page (5 new tests, 28 total)
- Update UserData interface to include garminConnected, notificationTime
- Test count: 770 tests across 43 files
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add skeleton loading components per specs/dashboard.md requirements:
- DecisionCardSkeleton: Shimmer placeholder for status and reason
- DataPanelSkeleton: Skeleton rows for 5 metrics
- NutritionPanelSkeleton: Skeleton for nutrition guidance
- MiniCalendarSkeleton: Placeholder grid with navigation and legend
- OverrideTogglesSkeleton: 4 toggle placeholders
- CycleInfoSkeleton: Cycle day and phase placeholders
- DashboardSkeleton: Combined skeleton for route-level loading
Add Next.js loading.tsx files for instant loading states:
- src/app/loading.tsx (Dashboard)
- src/app/calendar/loading.tsx
- src/app/history/loading.tsx
- src/app/plan/loading.tsx
- src/app/settings/loading.tsx
Update dashboard page to use DashboardSkeleton instead of "Loading..." text.
Fix flaky garmin test with wider date tolerance for timezone variations.
29 new tests in skeletons.test.tsx (749 total tests passing).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Complete the MiniCalendar component with:
- Full calendar grid showing all days of the month
- Phase colors applied to each day
- Today highlighting with ring indicator
- Navigation buttons (prev/next month, Today)
- Compact phase legend
- Integration into dashboard page (shows when lastPeriodDate exists)
Adds 23 new tests for the MiniCalendar component covering:
- Calendar grid rendering
- Phase color application
- Navigation functionality
- Cycle rollover handling
- Custom year/month props
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Set up Next.js 16 project with TypeScript for a training decision app
that integrates menstrual cycle phases with Garmin biometrics for
Hashimoto's thyroiditis management.
Stack: Next.js 16, React 19, Tailwind/shadcn, PocketBase, Drizzle,
Zod, Resend, Vitest, Biome, Lefthook, Nix dev environment.
Includes:
- 7 page routes (dashboard, login, settings, calendar, history, plan)
- 12 API endpoints (garmin, user, cycle, calendar, overrides, cron)
- Core lib utilities (decision engine, cycle phases, nutrition, ICS)
- Type definitions and component scaffolding
- Python script for Garmin token bootstrapping
- Initial unit tests for cycle utilities
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>