App Name: GymExe Package Name: com.sjn.gym Purpose: A modular, offline-first workout tracker for gym goers. Target OS: Android (Min SDK 26, Target SDK 36). Philosophy: Modular architecture, latest stable tools, absolute control over data (backups, logs), and "intelligent" input methods.
- Language: Kotlin 2.3.20
- JDK: Java 25 (OpenJDK). Build logic uses Java 25 Toolchain.
- Build System: Gradle 9.4.1 (Wrapper included)
- Android SDK: Compile 36, Min 26.
- UI Framework: Jetpack Compose (Material 3).
- Dependency Injection: Hilt.
- Database: Room (SQLite).
- CI/CD: GitHub Actions (Build, Test, Release).
- Code Quality: Spotless (Ktlint), Android Lint.
- Dev Tools: Chucker (Network Inspection), Timber (Logging), LeakCanary.
The app follows a fully modular architecture optimized with convention plugins (build-logic), Gradle Isolated Projects, and Configuration Cache for faster builds and easier debugging:
:app: Main entry point, navigation graph, flavor configuration.:core:ui: Design system, themes (GymExeTheme), common components.:core:data: Room Database, Repository implementations, DataStore.:core:model: Domain entities (Exercise, Workout, etc.).:feature:settings: Settings screens (Theme, Units, Backup placeholders).:feature:workout: Workout logging, Intelligent Text Box (PlateCalculator), Exercise list.:feature:profile: "You" page placeholders.:feature:onboarding: Setup wizard flow.
File: .github/workflows/build.yml
Features:
- JDK 25 Setup: Uses Temurin distribution.
- Caching: Gradle build/cache restored effectively. AVD caching (API 36).
- Signing: Uses repo-stored
app/debug.keystorewith defaultandroidcredentials for simplicity. - Versioning:
- Stable: Tag
v*-> Version1.2.3. - Dev: Hardcoded to
0.0.1(versionName) and1(versionCode) to preserve configuration cache. - Fallback: Defaults to
0.0.1if no tags exist.
- Stable: Tag
- Flavors: Builds
dev(debuggable, suffixed) andstable(minified) variants. - Artifacts:
GymExe-dev-release.apk/GymExe-dev-debug.apk(Dev builds).GymExe-stable-release.apk(Stable builds).
- Emulator: Uses
api-level: 36.
Directory: build-logic/
Purpose: Share build configuration via Convention Plugins.
Plugins Available:
gymexe.android.application: Common Android App config (SDK versions, Kotlin options).gymexe.android.library: Common Android Library config.gymexe.android.compose: Jetpack Compose setup.gymexe.android.hilt: Hilt/KSP setup.gymexe.android.feature: Feature module config (aggregates library, hilt, compose).gymexe.spotless: Spotless configuration.
- Initialize Repository:
README.md,LICENSE,.gitignorecreated. - AGENTS.md: Comprehensive agent instructions added.
- Gradle Setup:
gradle.properties(JVM args, optimizations),libs.versions.tomlconfigured. - Signing:
debug.keystoregenerated and tracked.build.gradle.ktsuses it. - CI/CD Pipeline:
build.ymlrobust, correct versioning, artifact upload fixed. - Java 25 Upgrade: Toolchains configured, Gradle plugins updated.
- Strict Linting: Spotless applied, Android lint enabled.
- Icons: Vector Assets (Adaptive) created. New Splash Icon created.
- Theming Engine: Material 3, Dark/Light/System mode, Dynamic Color support.
- Navigation: Type-safe Compose Navigation set up (
GymExeNavHost). - Build Logic: Infrastructure created.
- Splash Screen: Implemented
androidx.core.splashscreenfor instant startup.
- Welcome Screen: Basic UI implemented.
- DataStore:
UserPreferencesRepositorystores onboarding status. - Profile Setup: Input fields for gender/height/weight.
- Experience Level: Selection UI implemented.
- Equipment Setup: Selection UI implemented.
- Theme Settings: Functional UI for switching themes (System/Light/Dark).
- Settings UI: "Hexium" style implementation (Segmented Buttons, Developer Options).
- Updater:
- Stable: Checks latest tag, prioritizes ABI-specific APKs.
- Dev: Checks dev tag changelog, forces
dev-release. - UI: Dialog shows version diff, changelog, and download progress/size.
- Backup & Restore: Functional integration with
BackupRepository(File picker/saver). - Unit Configuration: Metric/Imperial toggle (Weight: kg/lbs, Dist: km/mi, Size: cm/in).
- Developer Options: Copy Logs / Save Logs, Network Inspector launch.
- First Day of Week: Auto-detect from Calendar or manual override.
- Clear Logs: Feature added to wipe logs from device.
- Entities:
ExerciseEntitycreated (with instructions).RoutineEntityandWorkoutPlanEntitycreated. - Database:
GymDatabaseconfigured with pre-population callback. - DAO:
ExerciseDaoimplemented. - Migrations: Logic for merging user vs built-in data needed later.
- Intelligent Text Box:
PlateCalculatorandWeightInputParserimplemented and tested. - Auto-Merger: Logic to merge weights (e.g.,
5 5->2x5) for Stackable equipment. - Strict Mode: Validation for non-stackable equipment (Dumbbells/Selectorized Machines).
- UI Integration:
WorkoutScreenconnects input to parser and validation. - Syntax Highlighting: Text box colors Quantity, Operator, and Weight.
- Library UI: Revamped. Routines tab prioritized and fully implemented with lists. Exercises tab accessible alongside it.
- Exercise Detail: UI skeleton implemented.
- Workout Session:
- Sets: Types (Warmup, Failure, Drop set, etc.).
- Timers: Quick timer, Rest timer.
- Notifications: Ongoing workout notification.
- Basic Screen: UI with revamped Height Input supporting Feet & Inches, and structured sections.
- Graphs: Weight History Line Chart UI implemented in Canvas, ready for real data.
- R8 Support: ProGuard rules added for Room, Serialization, and Retrofit to support
android.enableR8.fullMode=true. - Global Crash Handler:
CrashActivitycatches uncaught exceptions indevbuilds and offers log sharing. - Robust Logging:
LogRepositoryis now synchronized.build.ymlcaptures CI logs efficiently. - CI Optimization: Removed redundant ARM64 tests and reduced log verbosity.
- Instrumented Tests on R8 builds: Implemented specific, targeted ProGuard rules (
androidx.tracing,kotlin.time,kotlin.collections, etc.) via a dedicatedbenchmarkbuild type.
-
Instrumented Test Stability:
- Architecture: The project now uses a
benchmarkbuild type (inheriting fromrelease) specifically for CI instrumented tests. This build type appliesapp/proguard-test-rules.proto prevent test runner crashes while keeping R8 full mode enabled. - Workflow:
- Manual QA: Build/Install
devRelease. This is a strict R8 build (identical to productionstableRelease). - CI Testing: The CI runs
connectedDevBenchmarkAndroidTest. This uses thebenchmarkbuild type which includes the necessary keep rules for the test harness.
- Manual QA: Build/Install
- Constraint: Instrumented tests currently require a CI environment with KVM (hardware acceleration) support. The local agent environment does NOT support KVM, so tests must be verified via GitHub Actions logs.
- Architecture: The project now uses a
-
Fix AGP/KSP + JUnit 5
failOnNoDiscoveredTestsIssue (Completed):- Fix: Resolved natively via Gradle build logic configuration. Configured JUnit Platform with
testTask.setProperty("failOnNoDiscoveredTests", false)andtestTask.systemProperty("junit.jupiter.execution.failIfNoTests", "false"). TheDummyTest.ktfiles have been removed from the repository.
- Fix: Resolved natively via Gradle build logic configuration. Configured JUnit Platform with
-
Routines & Scheduling Logic (Completed):
- Implement CRUD operations for
RoutineandWorkoutPlan. - Connect UI to
RoutineRepository(needs creation). - Implement logic to "Activate" a routine and reflect it on Home Screen.
- Implement CRUD operations for
-
Exercise Data Population (Completed):
- Add real data for
instructionsand more exercises.
- Add real data for
- Feature Convention Plugin: Create a plugin to aggregate
android-library,android-compose, andandroid-hiltfor feature modules to reducebuild.gradle.ktsboilerplate. - JVM Library Convention Plugin: Create a plugin for pure Kotlin modules (e.g.,
:core:model) to avoid Android overhead where unnecessary. - Roborazzi Integration: Create a convention plugin to standardize screenshot testing configuration across UI modules.
- Kover Integration: Set up code coverage aggregation for the entire project.
- Setup Script: Integrated into
AGENTS.mdfor centralized environment initialization. - Dependency Bundling: Group related dependencies in
libs.versions.toml(e.g.,compose-ui,unit-test) for cleaner build files.
- Konsist Tests: Integrated
Konsistto enforce architectural rules (e.g., ViewModels must reside in feature packages).
- Roborazzi on CI: Ensure screenshot tests run and upload artifacts on failure.
- Release Notes Generation: Can still be written manually for now, or automate further with Release Drafter later.
- Instrumented Tests: Add Emulator-based tests (
managed devices) to catch runtime crashes on CI.