twenty-four: what's next
Two weeks after the service consolidation, here’s what’s been added.
Training Plan Generator
The big one: AI-powered training plan generation for endurance events.
What it does:
Give it a race (distance, date, sport) and it generates a complete training plan:
|
|
The service:
- Fetches your current fitness metrics from Intervals.icu (CTL, ATL, recent training)
- Checks your calendar for holidays and time off
- Sends everything to Claude with instructions
- Gets back a week-by-week plan
- Creates structured workouts in Intervals.icu
Holiday awareness:
This was critical. The system:
- Detects existing calendar events marked as holidays
- Shows them in the prompt: “2026-03-07 to 2026-03-14: Spring Break”
- Enforces complete rest during those periods
- Adjusts training volume leading into and out of holidays
No more manually editing plans when you book a vacation. The AI sees it and routes around it.
Example prompt to Claude:
|
|
Claude generates workouts that:
- Ramp volume gradually
- Include recovery weeks
- Respect holidays
- Peak 2-3 weeks before race day
- Include a proper taper
The system converts this to Intervals.icu format and creates all the workouts automatically.
Current state:
Tested with half marathon, 10k, and Olympic triathlon plans. Works well. The AI understands training periodization, knows when to schedule long runs vs. intervals, and respects your current fitness level.
Cost:
Each plan generation:
- ~2,000 input tokens (fitness context + holidays + instructions)
- ~6,000 output tokens (10-12 weeks of workouts)
Cost per plan: ~$0.10
Service Reorganization
Renamed services to better reflect scope:
Before:
calendar(orchestrator)workouts(gym + Strava + workout plans)dining(meals)routine(dashboard)
After:
routine(orchestrator - calendar sync, gym sync, Google Calendar)fitness(gym + Strava + workout plans + stretching + training plans)health(meals + quotes)dashboard(status monitoring)
The name workouts was too narrow. The service now handles:
- Gym class scraping and reservations
- Strava activity processing (emoji injection, commute detection)
- Claude-powered workout plan generation
- Daily stretching routines
- Multi-sport training plan generation
So it’s fitness now.
Similarly, dining was just meals. But I added daily inspirational quotes (also Claude-generated), so it’s health - mental + physical.
Caloric Goals
The health service (formerly dining) now lets you set daily calorie targets.
Interface:
Simple form at /meals/goals:
- Weekday target (Mon-Fri): 2800 cal
- Weekend target (Sat-Sun): 2500 cal
Saved to S3, integrated into the meal planning prompt:
|
|
The AI adapts meal sizes and portions to hit the target. If you increase your goal after a heavy training week, breakfast gets bigger. If you lower it for a rest day, portions shrink.
Why separate weekday/weekend?
Training volume differs. Most hard workouts happen during the week (gym, morning runs). Weekends are longer but easier efforts. Different caloric needs.
Weekly Meal Plans
Switched from daily meal generation to weekly.
Before:
Every day at 4am PT, generate today’s meals. Show one day at a time. Navigate forward/back through history.
After:
Every Monday at 4am PT, generate the full week. Display as a table:
| Day | Breakfast | Lunch | Dinner | Snacks |
|---|---|---|---|---|
| Monday | … | … | … | … |
| Tuesday | … | … | … | … |
| … | … | … | … | … |
Why weekly?
- Shopping efficiency: See the whole week, make one grocery list
- Meal variety: The AI can plan complementary meals across days (fish Monday, chicken Tuesday, etc.)
- Training awareness: The AI sees the full week’s workouts and adjusts meals accordingly
Example:
|
|
The prompt shows the entire week’s training schedule. Claude plans meals that support the workload.
Storage:
Changed from daily keys (dining/2025-11-01.json) to weekly keys (dining/week-2025-10-28.json). Week starts Monday, ends Sunday.
History retention: 12 weeks (used to be 30 days). Easier to browse past meal plans.
Observability
Added Prometheus metrics to all services:
- Request counts (by endpoint)
- Request duration (histogram)
- Error rates
- Active requests (gauge)
- Custom metrics (sync operations, API calls, etc.)
Endpoints:
/metrics- Prometheus metrics/health- Liveness probe/ready- Readiness probe/logs- Recent log tail/readme- Service documentation (rendered HTML)
Why /readme?
Each service has a detailed README.md explaining:
- What it does
- API endpoints
- Configuration
- Dependencies
- Deployment
The /readme endpoint serves this as HTML. Useful for quick reference:
|
|
Gym Notification Improvements
Fixed auto-reservation:
The routine service auto-reserves gym classes when:
- You have a workout scheduled in Intervals.icu
- The gym class matches the workout type (HIIT, Yoga, Spin, etc.)
- The class is within the reservation window (21 days)
The logic was broken - it checked the wrong field (Name instead of Status). Now it correctly identifies workouts that need reservations and books them automatically.
Notification deduplication:
Added a deduplication system for Pushover notifications:
|
|
Prevents duplicate notifications for the same event within 24 hours. If a gym class gets waitlisted and the hourly sync runs multiple times, you only get notified once.
Better status handling:
The gym scraper now correctly handles all status variations:
FULL→ Class is fullReserved→ You’re registeredWaitlisted→ You’re on the waitlist- Empty → Spots available
And it cleans up status markers from workout names/descriptions for classes beyond the reservation window.
What’s Actually Running
As of today (Nov 1, 2025):
|
|
Four services. All Go. All running on ARM nodes. Total memory usage: ~1.5Gi.
Service breakdown:
| Service | Purpose | Endpoints |
|---|---|---|
routine |
Calendar sync, gym sync, Google Calendar integration, notifications | /, /api, /sync, /status |
fitness |
Gym scraping, Strava processing, workout plans, stretching, training plans | /gym/*, /strava/*, /workouts/*, /stretching/*, /training-plan |
health |
Meal planning, caloric goals, inspirational quotes | /meals, /meals/goals, /quotes |
dashboard |
Status monitoring, health checks across all services | /, /health, /services |
Cost Summary
Monthly Claude API usage:
| Feature | Frequency | Tokens (in/out) | Cost/call | Monthly Cost |
|---|---|---|---|---|
| Workout plans | ~10/week | 500/200 | $0.004 | $0.16 |
| Stretching routines | Daily | 600/400 | $0.008 | $2.40 |
| Weekly meal plans | Weekly | 800/2000 | $0.035 | $1.40 |
| Inspirational quotes | Daily | 200/100 | $0.002 | $0.60 |
| Training plans | ~2/year | 2000/6000 | $0.10 | $0.02 |
Total: ~$4.60/month
Negligible. The most expensive part is the weekly meal plan generation ($0.035 per call) because it generates 7 days of meals in one shot. Still cheaper than any meal planning service.
What’s Next
Training plan refinements:
The generator works but needs tuning:
- Better recovery week placement (currently every 4th week, could be smarter)
- Sport-specific workout types (brick workouts for triathlon, tempo runs vs. intervals)
- Integration with actual training completion (adjust future weeks based on missed workouts)
Meal plan feedback loop:
Currently meal feedback is tracked but not used. Next iteration:
- Feed yesterday’s meal feedback into today’s prompt
- Track which meals get skipped/modified consistently
- Adjust portion sizes based on hunger/fullness feedback
- Build a preference model over time
Health metrics integration:
The health service could display:
- Weight trends (already syncing to Intervals.icu)
- Sleep data (if I start tracking it)
- Resting heart rate
- HRV (heart rate variability)
All available from wearables. Just need to wire it up.
Multi-tenancy:
Right now everything is hard-coded for me. Making it multi-tenant would require:
- User authentication
- Per-user secrets (Intervals.icu API keys, Google credentials, etc.)
- Per-user S3 storage paths
- UI for onboarding and configuration
Not planning to do this. This is infrastructure for me, not a SaaS product.
See also: Part 0: The Platform | Part 1: Building with Claude | Part 2: Calendar Service | Part 3: Gym Service | Part 4: Strava Service | Part 5: Workout Generator | Part 6: AI Recommendations | Part 7: Service Consolidation
🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com