🔥 75 Hard — Sprint Report

Comprehensive Sprint 0 Research & Sprint 1 Planning
Sprint 0 ✓ Sprint 1 Planned 10 Documents Feb 13, 2026
10
Documents
40
Story Points
70%
App Maturity
B+
Tech Grade
📊 Sprint 0 — Research
🎯 Sprint 1 — Planning

📦 Product Review

Sprint 0 Analysis • React PWA + Capacitor • Supabase Backend
Executive Summary

This is a comprehensive 75 Hard challenge tracking application with advanced AI-powered journaling, fitness integration (Strava), book tracking, progress photography, and community features. The app demonstrates strong technical architecture with a robust data model, AI enrichment pipeline, and extensive feature set.

However, several features are incomplete or broken, and monetization is only partially implemented.

Product Maturity: 70% — Core features work well, but critical gaps in payments and data persistence.

📋 Complete Feature Inventory (7 Daily Tasks)

Core Challenge Tracking

  • Water Tracking — Target: 3785ml (1 gallon), multiple entries with timestamps, progress visualization
  • Workout 1 & 2 — Manual toggle + Strava integration (auto-complete 45+ min), route maps, indoor/outdoor detection
  • Diet Tracking — Meal logging (breakfast, lunch, dinner, snacks), compliance checkbox
  • Reading — 10-page daily minimum, book library, voice notes + transcription, ISBN OCR scanning
  • Progress Photo — Daily capture, gallery view, before/after comparison, privacy blur, timelapse generation
  • Journal Entry — Text, voice, or handwriting input, photo + audio combinations, AI enrichment (mood, energy, themes, sentiment)

AI-Powered Features

  • Journal Intelligence — Mood detection, energy levels, sentiment analysis, theme extraction, entity recognition, key phrases, smart summaries
  • Reflection System — AI-generated daily prompts, user reflections analyzed, 7-day mood trends
  • Story Arcs — Weekly/monthly narrative synthesis, theme tracking, growth suggestions
  • Threads — Thematic clustering of journal entries, timeline view

Community Features (9 Event Types)

  • USER_JOINED, DAY_COMPLETED, FIRST_WEEK_COMPLETED, CHALLENGE_COMPLETED
  • LONG_WORKOUT, SIGNIFICANT_WEIGHT_CHANGE, STREAK_MILESTONE
  • BOOK_COMPLETED, BOOK_STARTED / BOOK_HALFWAY
  • Reactions, confetti animations, share settings
🔌 Integrations & Status
IntegrationStatusDetails
Supabase✓ FullAuth, DB, Storage, 18 Edge Functions, RLS
Strava✓ FullOAuth2, activity sync, route maps, token refresh
OpenAI (Gemini)✓ WorkingJournal enrichment, reflections, story arcs via Lovable gateway
OpenLibrary✓ WorkingBook metadata, ISBN lookup, cover images
Health Connect✗ UI OnlyComponents exist, no OAuth or data sync
Payments✗ NoneTrial works, no Stripe/RevenueCat integration
🔴 Critical Gaps & Broken Features

❌ Critical (Launch Blockers)

  • No Payment Integration — App has zero revenue capability. Trial expires with no subscription flow.
  • No Cloud Backup — Challenge days stored in localStorage. Users lose all progress on device change.
  • No Data Export — GDPR concern. Users cannot export their data.
  • Broken Trial Expiry UX — No upgrade prompt when AI trial expires. Features just stop working.

⚠️ Incomplete Features

  • Video Timelapse — Service exists, no UI for generating/viewing
  • Notification System — DB tables + preferences exist, no push notifications
  • Story Arc Generation — Edge function exists, no manual trigger UI
  • Thread Creation — Edge function exists, no UI to create/manage

🐛 Bugs

  • Task ordering reset includes wrong fields
  • Strava disconnect cleanup uses persistent localStorage flag
  • Journal media orphans when entries deleted
📊 Prioritized Improvement Backlog (20 Items)

🔴 P0 — Critical (Launch Blockers)

  1. Payment Integration — Stripe/RevenueCat (1-2 weeks)
  2. Challenge Day Cloud Backup — Sync localStorage to Supabase (1 week)
  3. Data Export — JSON/PDF/CSV export (3 days)
  4. Fix Expired Trial UX — Upgrade prompts (2 days)

🟡 P1 — High Priority (Next Sprint)

  1. Complete Health Connect Integration (1 week)
  2. Notification System (1 week)
  3. Analytics Dashboard — 75-day heatmap (1 week)
  4. Video Timelapse UI (3 days)

🟢 P2 — Medium Priority

  1. True Social Features (2 weeks)
  2. Story Arc & Thread UI (1 week)
  3. Workout History & Library (1 week)
  4. Enhanced Diet Tracking (1 week)
  5. Book Review Snippets Display (3 days)
  6. Donation Payment Integration (1 week)

🔵 P3 — Nice to Have

  1. Multi-Language Support
  2. Apple Health Integration
  3. Custom Challenges Beyond 75 Hard
  4. AI Voice Coach
  5. Gamification (badges, leaderboards)
  6. Desktop/Web Optimization

⚙️ Technical Audit

Architecture Grade: B+ • 17 DB Tables • 18 Edge Functions • 33% Atomic Design Compliance
Tech Stack & Architecture
CategoryTechnologyVersion
FrameworkReact + TypeScript18.3 / 5.8
BuildVite + SWC5.4
StylingTailwind CSS + shadcn/ui3.4
BackendSupabase (BaaS)2.81
MobileCapacitor7.4
StateReact Query5.83
FormsReact Hook Form + Zod7.61 / 3.25
ChartsRecharts2.15

Application Structure

  • 35 pages — Home, Books, Journal, Progress, Community, AI Insights, Settings + 8 onboarding steps
  • 126 components — UI primitives (shadcn), task cards, journal, progress, reflection, story, tutorial
  • 13 services — Business logic abstracting Supabase operations
  • 9 custom hooks — AI status, challenge day, mobile detection, privacy, safe area
  • 18 edge functions — AI enrichment, OCR, transcription, Strava, book metadata
🗄️ Database Schema (17 Tables)
TablePurposeKey Fields
profilesUser profilesusername, ai_status, challenge_start_date, onboarding_completed
challenge_daysDaily trackingdate, day_number (1-75), data (JSONB tasks)
journal_entriesJournal with AIraw_text, mood, energy_level, themes[], sentiment, key_phrases
journal_mediaPhotos/audiotype (image/audio), local_path, duration_ms
journal_threadsTheme clusterslabel, primary_theme, entry_ids[]
journal_reflection_nuggetsAI promptstitle, body, primary_themes[], suggestion
journal_user_reflectionsUser responsesuser_text, themes[], sentiment, possible_insight
trend_snapshotsAI trendstheme_counts (JSONB), average_mood, focus_suggestion
story_arcsAI narrativesperiod (7/14/30 days), title, body, key_themes[]
booksBook librarytitle, author, status, isbn, metadata_*
reading_sessionsReading logsfrom_page, to_page, notes_text, notes_audio_url
strava_connectionsOAuth tokensaccess_token, refresh_token, expires_at
strava_activitiesSynced workoutsname, type, distance, moving_time, elevation
community_eventsSocial feedtype (9 event types), summary_text, metadata (JSONB)
reactionsEmoji reactionsevent_id, emoji
notificationsUser notificationstype, title, body, read
user_api_keysBYOK keysopenai_key (plaintext ⚠️)
🔒 Security Analysis

✅ Strengths

  • RLS enabled on all 17 tables — Proper user isolation
  • JWT verification — 17/18 edge functions require auth
  • OAuth2 — Standard Strava flow with token refresh
  • Protected routes — Auth + onboarding checks

❌ Critical Issues

  • .env committed to git — Exposes Supabase credentials
  • No input validation in any edge function
  • No rate limiting — AI API abuse risk
  • API keys stored as plaintext — Should use Supabase Vault
  • allowMixedContent: true in Capacitor config
  • No GDPR consent flow
🔧 Tech Debt Summary
IssueSeverityImpact
.env in gitCriticalSecurity breach risk
67% atomic design non-complianceHighInconsistent UI, hard maintenance
No test filesHighRisky refactors, no regression checks
TypeScript as any castsHighRuntime errors not caught
No error tracking (Sentry)MediumBlind to production errors
No code splittingMediumLarge initial bundle
No Prettier/pre-commit hooksMediumInconsistent formatting

🎨 UX & QA Review

Overall Score: 7.5/10 • Accessibility: 6/10 • QA: 6.5/10 • 120+ Components
Design System Analysis

✅ Strengths

  • Consistent HSL-based color system with proper dark mode
  • Comprehensive design tokens (spacing, typography, radius, shadows)
  • Atomic design methodology (atoms → molecules → organisms → templates)
  • Modern gradients aligned with fitness app aesthetics

⚠️ Weaknesses

  • Mixed design systems — Both custom tokens and Tailwind/shadcn coexist
  • Color token duplicationCOLOUR constants (hex) vs CSS variables (HSL)
  • Inconsistent spacing — Some components use inline pixel values
  • No documented color contrast ratios
📱 Mobile UX Patterns

✅ Good

  • Minimum 48px touch targets enforced
  • Safe area insets handled (notch, home indicator)
  • Sticky header + bottom nav with backdrop blur
  • Native camera integration via Capacitor
  • Home-centered 5-tab bottom navigation

⚠️ Missing

  • No haptic feedback on any interactions
  • No swipe navigation between days
  • No pull-to-refresh
  • No offline mode indicator
  • Images not lazy-loaded
  • Limited tablet/desktop optimization
♿ Accessibility Review (Score: 6/10)
AreaStatusDetails
Semantic HTMLGoodLandmarks, buttons, form labels present
ARIA attributesPartialMissing aria-live, aria-expanded, aria-describedby
Keyboard navPartialTab order OK, no arrow keys or shortcuts
Color contrastFailingMuted text fails WCAG AA
Motion preferencesMissingNo prefers-reduced-motion support
Screen readerPartialSome icon buttons lack aria-label
🐛 Visual Bugs (13 Found)

Critical

  • Safe area inset stacking — Header 135px tall on iPhone 14 Pro (should be ~100px)
  • Gradient rendering on Android — May render as solid color in some WebViews
  • Bottom nav overlap — Extra 2rem creates 146px footer on Pixel 7

High Priority

  • Avatar fallback shows "U" for single-char usernames
  • CSS blur on large photos causes lag on low-end devices
  • Strava activity dialog exceeds viewport on small screens

Medium Priority

  • Long book titles break layout (no truncation)
  • Dark mode toggle FOUC
  • Notification badge clips on small icons
  • Chip alignment inconsistency
🔟 Top 10 UX Priorities
  1. Add search functionality (Journal, Books, Community)
  2. Implement offline mode with sync queue
  3. Fix safe area inset bugs for notched devices
  4. Add comprehensive empty states with CTAs
  5. Respect prefers-reduced-motion for accessibility
  6. Implement error boundaries for crash recovery
  7. Add undo/redo for task completions
  8. Optimize image loading with lazy load + compression
  9. Add keyboard navigation and shortcuts
  10. Implement proper loading skeletons instead of text

📋 Sprint 1 Backlog

Sprint Goal: UI Polish • Duration: 2 weeks • Capacity: 40 story points

Sprint Goal: Deliver a polished, accessible, and visually consistent UI by completing the atomic design system migration, fixing critical visual bugs, improving loading states, and enhancing mobile UX patterns.

Must Have (P0) — 28 Story Points
IDTaskPointsPriority
UI-001Migrate Index.tsx to Atomic Design System8P0
UI-002Fix Safe Area Inset Stacking Issues3P0
UI-003Implement Loading Skeletons Across Core Pages5P0
UI-004Add Comprehensive Empty States with CTAs5P0
UI-005Respect prefers-reduced-motion for Accessibility3P0
UI-006Fix Bottom Nav Overlap and Safe Area Bugs2P0
UI-007Add Proper Error Boundaries2P0
Should Have (P1) — 12 Story Points
IDTaskPointsPriority
UI-008Migrate Books.tsx to Atomic Design5P1
UI-009Fix Avatar Fallback Logic1P1
UI-010Add Haptic Feedback for Task Completion2P1
UI-011Optimize Image Loading with Lazy Load3P1
UI-012Add Visual Sync Status Indicators1P1
⚠️ Capacity Warning & Risks

Current backlog: 48 points (120% of 40-point capacity)

Recommendation: Defer UI-013 (Pull-to-Refresh) and UI-014 (Progress.tsx Migration) to Sprint 2 for exact 40-point fit.

Risk Register

RiskProbabilityImpact
Atomic migration breaks existing functionalityHighHigh
Safe area bugs device-specificMediumHigh
Team velocity unknownHighHigh
Haptics plugin not available on webHighLow
✅ Definition of Done
  • All acceptance criteria met
  • Code follows atomic design system patterns
  • Component is accessible (ARIA, keyboard, contrast)
  • Loading states and empty states implemented
  • Animations respect prefers-reduced-motion
  • Works on iOS (notch) and Android (gesture nav)
  • No console errors or warnings
  • Tested on both light and dark modes

📖 Product Owner Stories

8 Stories • 34 Total Points • Focus: UX Consistency & Error Handling
S1-PO-01: Empty State Consistency Must Have 5 pts

As a new user starting the challenge, I want helpful guidance when I haven't completed any tasks, so that I understand what to do next.

Required Empty States:

  • Journal list — "No journal entries yet" + "Write First Entry" CTA
  • Book list — "Your reading library is empty" + "Add Book" CTA
  • Progress Photos — "No progress photos yet" + "Take Photo" CTA
  • AI Insights — "Write 3+ entries to see your first insights"
  • Story Arcs — "Story arcs are generated weekly from your entries"
  • Community — "Your milestones will appear here"
S1-PO-02: Loading State Consistency Must Have 5 pts

As a user interacting with the app, I want consistent loading indicators, so that I know the app is working.

  • Journal entries loading → skeleton cards
  • AI enrichment processing → "Analyzing your entry..." status
  • Strava sync → button disabled + "Syncing..." text
  • Photo upload → progress indicator (0-100%)
  • Books loading → 3-5 skeleton cards
  • API failures → error message with retry option
S1-PO-03: Error Handling & Recovery Must Have 8 pts

As a user encountering errors, I want clear error messages and recovery options, so that I can resolve issues without losing data.

  • Journal save failure → text preserved in local state + "Retry" button
  • AI enrichment failure → warning (not blocking) + "Retry Analysis" later
  • Strava token expired → "Reconnect Strava" CTA
  • Photo upload error → "Photo must be JPEG/PNG and under 10MB"
  • Offline → "You're offline. Changes will sync when reconnected."
  • Component crash → Error boundary with "Go to Home" button
S1-PO-04 to S1-PO-08 Should/Could Have
StoryTitlePriorityPoints
S1-PO-04Task Completion Flow Polish (animations, undo confirm)Should5
S1-PO-05Onboarding Flow Polish (validation, progress)Should3
S1-PO-06Form Validation & FeedbackShould3
S1-PO-07Responsive Layout FixesCould3
S1-PO-08Micro-interactions & DelightCould2

🖥️ Frontend Tasks

6 Tasks • 34 Hours Total • React 18 + TypeScript + Tailwind
Task Summary
IDTaskHoursRiskPriority
S1-FE-01Fix Safe Area Inset Layout Bugs8HighHIGH
S1-FE-02Optimize Photo Blur Performance6MedMED
S1-FE-03Add prefers-reduced-motion Support4LowHIGH
S1-FE-04Fix Avatar Fallback & Long Text Truncation2LowLOW
S1-FE-05Implement Consistent Loading Skeletons6MedMED
S1-FE-06Audit & Fix Color Contrast (WCAG AA)8HighHIGH
S1-FE-01: Fix Safe Area Inset Layout Bugs (8h)

Files: Layout.tsx, AppHeader.tsx, BottomNav.tsx, use-safe-area.ts

Problem: Header safe area stacking creates 135px padding on iPhone 14 Pro. Bottom nav adds unnecessary 2rem creating 146px footer.

// Current (broken):
pt-[calc(5.5rem+env(safe-area-inset-top))]
pb-[calc(5rem+env(safe-area-inset-bottom)+2rem)]  // Extra 2rem!

// Fixed:
pt-[calc(5.5rem+env(safe-area-inset-top))]
pb-[calc(5rem+env(safe-area-inset-bottom))]

Testing: iPhone 14 Pro, Pixel 7, portrait/landscape, verify no content clipping.

S1-FE-03: prefers-reduced-motion Support (4h)

WCAG 2.1 Level AA requirement. Disable all animations for users with motion sensitivity.

/* Add to tailwind.config.ts */
@media (prefers-reduced-motion: reduce) {
  .animate-fade-in,
  .animate-slide-up,
  .animate-flash {
    animation: none !important;
  }
}

// confetti.ts
const shouldAnimate = !window.matchMedia(
  '(prefers-reduced-motion: reduce)'
).matches;
if (shouldAnimate) confetti({ ... });
S1-FE-05: Loading Skeletons (6h)

Replace all "Loading..." text with proper skeleton components matching page layouts.

// Before:
if (loading) {
  return <div>Loading...</div>;
}

// After:
if (loading) {
  return <DashboardSkeleton />;
}

const DashboardSkeleton = () => (
  <Stack spacing={SPACING[16]}>
    <Skeleton width="100%" height={120} />
    <Skeleton width="100%" height={80} />
    <Skeleton width="100%" height={80} />
  </Stack>
);

Pages affected: Index.tsx, JournalList.tsx, Books.tsx, ProgressGallery.tsx, Community.tsx

🔧 Backend Tasks

4 Tasks • 13 Story Points • Stability & Data Integrity Focus
Task Summary
IDTaskPointsPriority
S1-BE-01Add Input Validation to Critical Edge Functions (Zod)5Critical
S1-BE-02Fix Silent AI Failures with Error Propagation3High
S1-BE-03Implement Database Constraint Validation3High
S1-BE-04Add Bulk Delete Endpoint for Progress Photos2Medium

Edge Function Health: 18/18 Operational

  • ✅ All functions working
  • ⚠️ 17/18 require JWT (only enrich-book-metadata is public)
  • ❌ 0/18 have input validation
  • ⚠️ 2 potential duplicates (strava-oauth vs strava-oauth-simple)
S1-BE-01: Input Validation (5 pts) — Critical

Add Zod schema validation to 4 critical edge functions: enrich-journal-entry, generate-reflection-nugget, strava-sync, enrich-book-metadata

// supabase/functions/_shared/validation.ts
import { z } from "zod";

export const enrichJournalEntrySchema = z.object({
  entryId: z.string().uuid(),
  editedText: z.string().min(1).max(10000),
  date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  time: z.string().regex(/^\d{2}:\d{2}$/)
});
  • Invalid UUID → 400 "Invalid entry ID format"
  • Missing required fields → 400 with field name
  • No database queries executed if validation fails
S1-BE-02: Fix Silent AI Failures (3 pts)

Replace silent fallback values with explicit error handling and retry logic.

  • Standardize error types: AIProviderError, ValidationError, NotFoundError
  • Add retry with exponential backoff for 429 errors
  • Track enrichment status: pendingprocessingcompleted / failed
  • Remove as any casts in journalService.ts
S1-BE-03: Database Constraints (3 pts)
-- Enforce 75-day limit
ALTER TABLE challenge_days
ADD CONSTRAINT check_day_number_range
CHECK (day_number >= 1 AND day_number <= 75);

-- Prevent duplicate reading sessions per day
CREATE UNIQUE INDEX idx_reading_sessions_unique_book_date
ON reading_sessions(user_id, book_id, date)
WHERE book_id IS NOT NULL;

-- Clear AI enrichment when journal text is edited
CREATE TRIGGER trigger_clear_enrichment_on_edit
BEFORE UPDATE ON journal_entries
FOR EACH ROW
EXECUTE FUNCTION prevent_enrichment_overwrite();

🚀 DevOps Plan

4 Tasks • ~2 Hours Total • Domain: 75hard.tapfumamv.com
Architecture Overview
Internet
    ↓
Cloudflare Tunnel (75hard.tapfumamv.com)
    ↓ HTTPS (automatic TLS)
VPS (ports 5175/3002)
    ↓
systemd services → Node.js/Static Server
    ↓
Vite Build Output (dist/)
    ↓
Supabase Backend (hosted)
ComponentTechnologyPort
Productionserve dist/ (static)3002
Dev ServerVite dev mode5175
Reverse ProxyCloudflare TunnelHTTPS
Process Managersystemd
Deployment Tasks
IDTaskTime
S1-DO-01VPS Environment & Build Setup (npm install, build, verify)30 min
S1-DO-02Systemd Services (75hard-prod.service, enable auto-start)20 min
S1-DO-03Cloudflare Tunnel (config, DNS, HTTPS)45 min
S1-DO-04Monitoring & Health Checks (cron, log retention)25 min

Deployment Workflow

# Deploy
cd /root/.openclaw/workspace/75hard
npm run build
systemctl restart 75hard-prod
curl https://75hard.tapfumamv.com

# Rollback
git reset --hard <PREVIOUS_COMMIT>
npm run build
systemctl restart 75hard-prod

🎨 UI Design Tasks

8 Tasks • Focus: Accessibility, Consistency, Design System
Task Overview
IDTaskPriorityEffort
S1-UI-01Fix Color Contrast Issues (WCAG AA)HIGHM
S1-UI-02Consolidate Design System TokensHIGHL
S1-UI-03Fix Safe Area Inset Padding BugsHIGHS
S1-UI-04Implement prefers-reduced-motionHIGHM
S1-UI-05Standardize Component Spacing & BordersMEDM
S1-UI-06Fix Typography HierarchyMEDS
S1-UI-07Loading Skeleton ConsistencyMEDM
S1-UI-08Dark Mode Consistency AuditMEDS
Color Contrast Fixes Needed
ElementCurrent RatioRequiredFix
Muted text on background~3.2:14.5:1Darken L:47% → L:42%
Primary links on white~3.8:14.5:1Darken L:60% → L:54%
Success text on light bg~3.5:14.5:1Darken L:36% → L:32%
Missing Design Tokens & Patterns
  • Focus State System — No consistent focus indicators for keyboard navigation
  • Elevation System — Shadows defined but no semantic mapping (elevation-1/2/3)
  • Interactive State Tokens — No hover/active/disabled colors defined
  • Grid System — No documented responsive grid (4/8/12 columns)
  • Icon Size Scale — Only one size (24px), need Small (16px), Medium (20px), Large (24px), XL (32px)

✨ UX Improvements

6 Improvements • Focus: Friction Reduction & Native Feel
Improvement Overview
IDImprovementPriorityEffortImpact
S1-UX-01Quick Day Jump Navigation (date picker)HIGH2-3 days70% friction reduction
S1-UX-02Task Completion Undo (3s toast)HIGH3-4 daysReduces user anxiety
S1-UX-03Empty State CTAsMED2 daysImproves onboarding
S1-UX-04Horizontal Swipe Between DaysMED4-5 daysNative mobile feel
S1-UX-05Haptic Feedback SystemMED1-2 daysApp-native delight
S1-UX-06Sync Status IndicatorsMED2-3 daysReduces user anxiety
S1-UX-01: Quick Day Jump (Date Picker)

Problem: Navigating from Day 50 to Day 1 requires 49 taps on the "Previous" button.

Solution: Tap the date display → calendar overlay with challenge day numbers (1-75). Keyboard shortcut: Cmd/Ctrl + G.

Current depth: 49 taps → Target: 2 taps

S1-UX-02: Task Completion Undo

Problem: Accidental task completion cannot be reversed. Users express anxiety about misclicks.

Solution: Toast-based undo pattern with 3-second window:

[✓] Workout 1 completed  [UNDO]
// 3-second window, haptic on undo
// Don't sync to DB until window expires
S1-UX-05: Haptic Feedback System

Tiered haptic system using Capacitor Haptics plugin:

ActionHaptic Type
Task completionHeavy
Tab switchLight
Day change (swipe)Medium
Photo captureHeavy
Day complete (7/7)Success
Boundary hitWarning
Navigation Depth Audit
ActionCurrent TapsTargetStatus
Complete task1-21-2Good
Navigate to Day 1 (from 50)492Fix
Write journal entry21-2Good
Add new book22Good
Undo task completion∞ (manual)1Fix
View sync status31-2Improve

📊 Sprint 1 Summary

7
Must Have (P0)
5
Should Have (P1)
2
Could Have (P2)
Sprint Capacity Usage40/40 pts
Accessibility Target85 → 95+ Lighthouse
Atomic Design Compliance33% → 60%+
Backend StabilityEdge Functions Validated