Frontend:
- ChatCoach.jsx: streaming chat UI with SSE, provider indicator, suggestion
chips, 'no AI configured' state with setup link
- App.jsx: import + /chat route + nav bar (More → Coach with brain emoji)
- api.js: getAIStatus() method
Documentation:
- README.md: 'Built-in AI Coach' section with 8-provider table, external
agent config snippets for Claude Desktop, Claude Code, Cursor, Windsurf,
and COROS multi-MCP pattern
- AGENT_GUIDE.md: multi-device integration, Strava AI/ML warning,
provider-agnostic statement
Nav bar: Home | Log | Keto | Programs | Coach
Settings still reachable at /settings (linked from Coach setup prompt)
SEC-16: Add frontend ports mapping (80:80) to docker-compose.yml
UI-01: Add routes for Welcome, SettingsIntegrations, MealPlan in App.jsx
SEC-01: Remove traceback leak from auth error responses
SEC-02: Fix require_admin to use is_admin column (was undefined ADMIN_USERNAME)
SEC-03: Add API_TOKEN auth for MCP connector -> backend communication
SEC-04: OAuth state now uses signed JWT tokens (was raw user UUID)
OS-01: First registered user gets admin immediately during registration
10 files changed, 97 insertions(+), 25 deletions(-)
Two bugs fixed:
1. Backend: list_programs endpoint did not include catalog_id in its
response, so the frontend filter (p.catalog_id) always matched zero
programs. The previous LogActivity card never rendered because
loadActiveProgram() found no active program with a catalog link.
Now also exposes current_week.
2. UX restructure: instead of showing the program workout card at the
top of /log unconditionally, the card now appears AFTER the user
selects the 'Workout' category — matching the natural flow:
Log -> Workout -> see today's program workout option.
The Workout category now reveals:
- Active program banner (clickable, shows program name + week,
navigates to ProgramDetail on tap)
- Today's workout card with exercise preview and one-tap 75 pts
- Other uncompleted workouts in the current week (up to 3)
- 'Or log freeform' divider before the existing form
When all workouts in the current week are done, a green completion
banner appears instead.
Refactored the workout card into a ProgramWorkoutCard component since
it's now used for both today's featured workout and weekly upcoming.
Dashboard:
- The program bar at the top of the home page is now clickable and
navigates to the program detail page. Backend get_today_status now
returns program_id alongside name/day/total_days.
LogActivity:
- On mount, fetches the user's active catalog program and its today's
workout. If there's an uncompleted non-rest workout for today, a
featured 'Today's Program Workout' card appears at the top with an
exercise preview and a one-tap '✓ Complete — 75 pts' button.
- Tapping Complete fires the same /workout/{id}/complete endpoint as
ProgramDetail, surfaces weekly/completion bonuses in the success
message, and returns to the Dashboard.
- The standard category grid below is now relabeled 'Or log something
else' when a program workout is available.
CatalogDetail, ProgramDetail, ProgramSearch and SupportAdmin all use
inline-styled root divs instead of the .page CSS class, so they were
missing the padding-bottom: 96px that clears the fixed bottom nav bar.
Last button/section was hidden behind the nav.
Adds paddingBottom: 96px to each page's root div. Support.jsx has its
own full-height chat layout and is intentionally left as-is.
The 'View Details' button on ProgramSearch navigated to /catalog/:id
but no route or page existed. Now creates a proper detail view that
fetches via getCatalogProgram, shows program metadata, weeks/workouts,
progression rules, and an Adopt button that redirects to the user's
new program tracking page on success.