Refactor complex Android/KMP state management code to use FlowRedux state machine pattern...
For concrete examples and code samples, see examples.md.
When a developer provides Android/KMP code with complex state management, follow these steps:
1.1 UI Inventory - Map All Interactive Elements Before any refactoring, create a complete inventory:
Output: A checklist of ALL user actions this screen supports.
1.2 Data Flow Mapping
1.3 State Transition Graph Create a comprehensive state diagram showing:
Output: A complete state machine diagram or table.
2.1 Design Test Cases First Before writing ANY implementation code:
2.2 Test Case Format
@Test
fun `when [action] in [current state], should transition to [expected state]`() {
// Given: initial state
// When: action occurs
// Then: verify new state
}
2.3 Leverage MVI Observability Use the state machine's deterministic nature:
Output: Complete test suite BEFORE implementation.
3.1 Define Components Based on Analysis
3.2 Implement State Transitions
3.3 Verify Against Tests
4.1 Test-Driven Bug Finding When bugs are discovered:
4.2 Missing Functionality Detection Use test coverage to find:
5.1 Generate Complete Implementation
5.2 Provide Traceability
See examples.md for detailed code examples including:
Before writing any code:
## Feature Checklist
- [ ] Load videos button
- [ ] Pull to refresh
- [ ] Delete video (with swipe)
- [ ] Undo delete
- [ ] Play video
- [ ] Sort options (date, title)
- [ ] Filter (watched/unwatched)
- [ ] Empty state
- [ ] Error retry
- [ ] Offline mode indicator
Why: Ensures no functionality is missed in refactoring.
Create before implementation:
| Current State | Action | Next State | Side Effect |
|---------------|----------------|-----------------|-------------------|
| Initial | Load | Loading | Fetch from API |
| Loading | Success | Content | None |
| Loading | Error | Error | None |
| Content | Refresh | Refreshing | Fetch from API |
| Content | Delete(id) | Content | Delete from DB |
| Content | Sort(type) | Content | Resort locally |
Why: Makes state machine design explicit and reviewable.
Write tests before implementation:
class WatchLaterStateMachineTest {
@Test
fun `given Initial, when Load action, should transition to Loading`() {
val machine = createStateMachine()
machine.dispatchAction(Action.Load)
assertEquals(State.Loading, machine.state.value)
}
@Test
fun `given Loading, when data arrives, should transition to Content`() {
// Test the actual behavior
}
@Test
fun `given Content with items, when Delete action, should remove item optimistically`() {
// Test optimistic update
}
@Test
fun `given two simultaneous Delete actions, should handle race condition`() {
// Test edge cases
}
}
Why: Tests document expected behavior and catch regressions.
When reviewing implementation:
// Run test coverage report
// Missing coverage = missing functionality
@Test
fun `when offline and user triggers refresh, should show offline message`() {
// This test fails? → Feature is missing!
}
@Test
fun `when deleting last item, should show empty state`() {
// This test fails? → Edge case not handled!
}
Why: Test-driven approach reveals gaps in requirements.
See examples.md for detailed pattern implementations.
See examples.md for detailed pattern implementations.
See examples.md for detailed pattern implementations.
For each refactoring request, provide:
Feature Analysis:
Data Flow Diagram:
State Machine Design:
Test Suite (MUST PROVIDE BEFORE IMPLEMENTATION):
Implementation Code:
Integration Guide:
Test Execution Plan:
1. Analyze → List ALL features and interactions
↓
2. Design → Create state transition graph
↓
3. Test → Write test cases for EVERYTHING
↓
4. Verify → Check test coverage matches feature list
↓
5. Implement → Write state machine to pass tests
↓
6. Debug → Use failing tests to find/fix bugs
↓
7. Deliver → Provide complete, tested code
Always prefer clarity and completeness over brevity. Include proper error handling and coroutine scope management. Emphasize the test-driven approach and use of MVI's observability for quality assurance.