29 September 2026 · checked against Flutter 3.47.5
2 high3 medium3 low
74grade C
DependenciesB
86 / 100 · 1 medium, 2 low
Android & Google PlayC
69 / 100 · 1 high, 1 medium, 1 low
iOS & App StoreA
100 / 100 · no findings
Security & secretsA
100 / 100 · no findings
Code healthA
100 / 100 · no findings
Tests & CIC
72 / 100 · 1 high, 1 medium
Assets & sizeA
100 / 100 · no findings
Fix first
High Release builds are signed with the debug key · Android & Google Play
High No tests · Tests & CI
Dependencies
86 · B
Medium
haptic_feedback is 2 breaking releases behind (0.6.4+3 → 0.8.0)
Each breaking release (a new major version, or a new minor before 1.0) can need code changes. The further behind, the bigger the eventual upgrade, and fixes only land on the latest line.
Fix: Read the changelog for each one and upgrade a step at a time.
pubspec.lock
deps.breaking-behind
Low
7 direct dependencies are one breaking release behind
Fix: Upgrade while the gap is one version; it gets harder with each release you skip.
pubspec.lock
deps.one-breaking-behind
Low
7 dependencies are never imported: animations, collection, flutter_hooks, flutter_image_compress, haptic_feedback, hooks_riverpod, lottie
No Dart file imports them. Unused packages still add native code, permissions and upgrade work.
Fix: Check each one is not used some other way (a font, native code, a build step), then remove it.
pubspec.yaml
deps.unused
Android & Google Play
69 · C
High
Release builds are signed with the debug key
This is the template's placeholder so that flutter run --release works. Google Play rejects uploads signed with a debug key. (If a CI step signs the bundle after the build, this does not apply.)
Health Connect data to declare: READ_STEPS, READ_ACTIVE_CALORIES_BURNED, READ_TOTAL_CALORIES_BURNED
Google Play reviews access to Health Connect: the Health apps declaration in Play Console must list each data type and why the app needs it, and access is granted only for the uses the policy allows.
Fix: Request only the data types the features use, and prepare the declaration (App content → Health apps) before submitting.
Since Android 14, SCHEDULE_EXACT_ALARM is denied by default for newly installed apps (apart from alarm and calendar apps), so scheduling an exact alarm fails until the user turns it on in settings.
Fix: Check canScheduleExactAlarms() before scheduling; fall back to an inexact alarm or send the user to the setting.
android/app/src/main/AndroidManifest.xml:9
android.exact-alarm-denied
Tests & CI
72 · C
High
No tests
Every release is verified by hand, so regressions reach users, and nobody can refactor safely.
Fix: Start where bugs cost most: unit tests for the business logic (pricing, auth state, data parsing), then widget tests for the main flows. Run them in CI.
test/
testing.none
Medium
No CI configuration
Nothing builds the app or runs the tests on each change, so a broken build is found by whoever builds next, often on release day.
Fix: Add a workflow that runs flutter analyze, flutter test and a release build on every pull request (GitHub Actions and Codemagic both have free tiers).
Permissions added by plugins. Plugins merge their own permissions into the Android manifest at build time. Check the merged manifest of a release build (Android Studio: Merged Manifest tab) against what the app needs.
16 KB memory pages. Google Play requires apps targeting Android 15 or later to support 16 KB page sizes. Native libraries from plugins can fail this; check the release bundle in Android Studio's APK Analyzer.
Privacy manifests. App Store Connect checks required-reason APIs and third-party SDK privacy manifests when a build is uploaded, and reports problems by email (ITMS-91053, ITMS-91061).
Store privacy answers. The Play Data safety form and the App Store privacy labels must match what the app and every SDK in it collect.
Account deletion. If users can create an account, the App Store requires a way to delete it inside the app, and Google Play requires a web link for deletion requests.
Runtime behaviour. Startup time, jank, memory and battery need a profile build on a real low-end device; crashes need the production crash reports.
Design of the code. Whether the architecture will survive the next year of features is a judgement a person makes by reading it.