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>
This commit is contained in:
2026-01-11 09:19:55 +00:00
parent 00d902a396
commit 714194f2d3
7 changed files with 124 additions and 12 deletions

View File

@@ -4,7 +4,7 @@ This file is maintained by Ralph. Run `./ralph-sandbox.sh plan 3` to generate ta
## Current State Summary
### Overall Status: 717 tests passing across 40 test files
### Overall Status: 720 tests passing across 40 test files
### Library Implementation
| File | Status | Gap Analysis |
@@ -17,7 +17,7 @@ This file is maintained by Ralph. Run `./ralph-sandbox.sh plan 3` to generate ta
| `decision-engine.ts` | **COMPLETE** | 8 priority rules + override handling with `getDecisionWithOverrides()`, 24 tests |
| `garmin.ts` | **COMPLETE** | 33 tests covering fetchGarminData, fetchHrvStatus, fetchBodyBattery, fetchIntensityMinutes, isTokenExpired, daysUntilExpiry, error handling, token validation |
| `pocketbase.ts` | **COMPLETE** | 9 tests covering `createPocketBaseClient()`, `isAuthenticated()`, `getCurrentUser()`, `loadAuthFromCookies()` |
| `auth-middleware.ts` | **COMPLETE** | 6 tests covering `withAuth()` wrapper for API route protection |
| `auth-middleware.ts` | **COMPLETE** | 9 tests covering `withAuth()` wrapper for API route protection, structured logging for auth failures |
| `middleware.ts` (Next.js) | **COMPLETE** | 12 tests covering page protection, redirects to login |
| `logger.ts` | **COMPLETE** | 16 tests covering JSON output, log levels, error stack traces, child loggers |
| `metrics.ts` | **COMPLETE** | 33 tests covering metrics collection, counters, gauges, histograms, Prometheus format |
@@ -80,7 +80,7 @@ This file is maintained by Ralph. Run `./ralph-sandbox.sh plan 3` to generate ta
| `src/lib/cycle.test.ts` | **EXISTS** - 9 tests |
| `src/lib/decision-engine.test.ts` | **EXISTS** - 24 tests (8 algorithmic rules + 16 override scenarios) |
| `src/lib/pocketbase.test.ts` | **EXISTS** - 9 tests (auth helpers, cookie loading) |
| `src/lib/auth-middleware.test.ts` | **EXISTS** - 6 tests (withAuth wrapper, error handling) |
| `src/lib/auth-middleware.test.ts` | **EXISTS** - 9 tests (withAuth wrapper, error handling, structured logging) |
| `src/lib/logger.test.ts` | **EXISTS** - 16 tests (JSON format, log levels, error serialization, child loggers) |
| `src/lib/metrics.test.ts` | **EXISTS** - 18 tests (metrics collection, counters, gauges, histograms, Prometheus format) |
| `src/middleware.test.ts` | **EXISTS** - 12 tests (page protection, public routes, static assets) |
@@ -625,11 +625,25 @@ Testing, error handling, and refinements.
- Response parsing for biometric data structures
- **Why:** External API integration robustness is now fully tested
### P3.7: Error Handling Improvements
- [ ] Add consistent error responses across all API routes
### P3.7: Error Handling Improvements ✅ COMPLETE
- [x] Add consistent error responses across all API routes
- [x] Replace console.error with structured pino logger
- [x] Add logging for key events per observability spec
- **Files:**
- All route files - Standardize error format, add logging
- **Why:** Better debugging and user experience
- `src/lib/auth-middleware.ts` - Replaced console.error with structured logger, added auth failure logging
- `src/app/api/cycle/period/route.ts` - Added "Period logged" event logging, structured error logging
- `src/app/api/calendar/[userId]/[token].ics/route.ts` - Replaced console.error with structured logger
- `src/app/api/overrides/route.ts` - Added "Override toggled" event logging
- `src/app/api/today/route.ts` - Added "Decision calculated" event logging
- **Tests:**
- `src/lib/auth-middleware.test.ts` - Added 3 tests for structured logging (9 total)
- **Events Logged (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
- **Why:** Better debugging and user experience with structured JSON logs
### P3.8: Loading States
- [ ] Add loading indicators to all pages
@@ -798,7 +812,6 @@ P4.* UX Polish ────────> After core functionality complete
| Priority | Task | Effort | Notes |
|----------|------|--------|-------|
| Low | P3.7 Error Handling | Small | Polish |
| Low | P3.8 Loading States | Small | Polish |
| Low | P4.* UX Polish | Various | After core complete |
@@ -877,6 +890,7 @@ P4.* UX Polish ────────> After core functionality complete
- [x] **P3.4: ICS Tests** - Complete with 23 tests covering ICS format validation, 90-day event generation, timezone handling
- [x] **P3.5: Encryption Tests** - Complete with 14 tests covering AES-256-GCM round-trip, error handling, key validation
- [x] **P3.6: Garmin Tests** - Complete with 33 tests covering API interactions, token expiry, error handling
- [x] **P3.7: Error Handling Improvements** - Replaced console.error with structured pino logger across API routes, added key event logging (Period logged, Override toggled, Decision calculated, Auth failure), 3 new tests in auth-middleware.test.ts
- [x] **P3.9: Token Expiration Warnings** - Complete with 10 new tests in email.test.ts, 10 new tests in garmin-sync/route.test.ts; sends warnings at 14 and 7 days before expiry
- [x] **P3.11: Missing Component Tests** - Complete with 82 tests across 5 component test files (DecisionCard: 11, DataPanel: 18, NutritionPanel: 12, OverrideToggles: 18, DayCell: 23)