Project Structure

Understand the Kotlin template folders, feature modules, and ownership boundaries.

The Android template is one Gradle app module with package code under com.soarstarter.kotlin. The main split is core/ for reusable app services, data/ for persistence and network boundaries, feature/ for screen families, and nav/ for typed routes and graph composition.

The template's AGENTS.md / CLAUDE.md tree is slightly stale. Current code has core/showcase/, no feature/test/, no AuthGate.kt, and no separate MainNavGraph.kt; MainNavGraph is a private composable inside AppNavGraph.kt.

Project map

local.properties is git-ignored and belongs at the repo root. Android Studio also writes sdk.dir there. Firebase client configuration belongs at app/google-services.json; the Gradle plugin is applied only when that file is present.

App entry points

FileRole
SoarApp.kt@HiltAndroidApp; starts Sentry, PostHog, and the update controller on process start
MainActivity.kt@AndroidEntryPoint; handles deep-link intents, edge-to-edge bars, theme, locale, gates, root nav, and ToastHost
app/build.gradle.ktsAndroid SDK versions, BuildConfig fields, conditional Google Services plugin, signing config
AndroidManifest.xmlPermissions, FCM service, launcher activity, custom scheme, App Links

core/

core/ is reusable app infrastructure. Feature code can depend on it; core/ should not depend on feature screens.

FolderOwns
analytics/AnalyticsController and typed AnalyticsEvent for PostHog
auth/SessionController and Google Sign-In controller
biometric/Biometric app-lock controller and gate
deeplink/DeepLinkHandler, DeepLinkResolver, DeepLinkDestination
di/Hilt modules for DataStore, repositories, session flow, coroutines, biometric binding
error/AppErrorBus, ErrorBoundary, SentryReporter
haptics/Android vibrator wrapper used by toast and demos
legal/Legal document model, consent controller, LEGAL_VERSION
locale/AppLanguage, LocaleController, LocalizedAppHost
onboarding/Onboarding completion controller
purchases/RevenueCat lifecycle, entitlement reader, PremiumGate
rating/Play In-App Review controller
result/AppResult, AppError, friendly error mapping
showcase/Capability catalog models shared by the removable Showcase leaf
ui/components/Reusable Compose controls and states
ui/theme/Material 3 color schemes, typography, theme controller
ui/toast/SharedFlow toast controller and root overlay
update/Play In-App Updates controller and gate state

data/

data/ is where platform and backend details are hidden from screens.

FolderOwns
local/AppPreferences, the typed DataStore flows for theme, locale, gates, rating, and biometrics
model/Serializable app models such as Todo, Profile, Subscription, and profile/user DTOs
network/NetworkObserver, backed by ConnectivityManager.NetworkCallback
notifications/FCM service, token table data source, in-memory inbox, test-push function client
remote/SupabaseClientProvider and Supabase plugin setup
repository/Auth, todos, profile, subscription, and upload repositories plus Supabase remote data sources

When adding a backend-backed feature, follow the existing shape:

data/model/NewThing.kt
data/repository/NewThingRemoteDataSource.kt
data/repository/SupabaseNewThingRemoteDataSource.kt
data/repository/NewThingRepository.kt
core/di/RepositoryModule.kt binding
feature/newthing/NewThingViewModel.kt
feature/newthing/NewThingScreen.kt
nav/Routes.kt + graph mount

feature/

Each feature folder owns a screen family, its view models, and private UI.

FolderRole
auth/Login, signup, verification, forgot/reset password, pure validators
component/Data-driven UI component gallery and interactive demos
guide/Purchase-gated developer-guide example content
home/Home tab and entitlement-aware license card
legal/Consent gate UI and legal document screens
main/Main shell, bottom tabs, drawer, sign-out state
notifications/Push setup, FCM token display, in-memory inbox, test push button
onboarding/Four-page onboarding pager
paywall/Paywall, subscription management, redeem-code screen
permissions/Permission priming screen
profile/Me tab, personal info, account security, biometric toggle
refer/Android share-sheet referral example
showcase/Removable demo catalog and capability demos
todos/Example CRUD feature on the Home stack
update/Update dialogs used by UpdateGate
upload/Supabase Storage image upload sample

There is no current feature/test/ folder. Use the Showcase demos or add your own debug-only screen if you need manual observability triggers.

Current files:

FileRole
Routes.ktType-safe @Serializable app routes in object AppRoutes
AppNavGraph.ktRoot gates, outer nav destinations, auth graph, and private MainNavGraph
OnboardingGate.ktGate that shows onboarding before consent/main content

The tab graph is mounted inside feature/main/MainShellScreen.kt, where each tab gets a nested destination graph and tab navigation preserves back stacks.

Tests

Unit tests live in app/src/test. The current suite covers controllers, repositories, validators, model rules, component catalogs, entitlement gates, and view models using fakes and kotlinx-coroutines-test.

Instrumented tests live in app/src/androidTest. Current files include a smoke instrumented test and nav/NavRouteTest.kt. Run them only with a connected device or emulator:

./gradlew connectedDebugAndroidTest

On this page