Commit Graph

39 Commits

Author SHA1 Message Date
6ebd9788e1 Fix docker extraCommands to copy hidden files
All checks were successful
Deploy / deploy (push) Successful in 1m36s
Same issue as installPhase - need to use /. suffix instead of /* glob
to include hidden directories like .next.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:06:28 +00:00
f2794cf396 Fix docker.nix to copy hidden .next directory
Some checks failed
Deploy / deploy (push) Failing after 1m35s
The glob * doesn't include hidden files/directories. Use /. suffix
to copy all contents including .next from standalone output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:17:34 +00:00
8f643c299d Add Nomad deployment configuration and CI/CD pipeline
Some checks failed
Deploy / deploy (push) Failing after 1m43s
- Add docker.nix for Nix-based Docker image builds
- Update flake.nix with dockerImage package output
- Add output: standalone to next.config.ts for production builds
- Add /metrics endpoint for Prometheus scraping
- Add Gitea Actions workflow calling shared deploy-nomad.yaml

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:20:20 +00:00
9c5b8466f6 Implement skeleton loading states for dashboard and routes (P3.8)
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>
2026-01-11 09:32:09 +00:00
714194f2d3 Implement structured logging for API routes (P3.7)
Replace console.error with pino structured logger across API routes
and add key event logging per observability spec:
- Auth failure (warn): reason
- Period logged (info): userId, date
- Override toggled (info): userId, override, enabled
- Decision calculated (info): userId, decision, reason
- Error events (error): err object with stack trace

Files updated:
- auth-middleware.ts: Added structured logging for auth failures
- cycle/period/route.ts: Added Period logged event + error logging
- calendar/[userId]/[token].ics/route.ts: Replaced console.error
- overrides/route.ts: Added Override toggled events
- today/route.ts: Added Decision calculated event

Tests: 720 passing (added 3 new structured logging tests)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:19:55 +00:00
00d902a396 Implement OIDC authentication with Pocket-ID (P2.18)
Add OIDC/OAuth2 authentication support to the login page with automatic
provider detection and email/password fallback.

Features:
- Auto-detect OIDC provider via PocketBase listAuthMethods() API
- Display "Sign In with Pocket-ID" button when OIDC is configured
- Use PocketBase authWithOAuth2() popup-based OAuth2 flow
- Fall back to email/password form when OIDC not available
- Loading states during authentication
- Error handling with user-friendly messages

The implementation checks for available auth methods on page load and
conditionally renders either the OIDC button or the email/password form.
This allows production deployments to use OIDC while development
environments can continue using email/password.

Tests: 24 tests (10 new OIDC tests added)
- OIDC button rendering when provider configured
- OIDC authentication flow with authWithOAuth2
- Loading and error states for OIDC
- Fallback to email/password when OIDC unavailable

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:12:29 +00:00
267d45f98a Add component tests for P3.11 (82 tests across 5 files)
- DecisionCard tests: 11 tests covering rendering, status icons, styling
- DataPanel tests: 18 tests covering biometrics display, null handling, styling
- NutritionPanel tests: 12 tests covering seeds, carbs, keto guidance display
- OverrideToggles tests: 18 tests covering toggle states, callbacks, styling
- DayCell tests: 23 tests covering phase coloring, today highlighting, click handling

Total tests now: 707 passing across 40 test files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:02:34 +00:00
39198fdf8c Implement Plan page with phase overview and exercise reference (P2.13)
Add comprehensive training plan reference page that displays:
- Current phase status (day, phase name, training type, weekly limit)
- Phase overview cards for all 5 cycle phases with weekly intensity limits
- Strength training exercises reference with sets and reps
- Rebounding techniques organized by phase
- Weekly training guidelines for each phase

The page fetches cycle data from /api/cycle/current and highlights
the current phase. Implements full TDD with 16 tests covering loading
states, error handling, phase display, and exercise reference sections.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:56:52 +00:00
b2915bca9c Implement MiniCalendar dashboard widget (P2.14)
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>
2026-01-11 08:47:28 +00:00
5a0cdf7450 Implement Prometheus metrics endpoint (P2.16)
Add comprehensive metrics collection for production monitoring:
- src/lib/metrics.ts: prom-client based metrics library with custom counters,
  gauges, and histograms for Garmin sync, email, and decision engine
- GET /api/metrics: Prometheus-format endpoint for scraping
- Integration into garmin-sync cron: sync duration, success/failure counts,
  active users gauge
- Integration into email.ts: daily and warning email counters
- Integration into decision-engine.ts: decision type counters

Custom metrics implemented:
- phaseflow_garmin_sync_total (counter with status label)
- phaseflow_garmin_sync_duration_seconds (histogram)
- phaseflow_email_sent_total (counter with type label)
- phaseflow_decision_engine_calls_total (counter with decision label)
- phaseflow_active_users (gauge)

33 new tests (18 library + 15 route), bringing total to 586 tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:40:42 +00:00
5ec3aba8b3 Implement structured logging with pino (P2.17)
Add pino-based logger module for production observability:
- JSON output to stdout for log aggregators (Loki, ELK)
- Configurable via LOG_LEVEL environment variable (defaults to "info")
- Log levels: error, warn, info, debug
- Error objects serialized with type, message, and stack trace
- Child logger support for bound context
- ISO 8601 timestamps in all log entries

Test coverage: 16 tests covering JSON format, log levels, error
serialization, and child loggers.

Total tests now: 553 passing across 31 test files.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:29:31 +00:00
2ffee63a59 Implement token expiration warnings (P3.9)
Add email warnings for Garmin token expiration at 14-day and 7-day thresholds.
When the garmin-sync cron job runs, it now checks each user's token expiry and
sends a warning email at exactly 14 days and 7 days before expiration.

Changes:
- Add sendTokenExpirationWarning() to email.ts with differentiated subject
  lines and urgency levels for 14-day vs 7-day warnings
- Integrate warning logic into garmin-sync cron route using daysUntilExpiry()
- Track warnings sent in sync response with new warningsSent counter
- Add 20 new tests (10 for email function, 10 for sync integration)

Test count: 517 → 537

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:24:19 +00:00
6c3dd34412 Implement health check endpoint (P2.15)
Add GET /api/health endpoint for deployment monitoring and load balancer
health probes. Returns 200 with status "ok" when PocketBase is reachable,
503 with status "unhealthy" when PocketBase connection fails.

Response includes timestamp (ISO 8601), version, and error message (on failure).
Uses PocketBase SDK's built-in health.check() method for connectivity testing.

14 tests covering healthy/unhealthy states and edge cases.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:17:13 +00:00
6a8d55c0b9 Document spec gaps: auth, phase scaling, observability, testing
Address 21 previously undefined behaviors across specs:

- Authentication: Replace email/password with OIDC (Pocket-ID)
- Cycle tracking: Add fixed-luteal phase scaling formula with examples
- Calendar: Document period logging behavior (preserve predictions)
- Garmin: Clarify connection is required (no phase-only mode)
- Dashboard: Add UI states, dark mode, onboarding, accessibility
- Notifications: Document timezone batching approach
- New specs: observability.md (health, metrics, logging)
- New specs: testing.md (unit + integration strategy)
- Main spec: Add backup/recovery, known limitations, API updates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 07:49:56 +00:00
97a424e41d Implement Calendar page with MonthView and ICS subscription (P2.11)
- Complete MonthView component with calendar grid, DayCell integration,
  navigation controls (prev/next month, Today button), and phase legend
- Implement Calendar page with MonthView, month navigation state,
  ICS subscription section with URL display, copy, and token regeneration
- Add 21 tests for MonthView component (calendar grid, phase colors,
  navigation, legend, cycle rollover)
- Add 23 tests for Calendar page (rendering, navigation, ICS subscription,
  token regeneration, error handling)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 21:42:40 +00:00
742f220be5 Implement Garmin settings page with token management UI (P2.10)
- Add full Garmin connection management page at /settings/garmin
- Display connection status with colored indicators (green/red/gray)
- Show token expiry warnings (yellow 14 days, red 7 days)
- Token input form with JSON validation for bootstrap script output
- Disconnect functionality with confirmation
- Loading and error states throughout
- Add link from Settings page to Garmin settings
- 27 tests for Garmin settings page
- 3 additional tests for Settings page Garmin link

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 21:28:06 +00:00
be80c60253 Implement History page with table view and pagination (P2.12)
Add functional history page that displays DailyLog entries in a table
with date, cycle day/phase, decision, body battery, HRV, and intensity
columns. Features include:
- Data fetching from /api/history endpoint
- Pagination with previous/next navigation
- Date filtering with start/end date inputs
- Decision color coding (REST=red, TRAIN=green, GENTLE/LIGHT/REDUCED=yellow)
- Loading and error states
- Empty state when no history exists

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 20:22:08 +00:00
75f0e8ec80 Implement Settings page with form validation (P2.9)
- Add client-side form for cycleLength, notificationTime, timezone
- Fetch user data on mount and pre-fill form values
- Submit updates via PATCH /api/user with loading states
- Display success/error messages with proper accessibility
- Clear messages when user modifies form
- 24 tests covering rendering, data loading, validation, error handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 20:14:49 +00:00
e73d131450 Implement history API endpoint (P2.8)
Add GET /api/history for paginated historical daily logs with:
- Pagination support (page/limit query params, default 20 per page)
- Date filtering (startDate/endDate in YYYY-MM-DD format)
- Validation for all parameters with descriptive error messages
- Sort by date descending (most recent first)
- Response includes items, total, page, limit, totalPages, hasMore

Includes 19 tests covering pagination, date filtering, auth, and validation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 20:06:50 +00:00
532d49f570 Implement calendar ICS feed and token regeneration (P2.6, P2.7)
Add two calendar-related API endpoints:

P2.6 - GET /api/calendar/[userId]/[token].ics:
- Token-based authentication (no session required)
- Validates calendar token against user record
- Generates 90 days of phase events using generateIcsFeed()
- Returns proper Content-Type and Cache-Control headers
- 404 for non-existent users, 401 for invalid tokens
- 10 tests covering all scenarios

P2.7 - POST /api/calendar/regenerate-token:
- Requires authentication via withAuth() middleware
- Generates cryptographically secure 32-character hex token
- Updates user's calendarToken field in database
- Returns new token and formatted calendar URL
- Old tokens immediately invalidated
- 9 tests covering token generation and auth

Total: 19 new tests, 360 tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 20:02:07 +00:00
901543cb4d Implement notifications cron endpoint (P2.5)
Add daily email notification system that sends training decisions
at each user's preferred time in their timezone.

Features:
- Timezone-aware notification matching using Intl.DateTimeFormat
- DailyLog-based notifications with duplicate prevention
- Nutrition guidance integration via getNutritionGuidance
- Graceful error handling (continues processing on per-user failures)
- Summary response with detailed stats

Includes 20 tests covering:
- CRON_SECRET authentication
- Timezone matching (UTC and America/New_York)
- DailyLog existence and already-sent checks
- Email content assembly
- Error handling and response format

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:56:16 +00:00
fc970a2c61 Implement Garmin sync cron endpoint (P2.4)
Add daily sync functionality for Garmin biometric data:
- Fetch all users with garminConnected=true
- Skip users with expired tokens
- Decrypt OAuth2 tokens and fetch HRV, Body Battery, Intensity Minutes
- Calculate cycle day, phase, phase limit, remaining minutes
- Compute training decision using decision engine
- Create DailyLog entries for each user
- Return sync summary with usersProcessed, errors, skippedExpired, timestamp

Includes 22 tests covering:
- CRON_SECRET authentication
- User iteration and filtering
- Token decryption and expiry handling
- Garmin API data fetching
- DailyLog creation with all required fields
- Error handling and graceful degradation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:50:26 +00:00
0fc25a49f1 Implement Garmin token management endpoints (P2.2, P2.3)
Added three Garmin API endpoints for token management:

- POST /api/garmin/tokens: Accepts oauth1, oauth2, expires_at;
  encrypts tokens using AES-256-GCM; stores in user record;
  returns daysUntilExpiry

- DELETE /api/garmin/tokens: Clears encrypted tokens from user
  record and sets garminConnected to false

- GET /api/garmin/status: Returns connection status, days until
  expiry, expired flag, and warning level (critical ≤7 days,
  warning 8-14 days)

All endpoints use withAuth() middleware for authentication.
Added 26 tests covering encryption, validation, auth, and
warning level thresholds.

Also added pb_data/ to .gitignore for PocketBase data.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:45:16 +00:00
24b7c0fd3e Add pocketbase to devshell. 2026-01-10 19:44:03 +00:00
c1679789b5 Implement Garmin biometric fetching functions (P2.1)
Add specific fetchers for HRV, Body Battery, and Intensity Minutes
to enable real biometric data collection from Garmin Connect API.

Functions added:
- fetchHrvStatus(): Returns "Balanced", "Unbalanced", or "Unknown"
- fetchBodyBattery(): Returns current BB and yesterday's low value
- fetchIntensityMinutes(): Returns 7-day rolling sum of activity

All functions gracefully handle API failures with safe defaults.
Test count expanded from 14 to 33 covering all scenarios.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:38:22 +00:00
0d88066d00 Add unit tests for lib utilities (P3.2-P3.6)
Implement comprehensive test coverage for five library modules:

- encryption.test.ts (14 tests): AES-256-GCM encrypt/decrypt round-trip,
  ciphertext format validation, error handling, key padding/truncation
- nutrition.test.ts (17 tests): seed cycling by cycle day, carb ranges
  by phase, keto guidance by phase, seed switch alert on day 15
- garmin.test.ts (14 tests): token expiry checks, days until expiry
  calculation, API fetch with auth headers, error handling
- email.test.ts (14 tests): daily email composition with biometrics,
  nutrition guidance, period confirmation emails, null value handling
- ics.test.ts (23 tests): ICS format validation, phase events with
  emojis, warning events on days 22/25, cycle length handling

Total: 82 new tests bringing project total to 254 passing tests.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:32:17 +00:00
9f3c2ecac9 Implement Dashboard page with real data integration (P1.7)
Wire up the Dashboard page with /api/today data:
- Fetch today's decision, biometrics, and nutrition on mount
- Display DecisionCard with status, icon, and reason
- Show DataPanel with HRV, Body Battery, intensity minutes
- Show NutritionPanel with seed cycling and carb guidance
- Integrate OverrideToggles with POST/DELETE /api/overrides
- Handle loading states, error states, and setup prompts
- Display cycle day and phase information

Add 23 unit tests for the Dashboard component covering:
- Data fetching from /api/today and /api/user
- Component rendering (DecisionCard, DataPanel, NutritionPanel)
- Override toggle functionality (POST/DELETE API calls)
- Error handling and loading states
- Cycle information display

Also fixed TypeScript error in login page tests (resolveAuth
initialization).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:25:50 +00:00
933e39aed4 Implement Login page with PocketBase auth (P1.6)
Add functional login page with email/password form:
- Client component with controlled form inputs
- PocketBase authentication integration
- Error handling with visual feedback
- Loading states (disabled inputs, button text change)
- Form validation (prevents empty submissions)
- Redirect to dashboard on successful login

Test infrastructure improvements:
- Add @testing-library/jest-dom for DOM matchers
- Add global test setup with cleanup between tests
- Configure vitest.config.ts with setupFiles

14 new tests covering form rendering, auth flow, error
handling, and validation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:19:50 +00:00
18c34916ca Implement PATCH /api/user endpoint (P1.1)
Add profile update functionality with validation for:
- cycleLength: number, range 21-45 days
- notificationTime: string, HH:MM format (24-hour)
- timezone: non-empty string

Security: Ignores attempts to update non-updatable fields (email, tokens).
Returns updated user profile excluding sensitive fields.

17 tests covering validation, persistence, and security scenarios.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:14:12 +00:00
e4d123704d Implement POST/DELETE /api/overrides endpoints (P1.5)
Add override management API for the training decision system:
- POST /api/overrides adds an override (flare, stress, sleep, pms)
- DELETE /api/overrides removes an override
- Both endpoints use withAuth middleware
- Validation for override types, idempotent operations
- 14 tests covering auth, validation, and persistence

Also fix type error in today/route.ts where DailyLog body battery
fields could be null but biometrics object expected numbers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:09:08 +00:00
949cb1671a Implement GET /api/today endpoint (P1.4)
Add the core daily snapshot API that powers the dashboard. Returns:
- Training decision (status, reason, icon) using decision engine
- Cycle data (cycleDay, phase, phaseConfig, daysUntilNextPhase)
- Biometrics (hrvStatus, bodyBattery, weekIntensity, phaseLimit)
- Nutrition guidance (seeds, carbRange, ketoGuidance)

When no DailyLog exists (Garmin not synced), returns sensible defaults:
hrvStatus="Unknown", bodyBattery=100, weekIntensity=0. This allows
the app to function without Garmin integration.

22 tests covering auth, validation, all decision paths, override
handling, phase-specific logic, and nutrition guidance.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:03:13 +00:00
b6285e3c01 Implement GET /api/cycle/current endpoint (P1.3)
Add endpoint returning current cycle day, phase, phase configuration,
and days until next phase. Uses withAuth middleware for authentication.

Response shape:
- cycleDay: current day in menstrual cycle (1-31)
- phase: current phase (MENSTRUAL, FOLLICULAR, OVULATION, EARLY_LUTEAL, LATE_LUTEAL)
- phaseConfig: full configuration including weeklyLimit, trainingType
- daysUntilNextPhase: days remaining in current phase
- cycleLength: user's configured cycle length

Includes 10 tests covering:
- Authentication (401 when not authenticated)
- Validation (400 when no lastPeriodDate)
- All five cycle phases
- Cycle rollover handling
- Custom cycle lengths

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:58:04 +00:00
62ad2e3d1a Implement POST /api/cycle/period endpoint (P1.2)
Add period logging endpoint that allows users to record their period start date.
This is a critical path item that unblocks GET /api/cycle/current and GET /api/today.

Features:
- Protected with withAuth middleware
- Validates startDate is present, valid format (YYYY-MM-DD), and not in future
- Updates user.lastPeriodDate in PocketBase
- Creates PeriodLog record for historical tracking
- Returns updated cycle information (cycleDay, phase)

Tests: 8 tests covering authentication, validation, database operations, and error handling.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:53:34 +00:00
d3ba01d1e1 Implement GET /api/user endpoint (P0.4)
Add authenticated user profile retrieval endpoint using withAuth wrapper.
Returns user profile with safe fields, excluding encrypted tokens.

Changes:
- Implement GET handler in src/app/api/user/route.ts
- Add 4 tests for auth, response shape, sensitive field exclusion
- Add path alias resolution to vitest.config.ts for @/* imports
- Update IMPLEMENTATION_PLAN.md to mark P0.4 complete

Response includes: id, email, garminConnected, cycleLength,
lastPeriodDate, notificationTime, timezone, activeOverrides

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:48:19 +00:00
76a46439b3 Implement auth middleware for API routes (P0.2)
Add authentication infrastructure for protected routes:
- withAuth() wrapper for API route handlers (src/lib/auth-middleware.ts)
- Next.js middleware for page protection (src/middleware.ts)

withAuth() loads auth from cookies, validates session, and passes
user context to handlers. Returns 401 for unauthenticated requests.

Page middleware redirects unauthenticated users to /login, while
allowing public routes (/login), API routes (handled separately),
and static assets through.

Tests: 18 new tests (6 for withAuth, 12 for page middleware)
Total test count: 60 tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:43:19 +00:00
caed11a445 Implement PocketBase auth helpers (P0.1)
Add authentication utilities to pocketbase.ts for server-side auth:
- createPocketBaseClient() - factory for fresh instances per request
- isAuthenticated(pb) - checks authStore validity
- getCurrentUser(pb) - returns typed User from authStore
- loadAuthFromCookies(pb, cookies) - loads auth from Next.js cookies

Includes 9 unit tests covering all auth state scenarios and cookie loading.
This unblocks P0.2 (auth middleware) and all downstream API/page work.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:37:15 +00:00
03f1bde24c Implement decision engine override handling (P0.3)
Add getDecisionWithOverrides() function that checks manual overrides
before algorithmic rules. Overrides are applied in priority order:
flare > stress > sleep > pms, and all force REST status.

Includes comprehensive test suite with 24 tests covering:
- All 8 algorithmic priority rules
- Override type behaviors
- Override priority enforcement
- Empty override fallthrough to algorithmic rules

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:30:57 +00:00
d7ecc2944d Setup Ralph. 2026-01-10 17:13:18 +00:00
f15e093254 Initial project setup for PhaseFlow
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>
2026-01-09 16:50:39 +00:00