Hydrolyze
MCP server: Hydrolyze
Installation
npx hydrolyzeAsk AI about Hydrolyze
Powered by Claude Β· Grounded in docs
I know everything about Hydrolyze. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
π Hydrolyze MVP
An intelligent swim training load calculator that parses natural language swim sets, calculates training load using scientifically-backed formulas, and tracks ACWR (Acute:Chronic Workload Ratio) for injury prevention.
Features
- β Authentication: Secure login with Google, Apple, or Email/Password
- π Rules-Based Parsing: Pure deterministic parsing (no LLM calls) - works offline
- π ACWR Calculation: Real-time injury risk assessment using EWMA
- β‘ Training Load Formula: Full implementation with stroke, equipment, and intensity factors
- π― Smart Flagging: Identifies specific reps that push into danger zones
- π± Mobile-First UI: Dark theme, touch-optimized interface
- π§ Learning System: Remembers user-specific terminology
Quick Start
1. Prerequisites
- Node.js 18+ and npm
- Supabase account (for database and auth)
2. Setup Supabase
- Create a new Supabase project at https://supabase.com
- Run the following SQL in the Supabase SQL Editor:
-- Enable UUID extension
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Users table (links to auth.users)
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
"UID" UUID REFERENCES auth.users(id) ON DELETE CASCADE,
email TEXT,
name TEXT,
"userType" TEXT DEFAULT 'swimmer',
"isAdmin" BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- User parsing profile (learned terms)
CREATE TABLE IF NOT EXISTS user_parsing_profile (
user_id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
learned_terms JSONB DEFAULT '{}',
baseline_ctl FLOAT,
baseline_atl FLOAT,
last_acwr_calc TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Swim sets (planned workouts)
CREATE TABLE IF NOT EXISTS swimsets (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
name TEXT NOT NULL,
sets_json JSONB NOT NULL,
total_distance INTEGER,
estimated_duration INTEGER,
projected_load FLOAT,
projected_tss FLOAT,
acwr_before FLOAT,
acwr_after FLOAT,
risk_level TEXT CHECK (risk_level IN ('optimal', 'elevated', 'high')),
flagged_reps JSONB,
scheduled_date DATE,
status TEXT CHECK (status IN ('planned', 'completed', 'skipped')) DEFAULT 'planned',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Swim records (completed sessions)
CREATE TABLE IF NOT EXISTS "swimRecords" (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
"UID" UUID REFERENCES auth.users(id) ON DELETE CASCADE,
date TIMESTAMPTZ NOT NULL,
distance INTEGER NOT NULL,
duration INTEGER,
stroke TEXT,
"heartRate" INTEGER,
"strokeRate" INTEGER,
gear TEXT[],
"poolLength" INTEGER CHECK ("poolLength" IN (25, 50)),
swim_set_id UUID REFERENCES swimsets(id),
rep_index INTEGER,
actual_load FLOAT,
htls_score FLOAT,
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Indexes for performance
CREATE INDEX IF NOT EXISTS idx_users_uid ON users("UID");
CREATE INDEX IF NOT EXISTS idx_swimsets_user ON swimsets(user_id);
CREATE INDEX IF NOT EXISTS idx_swimrecords_user ON "swimRecords"("UID");
CREATE INDEX IF NOT EXISTS idx_swimrecords_date ON "swimRecords"(date);
CREATE INDEX IF NOT EXISTS idx_swimrecords_set ON "swimRecords"(swim_set_id);
-- RLS Policies
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE user_parsing_profile ENABLE ROW LEVEL SECURITY;
ALTER TABLE swimsets ENABLE ROW LEVEL SECURITY;
ALTER TABLE "swimRecords" ENABLE ROW LEVEL SECURITY;
-- Users policies
CREATE POLICY "Users can read own profile" ON users FOR SELECT USING (auth.uid() = "UID");
CREATE POLICY "Users can update own profile" ON users FOR UPDATE USING (auth.uid() = "UID");
CREATE POLICY "Users can insert own profile" ON users FOR INSERT WITH CHECK (auth.uid() = "UID");
-- User parsing profile policies
CREATE POLICY "Users can manage own parsing profile" ON user_parsing_profile FOR ALL USING (auth.uid() = user_id);
-- Swim sets policies
CREATE POLICY "Users can manage own sets" ON swimsets FOR ALL USING (auth.uid() = user_id);
-- Swim records policies
CREATE POLICY "Users can manage own records" ON "swimRecords" FOR ALL USING (auth.uid() = "UID");
- Enable authentication providers in Supabase Dashboard:
- Go to Authentication β Providers
- Enable Google OAuth (configure in Google Cloud Console)
- Enable Apple OAuth (configure in Apple Developer)
- Enable Email/Password authentication
3. Configure Environment Variables
Copy .env.local and add your Supabase credentials:
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key-here
4. Install & Run
npm install
npm run dev
Visit http://localhost:5173
Usage
Adding a Workout
- Click the + button (bottom-right)
- Paste your workout (e.g., from a coach or training plan)
- Click "Parse & Review"
- Review the parsed workout with calculated training load
- Check ACWR and any flagged reps
- Click "Confirm & Save"
Example Workout Format
Warm-up:
4x75 FR easy
4x50 K @ 1:00
Main:
6x100 FR @ 1:30
4x50 FL sprint @ 1:00
Cool-down:
200 FR easy
Parser Capabilities
The parser understands:
- Strokes: freestyle, free, FR, backstroke, back, BK, breaststroke, breast, BR, butterfly, fly, FL, IM, kick, pull, drill
- Equipment: fins, pull buoy, paddles, snorkel, kickboard, parachute, ankle band, etc.
- Intensities: easy, moderate, hard, sprint, threshold, descend, build, etc.
- Intervals: @ 1:30, on 1:45
- Rest: :15 rest, @ :20 rest
- Sections: Warm-up:, Main:, Cool-down:, Sprint:, Drill:
Training Load Formula
Each rep's load is calculated as:
Load = Distance Γ Adjusted Intensity Γ Equipment Factor Γ Stroke Factor
Where:
- Adjusted Intensity = Base Intensity + Intensity Modifier
- Equipment Factor = Product of all equipment multipliers
- Stroke Factor = Metabolic demand of stroke type
ACWR Calculation
Uses Exponentially Weighted Moving Average (EWMA):
- CTL (Chronic Training Load): 28-day average (Ξ»=42)
- ATL (Acute Training Load): 7-day average (Ξ»=7)
- ACWR = ATL / CTL
Risk zones:
- < 0.8: Underloaded (safe to increase)
- 0.8 - 1.3: Optimal zone
- 1.3 - 1.5: Elevated risk
- > 1.5: High injury risk
Project Structure
src/
βββ calculator/ # ACWR and load calculations
β βββ acwr.ts
β βββ repFlagger.ts
β βββ repLoad.ts
βββ components/ # React components
β βββ auth/ # Authentication pages
β βββ ACWRIndicator.tsx
β βββ Dashboard.tsx
β βββ FAB.tsx
β βββ InputModal.tsx
β βββ ParsedWorkoutReview.tsx
βββ contexts/ # React contexts
β βββ AuthContext.tsx
βββ db/ # Database layer
β βββ records.ts
β βββ sets.ts
β βββ supabase.ts
β βββ userProfile.ts
βββ hooks/ # Custom React hooks
β βββ useUserProfile.ts
βββ parser/ # Rules-based parser
β βββ constants.ts
β βββ index.ts
β βββ patternMatcher.ts
β βββ tokenizer.ts
β βββ typeDetector.ts
βββ types/ # TypeScript types
β βββ index.ts
βββ App.tsx
βββ main.tsx
βββ index.css
Tech Stack
- Frontend: React 18 + TypeScript + Vite
- Styling: Tailwind CSS (dark theme)
- Database: Supabase (PostgreSQL)
- Authentication: Supabase Auth (Google, Apple, Email)
- Routing: React Router v6
- State: Zustand + React Query (planned)
Development
npm run dev # Start dev server
npm run build # Build for production
npm run preview # Preview production build
Roadmap
Phase 1 (MVP - Current):
- β Authentication
- β Rules-based parsing
- β Training load calculation
- β ACWR tracking
- β Basic UI
Phase 2:
- Unknown term learning UI
- Timed effort prompts
- Set-to-record matching
- Workout history charts
Phase 3:
- Mobile app (React Native)
- Coach-athlete relationships
- Workout templates
- Advanced analytics
Contributing
This is currently a private MVP. For questions or issues, contact the development team.
License
Private - All Rights Reserved
