Skip to content

dev-personal-projects/devops-ai-agent-android

Repository files navigation

devops-ai-agent-android

🛠️ Tech Stack

  • Language: Kotlin
  • Architecture: MVVM Architecture
  • UI: Jetpack Compose
  • Dependency Injection: Hilt
  • Networking: Retrofit, OkHttp

Configure keys.properties

Create a file named keys.properties in the root directory with the following content:

# Backend API URL
BACKEND_URL=https://your-backend-url.com

Explanation of Properties

  • BACKEND_URL: The base URL for the backend API

Ensure the File is Ignored in Version Control

To prevent accidental commits of sensitive information, make sure keys.properties is included in the .gitignore file:

keys.properties

How the File is Used in build.gradle.kts

The properties are loaded in the build script and used to configure the backend URL and signing configuration:

import java.util.Properties

val keysFile = rootProject.file("keys.properties")
val keysProps = Properties()
if (keysFile.exists()) {
    keysFile.inputStream().use { keysProps.load(it) }
}

// Provide a fallback if the property is missing
val backendUrlFromKeys: String = keysProps.getProperty("BACKEND_URL")
    ?: throw GradleException("BACKEND_URL not found in keys.properties")


android {
    // others code

        // Expose BACKEND_URL to BuildConfig
        buildConfigField("String", "BACKEND_URL", "\"$backendUrlFromKeys\"")
    }

 buildFeatures {
        compose = true
        buildConfig = true
    }

]


# DevOps Android App - Clean Architecture Folder Structure

app/src/main/java/com/example/devops/ │ ├── application/ │ └── DevOpsApp.kt # Application class with Hilt │ ├── di/ # Dependency Injection │ ├── NetworkModule.kt # Network dependencies (Retrofit, OkHttp) │ ├── AuthModule.kt # Authentication dependencies │ └── DatabaseModule.kt # Database dependencies (if needed) │ ├── core/ # Core/Shared utilities │ ├── network/ │ │ ├── NetworkResult.kt # Network response wrapper │ │ ├── ApiResponse.kt # Standard API response format │ │ └── NetworkConstants.kt # Network constants │ ├── security/ │ │ ├── TokenAuthenticator.kt # Automatic token refresh │ │ └── AuthInterceptor.kt # Auth header interceptor │ ├── utils/ │ │ ├── Constants.kt # App-wide constants │ │ ├── Extensions.kt # Kotlin extensions │ │ └── DateUtils.kt # Date utilities │ └── exceptions/ │ ├── AuthException.kt # Custom auth exceptions │ └── NetworkException.kt # Custom network exceptions │ ├── ui/ # UI Layer │ ├── theme/ │ │ ├── Color.kt # App colors │ │ ├── Theme.kt # Material 3 theme │ │ ├── Type.kt # Typography │ │ └── Shape.kt # Custom shapes │ │ │ ├── components/ # Reusable UI components │ │ ├── buttons/ │ │ │ ├── PrimaryButton.kt │ │ │ ├── SecondaryButton.kt │ │ │ └── GitHubButton.kt │ │ ├── cards/ │ │ │ ├── ErrorCard.kt │ │ │ ├── InfoCard.kt │ │ │ └── WelcomeCard.kt │ │ ├── dialogs/ │ │ │ ├── LoadingDialog.kt │ │ │ └── ConfirmationDialog.kt │ │ └── indicators/ │ │ ├── LoadingIndicator.kt │ │ └── EmptyStateIndicator.kt │ │ │ └── features/ # Feature-specific UI │ ├── auth/ # Authentication Feature │ │ ├── domain/ # Domain Layer (Business Logic) │ │ │ ├── model/ │ │ │ │ ├── User.kt # User entity │ │ │ │ ├── AuthTokens.kt # Token model │ │ │ │ ├── AuthState.kt # Authentication state │ │ │ │ └── AuthResult.kt # Result wrapper │ │ │ ├── repository/ │ │ │ │ └── AuthRepository.kt # Repository interface │ │ │ └── usecase/ │ │ │ ├── AuthenticateWithGitHubUseCase.kt │ │ │ ├── HandleOAuthCallbackUseCase.kt │ │ │ ├── GetCurrentUserUseCase.kt │ │ │ ├── LogoutUseCase.kt │ │ │ └── ObserveAuthStateUseCase.kt │ │ │ │ │ ├── data/ # Data Layer │ │ │ ├── remote/ │ │ │ │ ├── api/ │ │ │ │ │ └── GitHubAuthApi.kt # API interface │ │ │ │ └── dto/ │ │ │ │ ├── OAuthInitiationResponse.kt │ │ │ │ ├── OAuthCallbackDto.kt │ │ │ │ ├── AuthResponseDto.kt │ │ │ │ ├── UserDto.kt │ │ │ │ └── RefreshTokenDto.kt │ │ │ ├── local/ │ │ │ │ ├── LocalAuthDataSource.kt # Interface │ │ │ │ ├── EncryptedAuthStorage.kt # Implementation │ │ │ │ └── model/ │ │ │ │ ├── UserStorageModel.kt │ │ │ │ └── AuthTokensStorageModel.kt │ │ │ ├── mapper/ │ │ │ │ ├── AuthMapper.kt # Data <-> Domain mapping │ │ │ │ └── UserMapper.kt # User mapping │ │ │ └── repository/ │ │ │ └── AuthRepositoryImpl.kt # Repository implementation │ │ │ │ │ └── presentation/ # Presentation Layer │ │ ├── activity/ │ │ │ └── OAuthCallbackActivity.kt │ │ ├── screen/ │ │ │ └── LoginScreen.kt # Main login screen │ │ ├── components/ │ │ │ ├── AuthenticationSection.kt │ │ │ ├── GitHubLoginButton.kt │ │ │ ├── LogoSection.kt │ │ │ ├── WelcomeSection.kt │ │ │ ├── ErrorMessage.kt │ │ │ ├── LoadingIndicator.kt │ │ │ └── SecurityFooter.kt │ │ ├── state/ │ │ │ ├── AuthUiState.kt # UI state models │ │ │ └── LoginScreenState.kt # Screen-specific state │ │ ├── event/ │ │ │ └── AuthEvent.kt # UI events │ │ ├── viewmodel/ │ │ │ └── AuthViewModel.kt # ViewModel │ │ └── oauth/ │ │ └── GitHubOAuthManager.kt # OAuth flow manager │ │ │ ├── home/ # Home Feature │ │ ├── domain/ │ │ │ ├── model/ │ │ │ │ └── HomeData.kt │ │ │ ├── repository/ │ │ │ │ └── HomeRepository.kt │ │ │ └── usecase/ │ │ │ └── GetHomeDataUseCase.kt │ │ ├── data/ │ │ │ ├── remote/ │ │ │ │ └── api/ │ │ │ │ └── HomeApi.kt │ │ │ └── repository/ │ │ │ └── HomeRepositoryImpl.kt │ │ └── presentation/ │ │ ├── screen/ │ │ │ └── HomeScreen.kt │ │ ├── components/ │ │ │ ├── UserProfileCard.kt │ │ │ └── QuickActionsCard.kt │ │ ├── state/ │ │ │ └── HomeUiState.kt │ │ └── viewmodel/ │ │ └── HomeViewModel.kt │ │ │ ├── onboarding/ # Onboarding Feature │ │ ├── data/ │ │ │ ├── model/ │ │ │ │ └── OnboardingPage.kt │ │ │ └── state/ │ │ │ └── OnboardingUiState.kt │ │ ├── presentation/ │ │ │ ├── screen/ │ │ │ │ └── OnboardingScreen.kt │ │ │ ├── components/ │ │ │ │ ├── OnboardingPageContent.kt │ │ │ │ ├── PageIndicators.kt │ │ │ │ ├── NavigationButtons.kt │ │ │ │ └── AnimatedBackground.kt │ │ │ └── viewmodel/ │ │ │ └── OnboardingViewModel.kt │ │ └── storage/ │ │ └── OnboardingPreferencesManager.kt │ │ │ └── profile/ # Future Profile Feature │ ├── domain/ │ ├── data/ │ └── presentation/ │ ├── navigation/ # Navigation │ ├── NavigationGraph.kt # Main navigation setup │ ├── Routes.kt # Navigation routes │ └── NavigationViewModel.kt # Navigation state management │ └── MainActivity.kt # Main Activity


## Key Files Description by Layer

### 1. Domain Layer (Pure Kotlin - No Android Dependencies)
**Purpose**: Contains business logic and entities

- **Models**: Pure data classes representing business entities
- **Repository Interfaces**: Contracts for data operations
- **Use Cases**: Single-purpose business logic operations

### 2. Data Layer (External Concerns)
**Purpose**: Handles data sources and external APIs

- **Remote**: API interfaces and DTOs for network calls
- **Local**: Database/SharedPreferences and local models
- **Mappers**: Convert between data and domain models
- **Repository Implementations**: Concrete implementations of domain contracts

### 3. Presentation Layer (UI)
**Purpose**: Handles UI logic and user interactions

- **Screens**: Composable screens
- **Components**: Reusable UI components
- **ViewModels**: UI state management and business logic coordination
- **States**: UI state data classes
- **Events**: User interaction events

## File Naming Conventions

### 1. Domain Layer

User.kt # Entity models (PascalCase) AuthRepository.kt # Interface name + Repository GetUserUseCase.kt # Action + UseCase suffix AuthResult.kt # Concept + Result/State


### 2. Data Layer

GitHubAuthApi.kt # Service + Api suffix UserDto.kt # Model + Dto suffix UserStorageModel.kt # Model + StorageModel suffix AuthRepositoryImpl.kt # Interface + Impl suffix UserMapper.kt # Entity + M

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •