Root structure
The package name
com.demodogo.ev_sum_2 represents the application identifier. All code is organized under this namespace.Data layer
The data layer contains all code related to data access and persistence:Key files
FirebaseModule.kt
FirebaseModule.kt
Initializes Firebase services and provides singleton instances of
Dependencies: Firebase SDK
FirebaseAuth and FirebaseFirestore.Purpose: Centralized Firebase configurationDependencies: Firebase SDK
AuthRepository.kt
AuthRepository.kt
Manages Firebase Authentication operations including login, registration, password reset, and session state.Key methods:
suspend fun login(email: String, password: String)suspend fun register(email: String, password: String)fun authStateFlow(): Flow<FirebaseUser?>
data/repositories/AuthRepository.kt:1PhraseRepository.kt
PhraseRepository.kt
Handles CRUD operations for phrases in Firestore. Automatically scopes data to the current user’s UID.Key methods:
suspend fun add(text: String)suspend fun get(): List<Phrase>suspend fun update(id: String, newText: String)suspend fun delete(id: String)
data/repositories/PhraseRepository.kt:1LocationRepository.kt
LocationRepository.kt
Wraps Google Play Services FusedLocationProviderClient to access device GPS coordinates.Key methods:
fun hasPermission(): Booleansuspend fun getLatLng(): Pair<Double, Double>
SessionStore.kt
SessionStore.kt
Uses DataStore Preferences API for local key-value storage. Stores session-related data.
Domain layer
The domain layer contains pure Kotlin code with no Android or Firebase dependencies:Key files
Phrase.kt
Phrase.kt
Represents a user-created phrase with metadata.Location:
domain/models/Phrase.kt:1DeviceLocation.kt
DeviceLocation.kt
Represents GPS coordinates.
SpeechNormalization.kt
SpeechNormalization.kt
Contains algorithms for converting spoken Spanish to text suitable for email/password fields.Key functions:
normalizeEmailFromSpeech(input: String): StringnormalizePasswordFromSpeech(input: String): String
- “arroba” → ”@”
- “punto” → ”.”
- “guion bajo” → ”_”
- “uno” → “1”
domain/validators/SpeechNormalization.kt:1AppException.kt / AuthException.kt / DataException.kt
AppException.kt / AuthException.kt / DataException.kt
Domain-specific exception classes for error handling throughout the application.
The domain layer can be tested with standard JUnit without requiring the Android framework or Firebase emulators.
Service layer
The service layer coordinates between UI and data, and controls device hardware:Key files
AuthService.kt
AuthService.kt
Orchestrates authentication flow with error mapping.Key methods:
suspend fun login(email: String, password: String)suspend fun register(email: String, password: String)suspend fun recover(email: String)fun authStateFlow(): Flow<FirebaseUser?>
services/AuthService.kt:1LocationService.kt
LocationService.kt
Combines GPS coordinates with reverse geocoding to provide location + address.Key methods:
Location:
fun hasPermission(): Booleansuspend fun getLocationWithAddress(): LocationResultprivate suspend fun reverseGeocodeSafe(lat: Double, lon: Double): String?
Location:
services/LocationService.kt:1SpeechController.kt
SpeechController.kt
Wraps Android’s SpeechRecognizer for voice input.Key methods:
Location:
fun setListener(onReady, onPartial, onFinal, onError, onEnd)fun start()fun stop()fun destroy()
Location:
services/SpeechController.kt:1TextToSpeechController.kt
TextToSpeechController.kt
Controls Android’s TTS engine for accessibility.Key methods:
Location:
fun speak(text: String)fun stop()fun destroy()
QUEUE_FLUSH to prevent audio overlapLocation:
services/TextToSpeechController.kt:1UI layer
The UI layer is built entirely with Jetpack Compose and organized by feature:Navigation structure
The app uses Jetpack Navigation Compose with a router pattern for authentication-aware navigation.
AppRoutes.kt
Defines route constants:AppNavGraph.kt
Defines the navigation graph with reactive authentication state: Key features:- Reactive authentication state using
authStateFlow().collectAsState() - Automatic redirection based on login status
- Proper back stack management with
popUpTo
ui/nav/AppNavGraph.kt:1
RouterScreen.kt
Handles automatic navigation based on authentication state:Screen components
- Authentication
- Main features
- Location
LoginScreen.kt
- Email and password input fields
- Voice dictation for email/password
- Speech normalization integration
- Navigation to register/recover screens
- New account creation
- Password confirmation
- Voice input support
- Password reset email
- Firebase sendPasswordResetEmail integration
Testing structure
SpeechNormalizersTest.kt
Comprehensive test suite for speech-to-text normalization:Email normalization tests
Tests conversion of spoken email addresses including “arroba”, “punto”, and numeric spellings
Password normalization tests
Validates password input from voice with special characters and numbers
Edge cases
Tests spacing, special characters, and phonetic variations
100% coverage
Ensures all normalization paths are validated
app/src/test/java/com/demodogo/ev_sum_2/domain/validators/SpeechNormalizersTest.kt:1
Configuration files
Build configuration
Key dependencies (build.gradle.kts)
- Jetpack Compose
- Firebase
- Location & Storage
compileSdk = 36minSdk = 24targetSdk = 36- Kotlin JVM target:
11
Manifest configuration
Required permissions declared inAndroidManifest.xml:
File naming conventions
Screens
FeatureScreen.kt (e.g., LoginScreen.kt, HomeScreen.kt)Repositories
EntityRepository.kt (e.g., AuthRepository.kt, PhraseRepository.kt)Services
EntityService.kt or FeatureController.ktModels
EntityName.kt (e.g., Phrase.kt, AppUser.kt)Tests
ClassNameTest.kt (e.g., SpeechNormalizersTest.kt)Package organization principles
Layer-first organization
Top-level packages represent architectural layers (
data, domain, services, ui)Shared utilities at layer root
Common utilities live at the root of their layer (e.g.,
data/Validators.kt)Quick reference
Use this guide to quickly locate specific functionality:| Feature | Layer | File |
|---|---|---|
| User login | Data | data/repositories/AuthRepository.kt:15 |
| Login UI | UI | ui/auth/LoginScreen.kt |
| Login coordination | Services | services/AuthService.kt:11 |
| Phrase CRUD | Data | data/repositories/PhraseRepository.kt:17 |
| GPS location | Data | data/repositories/LocationRepository.kt |
| Reverse geocoding | Services | services/LocationService.kt:39 |
| Voice recognition | Services | services/SpeechController.kt:54 |
| Speech normalization | Domain | domain/validators/SpeechNormalization.kt:4 |
| Text-to-speech | Services | services/TextToSpeechController.kt:20 |
| Navigation graph | UI | ui/nav/AppNavGraph.kt:19 |
| Theme configuration | UI | ui/theme/Theme.kt |
| Firebase init | Data | data/firebase/FirebaseModule.kt |
Next steps
Architecture overview
Review the high-level architecture and design principles
Service-Repository pattern
Learn about the architectural pattern implementation