Files
HealthTracking/docs/superpowers/plans/2026-06-04-fightrate-android-mvp.md
T

148 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# FightRate Android MVP Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build the first Android-native FightRate app scaffold for live combat-sport heart-rate tracking with Magene H003 BLE support.
**Architecture:** Android-native Kotlin app using Jetpack Compose for UI, pure Kotlin domain/parse logic, Android BLE APIs isolated behind a BLE package, and local persistence planned with Room. The first implementation slice creates a buildable app shell plus a tested Heart Rate Measurement parser.
**Tech Stack:** Kotlin, Gradle Kotlin DSL, Android Gradle Plugin, Jetpack Compose Material 3, Coroutines/Flow, Android BLE APIs, JUnit.
---
## File Structure
```text
settings.gradle.kts Project module declaration
build.gradle.kts Root Gradle plugin versions
gradle.properties Android/Kotlin build flags
app/build.gradle.kts Android app dependencies and config
app/src/main/AndroidManifest.xml Permissions, activity, BLE feature flags
app/src/main/java/com/healthtracking/fightrate/MainActivity.kt
app/src/main/java/com/healthtracking/fightrate/ble/HeartRateParser.kt
app/src/main/java/com/healthtracking/fightrate/domain/model/FightSport.kt
app/src/main/java/com/healthtracking/fightrate/domain/model/HeartRateMeasurement.kt
app/src/main/java/com/healthtracking/fightrate/ui/theme/FightRateTheme.kt
app/src/main/java/com/healthtracking/fightrate/ui/theme/Color.kt
app/src/main/java/com/healthtracking/fightrate/ui/screens/HomeScreen.kt
app/src/test/java/com/healthtracking/fightrate/ble/HeartRateParserTest.kt
```
---
## Task 1: Android project scaffold
**Files:**
- Create: `settings.gradle.kts`
- Create: `build.gradle.kts`
- Create: `gradle.properties`
- Create: `app/build.gradle.kts`
- Create: `app/src/main/AndroidManifest.xml`
- Create: `app/src/main/java/com/healthtracking/fightrate/MainActivity.kt`
- [ ] **Step 1: Create Gradle project files**
Use Android app module `:app`, package `com.healthtracking.fightrate`, min SDK 26, target/compile SDK 35, Kotlin 2.x compatible Compose.
- [ ] **Step 2: Create manifest**
Declare Bluetooth permissions for Android 12+, legacy Bluetooth/location permissions for Android 11 and below, BLE feature, foreground service permissions, and `MainActivity`.
- [ ] **Step 3: Create minimal MainActivity**
Use `ComponentActivity`, `setContent`, `FightRateTheme`, and `HomeScreen`.
- [ ] **Step 4: Verify**
Run: `./gradlew :app:assembleDebug`
Expected: build succeeds when Gradle/Android SDK are installed.
---
## Task 2: Heart Rate Measurement parser, TDD first
**Files:**
- Create: `app/src/main/java/com/healthtracking/fightrate/ble/HeartRateParser.kt`
- Create: `app/src/main/java/com/healthtracking/fightrate/domain/model/HeartRateMeasurement.kt`
- Create: `app/src/test/java/com/healthtracking/fightrate/ble/HeartRateParserTest.kt`
- [ ] **Step 1: Write tests**
Cover these Bluetooth Heart Rate Measurement payloads:
```kotlin
byteArrayOf(0x00, 72) // uint8 BPM
byteArrayOf(0x01, 0x2C, 0x01) // uint16 BPM = 300
byteArrayOf(0x08, 90, 0x34, 0x12) // energy expended = 0x1234
byteArrayOf(0x10, 120, 0x00, 0x04) // RR interval = 1024 -> 1000ms
byteArrayOf() // invalid empty payload
```
- [ ] **Step 2: Implement parser**
Parse flags, BPM format, optional energy expended, optional RR intervals. Throw `IllegalArgumentException` for malformed payloads.
- [ ] **Step 3: Verify**
Run: `./gradlew :app:testDebugUnitTest`
Expected: all parser tests pass.
---
## Task 3: FightRate visual shell
**Files:**
- Create: `app/src/main/java/com/healthtracking/fightrate/ui/theme/Color.kt`
- Create: `app/src/main/java/com/healthtracking/fightrate/ui/theme/FightRateTheme.kt`
- Create: `app/src/main/java/com/healthtracking/fightrate/domain/model/FightSport.kt`
- Create: `app/src/main/java/com/healthtracking/fightrate/ui/screens/HomeScreen.kt`
- [ ] **Step 1: Define design tokens**
Use the FightRate palette from the design system: black canvas, charcoal surfaces, fight orange, redline red, recovery green, muted gray text.
- [ ] **Step 2: Build static HomeScreen**
Include static UI cards for sensor status, current BPM, round timer, zone bar, sport chips, and session metrics.
- [ ] **Step 3: Verify**
Run: `./gradlew :app:assembleDebug`
Expected: app compiles and opens to a dark FightRate dashboard.
---
## Task 4: BLE connection layer placeholder
**Files:**
- Create: `app/src/main/java/com/healthtracking/fightrate/ble/HeartRateBleConstants.kt`
- Create: `app/src/main/java/com/healthtracking/fightrate/ble/HeartRateBleScanner.kt`
- Create: `app/src/main/java/com/healthtracking/fightrate/ble/HeartRateBleClient.kt`
- [ ] **Step 1: Define UUID constants**
```kotlin
HEART_RATE_SERVICE = 0000180d-0000-1000-8000-00805f9b34fb
HEART_RATE_MEASUREMENT = 00002a37-0000-1000-8000-00805f9b34fb
BODY_SENSOR_LOCATION = 00002a38-0000-1000-8000-00805f9b34fb
BATTERY_SERVICE = 0000180f-0000-1000-8000-00805f9b34fb
BATTERY_LEVEL = 00002a19-0000-1000-8000-00805f9b34fb
```
- [ ] **Step 2: Scanner contract**
Expose a Kotlin API that can later be wired to `BluetoothLeScanner` and emits scan results.
- [ ] **Step 3: Client contract**
Expose connect/disconnect and `Flow<HeartRateMeasurement>` API.
---
## Current Execution Choice
The user asked to proceed with app creation, so start with **Inline Execution** for Tasks 1–3, stopping after verification evidence and reporting environment blockers if Android SDK/Gradle is unavailable.