5.4 KiB
5.4 KiB
TabataGo — iOS Tabata Workout App
Tabata interval training app for iOS + watchOS with HealthKit integration.
Agent Context
This project is part of the Millian Team — an AI agent engineering team. When working here, agents should load the relevant skill:
senior-ios— SwiftUI, Xcode, iOS/watchOS developmentsenior-backend— Supabase backendsenior-devops— Deploy infrastructurepo-pm— Product vision, specs, validation
Tech Stack
| Layer | Tech |
|---|---|
| App | SwiftUI, iOS 26.0+ |
| Watch | SwiftUI, watchOS 11.0+ |
| Widget | WidgetKit, Live Activities |
| Language | Swift 6.0 (strict concurrency) |
| Architecture | MVVM, @Observable, AppState central |
| Backend | Supabase (PostgreSQL, Auth, Storage) |
| Subscriptions | RevenueCat 5.x |
| Analytics | PostHog 3.x |
| Health | HealthKit (heart rate, calories, workouts) |
| Music | Apple Music integration + YouTube worker |
| Build | XcodeGen (project.yml → .xcodeproj) |
| Package Manager | Swift Package Manager |
Project Structure
tabatago/
├── tabatago-swift/ # Main Xcode project
│ ├── project.yml # XcodeGen spec
│ ├── Config/
│ │ ├── Secrets.xcconfig # API keys (not committed)
│ │ └── Secrets.xcconfig.example
│ ├── TabataGo/ # iOS App
│ │ ├── App/ # App entry, state, root view
│ │ │ ├── TabataGoApp.swift
│ │ │ ├── RootView.swift
│ │ │ └── AppState.swift
│ │ ├── Views/
│ │ │ ├── Tabs/ # MainTabView, Home, Activity, Programs, Profile
│ │ │ ├── Player/ # Workout player (PlayerView, NowPlaying)
│ │ │ ├── Programs/ # ProgramDetail, BodyZone
│ │ │ ├── Onboarding/ # Onboarding flow
│ │ │ ├── Paywall/ # RevenueCat paywall
│ │ │ ├── Complete/ # Workout completion screen
│ │ │ ├── Settings/ # Settings, policies
│ │ │ └── Components/ # Shared UI components
│ │ ├── ViewModels/ # HomeVM, HealthVM, PlayerVM, PurchaseVM, MusicVM
│ │ ├── Models/ # WorkoutProgram, WorkoutSession, UserProfile, etc.
│ │ ├── Services/ # Supabase, HealthKit, Music, Audio, Purchase, Analytics
│ │ ├── Theme/ # App theme
│ │ ├── Utilities/ # Strings, Environment
│ │ └── Resources/ # Assets, Localizable, entitlements
│ ├── TabataGoWatch/ # watchOS App
│ │ ├── Views/ # WatchRoot, WatchIdle, WatchActivity, WatchPlayer
│ │ ├── Services/ # WatchConnectivity, WatchPlayerEngine
│ │ ├── Complications/ # Watch face complications
│ │ └── Resources/
│ ├── TabataGoWidget/ # iOS Widget + Live Activities
│ ├── TabataGoTests/ # Unit tests
│ └── TabataGoUITests/ # UI tests
├── supabase/ # Supabase config
│ ├── schema.sql
│ ├── seed.sql
│ ├── setup-admin.sql
│ └── migrations/ # SQL migrations (001-006)
└── youtube-worker/ # Node.js worker for YouTube music
├── server.js
├── package.json
└── Dockerfile
Dependencies (SPM)
- Supabase 2.5+ — Backend SDK (Auth, Database, Storage)
- RevenueCat 5.0+ — In-app purchases
- PostHog 3.0+ — Analytics
Features
- Tabata/interval workout player with configurable timers
- Pre-built workout programs by body zone
- HealthKit integration (heart rate, calories, workout saving)
- Apple Watch companion with real-time metrics
- Live Activities + Dynamic Island
- Music integration (Apple Music + YouTube)
- RevenueCat subscriptions
- Onboarding flow
- Activity tracking & workout history
Commands
# From tabatago-swift/
xcodegen generate # Generate .xcodeproj
open TabataGo.xcodeproj # Open in Xcode
# In Xcode
Cmd+R → Run on simulator
Cmd+U → Run tests
Configuration
Config/Secrets.xcconfigcontains API keys (not committed)- Template:
Config/Secrets.xcconfig.example - Env vars:
SUPABASE_URL,SUPABASE_ANON_KEY,REVENUECAT_API_KEY,POSTHOG_API_KEY
Current State
- Version: 1.0 (build 2) — not yet released
- State: App functional, needs finishing work
- Platforms: iOS 26.0+, watchOS 11.0+
- Requires: macOS with Xcode 26+ to build
Supabase Schema
Tables: profiles, workout_sessions, workout_programs, download_jobs, music_genre, etc.
See supabase/schema.sql and supabase/migrations/ for full schema.
Team Rules
- Swift Concurrency — async/await everywhere, no completion handlers
- @Observable — not @ObservableObject
- No force unwrap —
guard letalways, never! - SwiftUI only — no UIKit unless unavoidable
- XcodeGen — project.yml is source of truth, not .xcodeproj
- Secrets — never commit Secrets.xcconfig
- French — all user-facing strings in French (Localizable.xcstrings)
Project Context
- User: Millian LMX (CEO)
- Gitea: https://gitea.1000co.fr/millianlmx/tabatago
- Supabase: Managed instance (URL in secrets)
- App Store: Not yet published