diff --git a/.cursor/rules/android/android_clean_architecture.mdc b/.cursor/rules/android/android_clean_architecture.mdc new file mode 100644 index 0000000..ed0d4e2 --- /dev/null +++ b/.cursor/rules/android/android_clean_architecture.mdc @@ -0,0 +1,13 @@ +--- +description: Enforce clean architecture principles in Android projects +globs: + - "app/src/main/java/**" +alwaysApply: true +--- +- Follow domain/data/presentation separation: domain is business logic, data is data sources, presentation is UI. +- Keep domain layer free of Android framework dependencies. +- Use UseCases (Interactors) for business rules, triggered from ViewModels or Controllers. +- Repositories should expose interfaces, not implementations. +- Avoid directly accessing data sources in presentation layer. +- Prefer dependency inversion: inject interfaces rather than concrete classes. +- Maintain simple, testable domain models. diff --git a/.cursor/rules/android/android_di_hilt_patterns.mdc b/.cursor/rules/android/android_di_hilt_patterns.mdc new file mode 100644 index 0000000..526a2f2 --- /dev/null +++ b/.cursor/rules/android/android_di_hilt_patterns.mdc @@ -0,0 +1,13 @@ +--- +description: Dependency injection patterns with Hilt +globs: + - "app/src/main/java/**" +alwaysApply: true +--- +- Annotate Application class with @HiltAndroidApp +- Use @HiltViewModel for ViewModel injection +- Provide dependencies in @Module with @InstallIn +- Inject interfaces rather than concrete implementations +- Use qualifiers when multiple implementations exist +- Avoid static singletons outside of Hilt’s graph +- Keep modules small and logically grouped diff --git a/.cursor/rules/android/android_general_rules.mdc b/.cursor/rules/android/android_general_rules.mdc new file mode 100644 index 0000000..42728f1 --- /dev/null +++ b/.cursor/rules/android/android_general_rules.mdc @@ -0,0 +1,38 @@ +--- +alwaysApply: false +--- +For every Kotlin Android code you generate or refactor: + +1. **Architecture:** + - Follow **MVVM pattern** strictly. + - Business logic must go into `ViewModel`, not in `View` (Activity/Fragment/Composable). + - Views should only observe `StateFlow`/`LiveData` from ViewModel. + +2. **Kotlin Best Practices:** + - Use `StateFlow` instead of `LiveData` unless explicitly required. + - Use Kotlin Coroutines (structured concurrency, `viewModelScope`, `SupervisorJob`). + - Prefer `val` over `var` where possible. + - Use extension functions and sealed classes when appropriate. + - No memory leaks (avoid context leaks in ViewModel). + - Use Dependency Injection (Hilt) if necessary. + +3. **Android Performance:** + - Avoid heavy work on the main thread. + - Use `Dispatchers.IO` or background coroutines for I/O, disk, and network tasks. + - Use `lazy` initialization where suitable. + - For RecyclerView/List: use `ListAdapter` + `DiffUtil`. + - Avoid unnecessary recomposition in Jetpack Compose. + - Apply LRU caching for repeated data/images if needed. + +4. **Testing:** + - Generated ViewModel and Repository code must be testable (no static singletons). + - Show sample unit test if introducing new logic. + +5. **Code Quality:** + - Minimize code duplication. + - Clear function separation (Single Responsibility Principle). + - Provide brief inline comments for complex sections. + +6. **Output Requirement:** + - Provide **full code samples** (including imports) unless specified otherwise. + - Brief explanation of key design decisions made. diff --git a/.cursor/rules/android/android_integration_testing.mdc b/.cursor/rules/android/android_integration_testing.mdc new file mode 100644 index 0000000..98b592e --- /dev/null +++ b/.cursor/rules/android/android_integration_testing.mdc @@ -0,0 +1,11 @@ +--- +description: Android Integration Testing best practices for multi-layer testing +alwaysApply: false +--- +- Integration tests should verify interactions between multiple layers (e.g., ViewModel + Repository + Data Source). +- Use **Hilt Test Components** or DI overrides to inject fake or in-memory dependencies. +- Avoid hitting real external services; use mocked network responses or test databases. +- Write integration tests to cover critical user flows end-to-end. +- Keep tests stable and repeatable; clean up any test data after execution. +- Use **JUnit Rules** or **TestContainers** where applicable for environment setup/teardown. +- Separate integration tests from unit tests and run them less frequently (e.g., nightly builds). diff --git a/.cursor/rules/android/android_naming_conventions.mdc b/.cursor/rules/android/android_naming_conventions.mdc new file mode 100644 index 0000000..293d821 --- /dev/null +++ b/.cursor/rules/android/android_naming_conventions.mdc @@ -0,0 +1,13 @@ +--- +description: Naming conventions for consistency +globs: + - "**/*.kt" +alwaysApply: true +--- +- Classes: PascalCase +- Functions: camelCase +- Constants: UPPER_SNAKE_CASE +- Variables: camelCase +- Test functions: GIVEN_ WHEN THEN +- Avoid abbreviations and cryptic names +- Name should communicate clear intent diff --git a/.cursor/rules/android/android_ui_testing.mdc b/.cursor/rules/android/android_ui_testing.mdc new file mode 100644 index 0000000..0ce9726 --- /dev/null +++ b/.cursor/rules/android/android_ui_testing.mdc @@ -0,0 +1,11 @@ +--- +description: Android UI testing best practices using Espresso and Compose Testing +alwaysApply: false +--- +- Use **Espresso** for testing classic Android Views; use **Compose Testing APIs** for Jetpack Compose UI. +- Keep UI tests focused on user interactions and visible UI changes. +- Avoid complex logic in UI tests; delegate business logic testing to unit tests. +- Use **Idling Resources** or `composeTestRule.awaitIdle()` to synchronize asynchronous events. +- Use clear, descriptive test names that reflect user behavior being tested. +- Isolate UI tests from backend dependencies by using mock servers or test doubles. +- Run UI tests on real or emulated devices to catch platform-specific issues. diff --git a/.cursor/rules/android/android_unit_testing_bdd.mdc b/.cursor/rules/android/android_unit_testing_bdd.mdc new file mode 100644 index 0000000..8831ebb --- /dev/null +++ b/.cursor/rules/android/android_unit_testing_bdd.mdc @@ -0,0 +1,24 @@ +--- +description: Unit testing best practices with BDD style +alwaysApply: false +--- +- Name test functions in BDD style: given__when__then_ +- Use GIVEN, WHEN, THEN comments in the test body for clarity. +- Write one behavioral scenario per test. +- Use mocks (MockK, Mockito) to isolate dependencies. +- Prefer runTest or coroutine test rules for suspend functions. +- Avoid fragile tests with real-time delays or random input. +- Example: +```kotlin +@Test +fun givenValidUser_whenFetchUser_thenReturnsUser() { + // GIVEN + val userId = 123 + coEvery { userRepo.getUser(userId) } returns User(userId, "Alice") + + // WHEN + val result = runBlocking { sut.fetchUser(userId) } + + // THEN + assertEquals("Alice", result.name) +} diff --git a/.cursor/rules/android/android_workmanager_best_practices.mdc b/.cursor/rules/android/android_workmanager_best_practices.mdc new file mode 100644 index 0000000..6d82dd8 --- /dev/null +++ b/.cursor/rules/android/android_workmanager_best_practices.mdc @@ -0,0 +1,11 @@ +--- +description: Best practices for WorkManager usage in background tasks +alwaysApply: false +--- +- Use `CoroutineWorker` for suspendable background work. +- Keep work inputs and outputs small and serializable. +- Chain dependent work using `WorkContinuation`. +- Use appropriate `Constraints` for battery and network considerations. +- Monitor and handle work statuses for retries and failures gracefully. +- Avoid long-running tasks; break them into smaller units if needed. +- Clean up or cancel obsolete work to prevent resource leaks. diff --git a/.cursor/rules/general_clean_code_principles.mdc b/.cursor/rules/general_clean_code_principles.mdc new file mode 100644 index 0000000..d827569 --- /dev/null +++ b/.cursor/rules/general_clean_code_principles.mdc @@ -0,0 +1,12 @@ +--- +description: Clean code principles for better readability +alwaysApply: false +--- +- Keep functions small and focused +- One class per file +- Limit function size to 20 lines if possible +- Avoid long parameter lists (max 3–4 parameters) +- Minimize nested control structures +- Remove commented-out code before committing +- Prefer meaningful names over comments +- DRY (Don’t Repeat Yourself): extract duplication diff --git a/.cursor/rules/general_performance_tips.mdc b/.cursor/rules/general_performance_tips.mdc new file mode 100644 index 0000000..ab70b18 --- /dev/null +++ b/.cursor/rules/general_performance_tips.mdc @@ -0,0 +1,11 @@ +--- +description: Performance best practices for Android +alwaysApply: false +--- +- Avoid allocating objects in tight loops +- Use lazy initialization where appropriate +- Reuse existing objects instead of recreating +- Prefer immutable data structures for concurrency +- Minimize reflection usage +- Avoid excessive recomposition in Compose by using keys and remember +- Profile and measure before optimizing prematurely diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a2921b9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[*.{kt,kts}] +indent_size = 4 +indent_style = space +max_line_length = 100 +ktlint_standard_max_line_length = 100 +ij_kotlin_allow_trailing_comma = true +ij_kotlin_allow_trailing_comma_on_call_site = true +ktlint_standard_no-wildcard-imports = disabled diff --git a/.idea/misc.xml b/.idea/misc.xml index 7062a71..088e11d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ -