Weekly Training Review AI Assistant
Overview
Build-time script that generates weekly training analysis by calling Claude API, producing per-week JSON files consumed by a new Dashboard modal component. Integrates with existing strava:sync workflow.
Decisions
| Decision | Choice | Rationale |
|---|---|---|
| Trigger | Build-time script (pnpm weekly-review) | Consistent with strava:sync workflow, git-trackable output |
| Storage | Per-week JSON files (W01.json, W02.json) | Independent, easy to regenerate individual weeks |
| Analysis | 4 dimensions: completion, quality, fatigue, advice | Comprehensive yet focused on actionable insights |
| UI | New card in ProgressTracker + modal | Follows existing Dashboard pattern |
| Language | Bilingual (zh + en) per file | Matches project's i18n structure |
Data Structure
WeeklyReview Interface
typescript
export interface WeeklyReview {
weekNumber: number;
weekRange: string; // "2026-01-19 - 2026-01-25"
language: 'zh' | 'en';
generatedAt: string; // ISO timestamp
planCompletion: {
weeklyDistanceTarget: number;
weeklyDistanceActual: number;
completionRate: number; // 0-1
missedSessions: string[];
summary: string; // AI-generated
};
qualityAssessment: {
avgPace: string;
paceConsistency: 'excellent' | 'good' | 'variable' | 'poor';
heartRateCompliance: number; // 0-1
effortDistribution: {
easy: number;
moderate: number;
hard: number;
allOut: number;
};
summary: string;
};
fatigueRisk: {
level: 'low' | 'moderate' | 'high';
indicators: string[];
recommendation: string;
};
nextWeekAdvice: {
focus: string;
adjustments: string[];
tips: string;
};
}JSON File Format (data/weekly-reviews/W01.json)
json
{
"zh": { "weekNumber": 1, "language": "zh", ... },
"en": { "weekNumber": 1, "language": "en", ... }
}Architecture
Script Structure
scripts/weekly-review/
├── generate.ts # Main: aggregate data + call Claude API
├── client.ts # Claude API client wrapper
├── config.ts # API key / model config (from env)
└── prompt.ts # Prompt templates (zh + en)Workflow
Data Aggregation (
generate.ts)- Read
workouts.json+training-config.ts - Calculate current training week (based on
trainingStartDate) - Filter workouts for target week (Monday-Sunday)
- Extract plan data (weeklyPlan + lsdDistanceByWeek)
- Compute metrics: distance, pace, HR zones, effort distribution
- Read
Prompt Construction (
prompt.ts)- Role: Professional running coach analyzing marathon training
- Input: Structured JSON (plan vs actual)
- Requirements: 4-dimension analysis with specific metrics
- Output: Strict JSON schema (WeeklyReview interface)
- Tone: Professional yet friendly, moderate emoji use (match training-config tips style)
API Call (
client.ts)- Model:
claude-3-5-sonnet-20241022 - Temperature: 0.3 (consistent analysis)
- Max tokens: 4096
- Parse response JSON, validate structure
- Model:
Output
- Write to
data/weekly-reviews/W{weekNumber}.json - Bilingual: both zh and en in single file
- Write to
CLI Commands
bash
pnpm weekly-review # Generate current week
pnpm weekly-review --week 3 # Generate week 3
pnpm weekly-review --all # Regenerate all completed weeks
pnpm weekly-review --lang zh # Chinese only (default: both)Integration with Strava Sync
Modify scripts/strava/sync.ts:
- After successful sync, check if current week is complete (has Sunday data)
- If complete, auto-run
weekly-reviewfor current week - Log: "✓ Week 8 review generated"
Prompt Design
Key Elements
Role Definition
You are a professional running coach analyzing marathon training data. Provide specific, actionable insights based on the data provided.Input Format
- Plan: sessions array with type, distance, targetHR
- Actual: workouts array with pace, HR zones, effort
- Context: week number, training phase (base/peak/taper)
Analysis Requirements
- Plan Completion: Compare target vs actual distance, identify missed sessions
- Quality Assessment: Pace consistency (CV%), HR compliance (% in target zones), effort balance
- Fatigue Risk: Detect patterns (consecutive high-intensity, insufficient rest)
- Next Week Advice: Specific adjustments based on current performance
Output Schema
- Provide complete TypeScript interface as JSON schema
- Include example output (few-shot)
- Require strict JSON response (no markdown)
Terminology (Chinese)
- LSD (Long Slow Distance) → 长距离慢跑
- Interval → 间歇跑
- Tempo → 节奏跑
- Recovery → 恢复跑
- Heart Rate Zone → 心率区间
Example Prompt Structure
typescript
export function buildWeeklyReviewPrompt(
data: WeeklyData,
lang: 'zh' | 'en',
): string {
return `
You are a professional marathon coach. Analyze this week's training data.
## Week ${data.weekNumber} (${data.weekRange})
Training Phase: ${data.phase}
## Planned Training
${JSON.stringify(data.plan, null, 2)}
## Actual Workouts
${JSON.stringify(data.actual, null, 2)}
## Analysis Requirements
1. Plan Completion: Calculate completion rate, list missed sessions
2. Quality Assessment: Evaluate pace consistency, HR compliance, effort distribution
3. Fatigue Risk: Identify warning signs (consecutive high-intensity, skipped rest)
4. Next Week Advice: Provide 2-3 specific adjustments
## Output Format
Return ONLY valid JSON matching this schema:
${JSON.stringify(WeeklyReviewSchema, null, 2)}
Language: ${lang === 'zh' ? 'Chinese' : 'English'}
Tone: Professional, friendly, use moderate emojis (🏃 💪 ⚠️ ✅)
`;
}UI Components
New Components
composites/WeeklyReviewModal.tsx+.css- CSS prefix:
wr- - z-index: 1000 (level-1 modal)
Modal Layout
┌─────────────────────────────────────┐
│ 📊 Week 8 Review [← →] [×] │ ← Title + week nav + close
├─────────────────────────────────────┤
│ ■ Plan Completion │
│ ████████░░ 82% (40.2 / 49km) │ ← Progress bar + numbers
│ "Completed most sessions..." │ ← AI summary
├─────────────────────────────────────┤
│ ■ Training Quality │
│ Pace Consistency: ★★★★☆ │
│ HR Compliance: 78% │
│ "Interval HR control was good..." │
├─────────────────────────────────────┤
│ ■ Fatigue Risk 🟢 Low │ ← Green/Yellow/Red
│ "Rest days well scheduled..." │
├─────────────────────────────────────┤
│ ■ Next Week Advice │
│ • Increase LSD to 19km │
│ • Maintain 6 interval sets │
│ "Continue building aerobic base..."│
└─────────────────────────────────────┘Component Props
typescript
interface WeeklyReviewModalProps {
weekNumber: number; // Initial week to display
onClose: () => void;
allWorkoutRecords: WorkoutRecord[];
trainingPlan: TrainingPlan;
}Integration with ProgressTracker
Option A: Replace "Completed Sessions" card with "Weekly Review" card
- Icon: 📊
- Label: "Week 8 Review"
- Value: Completion rate (e.g., "82%")
- Click → open WeeklyReviewModal
Option B: Add 5th card below existing 4
- Keep existing 4 cards unchanged
- New row with single "Weekly Review" card
Recommendation: Option A (replace), keeps layout compact
Week Navigation
- Modal header:
← Week 7|Week 8 Review|Week 9 → - Arrows disabled if week data doesn't exist
- Dynamically load
W{n}.jsonon navigation - Show loading spinner during fetch
Data Loading
typescript
// In training-config.ts
export async function loadWeeklyReview(
weekNumber: number,
lang: 'zh' | 'en',
): Promise<WeeklyReview | null> {
try {
const data = await import(
`../data/weekly-reviews/W${weekNumber.toString().padStart(2, '0')}.json`
);
return data[lang];
} catch {
return null;
}
}File Structure
scripts/weekly-review/
├── generate.ts
├── client.ts
├── config.ts
└── prompt.ts
daily/long-term-goals/
├── data/
│ └── weekly-reviews/
│ ├── W01.json
│ ├── W02.json
│ └── ...
└── components/
├── core/types.ts # + WeeklyReview interface
├── composites/
│ ├── WeeklyReviewModal.tsx # New
│ ├── WeeklyReviewModal.css # New
│ └── ProgressTracker.tsx # Modified: add review card
└── training-config.ts # + loadWeeklyReview function
zh/daily/long-term-goals/
└── components/
└── composites/
├── WeeklyReviewModal.tsx # Chinese version
└── WeeklyReviewModal.css # Shared CSSImplementation Phases
Phase 1: Script Foundation
- Create
scripts/weekly-review/structure - Implement data aggregation logic
- Build prompt templates (zh + en)
- Set up Claude API client
- Test with Week 1 data
Phase 2: CLI Integration
- Add
weekly-reviewnpm script - Implement CLI arguments (--week, --all, --lang)
- Integrate with
strava:syncauto-trigger - Generate reviews for all completed weeks
Phase 3: UI Components
- Define WeeklyReview TypeScript interface
- Build WeeklyReviewModal component
- Implement week navigation
- Add review card to ProgressTracker
- Style with Strava-inspired design
Phase 4: Bilingual Support
- Duplicate components to
zh/directory - Test language switching
- Ensure prompt quality in both languages
Configuration
Environment Variables
bash
# .env.local
ANTHROPIC_API_KEY=sk-ant-...
WEEKLY_REVIEW_MODEL=claude-3-5-sonnet-20241022 # Optional, default
WEEKLY_REVIEW_TEMPERATURE=0.3 # Optional, defaultpackage.json Scripts
json
{
"scripts": {
"weekly-review": "tsx scripts/weekly-review/generate.ts",
"weekly-review:all": "tsx scripts/weekly-review/generate.ts --all",
"strava:sync": "tsx scripts/strava/sync.ts && pnpm weekly-review"
}
}Error Handling
- Missing API Key: Exit with clear error message
- API Failure: Retry once, then log error and continue
- Invalid JSON Response: Log raw response, skip week
- Missing Week Data: Return null, show "No review available" in UI
- File Write Error: Log error, don't crash script
Testing Strategy
Unit Tests (optional, if time permits)
- Prompt construction
- Data aggregation logic
- JSON validation
Manual Testing
- Generate Week 1 review, verify all 4 dimensions
- Test with incomplete week (missing sessions)
- Test with perfect week (all sessions completed)
- Verify bilingual output quality
- Test UI navigation between weeks
Edge Cases
- Week with zero workouts
- Week with only rest days
- Week with multiple workouts per day
- Future weeks (should fail gracefully)
Success Criteria
- [ ] Script generates valid JSON for completed weeks
- [ ] Bilingual output (zh + en) in single file
- [ ] 4 analysis dimensions present and meaningful
- [ ] UI modal displays review with week navigation
- [ ] Integration with
strava:syncworks automatically - [ ] No build errors, TypeScript types correct
- [ ] Mobile responsive (modal adapts to small screens)
Future Enhancements
- Trend Analysis: Compare current week vs previous 4 weeks
- Goal Tracking: Progress toward sub-9:30 marathon goal
- Injury Risk: Detect sudden mileage spikes (>10% increase)
- Export: Download review as PDF or markdown
- Notifications: Alert if fatigue risk is high