A full-featured expense module for small business owners to quickly capture, review, and report daily spend. Built with Jetpack Compose and MVVM, with local persistence via Room.
I used Gemini (Android Studio agent) and ChatGPT-5 Thinking as pair-programmers to scaffold the
module, generate MVVM/Compose boilerplate, and iterate quickly on UI/UX. They helped diagnose build
issues (KSP, missing test deps), improved performance via targeted recomposition fixes (remember,
derivedStateOf, @Stable), and added accessibility + haptics with minimal patches. I leaned on
the agents for small, verifiable diffs (one feature per prompt), then immediately compiled and fed
back errors for precise fix-ups. They also drafted README/usage docs and produced a concise
compliance checklist against the brief.
-
Prompt: “Add a calendar icon to the expense list screen. On click, it should open a date picker that allows selection up to today.” Outcome: Implemented a
DatePickerDialoglaunched from a new calendar icon, disabling future dates and updating the ViewModel on selection. -
Prompt: “I’m getting the following error while building my project: KSP failed with exit code: PROCESSING_ERROR.” Outcome: Root-caused annotation processing issues and provided a checklist (versions, kapt/ksp setup, incremental flags), plus a minimal Gradle/config patch.
-
Prompt: “Review Entry/List/Report composables for recomposition issues; introduce
remember/derivedStateOfwhere appropriate.” Outcome: Produced a focused diff usingremember,derivedStateOf, and@Stabledata holders to reduce unnecessary recompositions. -
Prompt: “Refactor the chart to calculate its Y-axis scale automatically. Also, replace the hardcoded category colors with theme-aware ones.” Outcome: Made the line chart’s Y-axis dynamic by calculating intervals based on the data. Decoupled colors from the data model and used theme-aware colors in the UI.
-
Prompt: “Add content descriptions for actionable icons/images, error semantics for validation, and haptic feedback on successful add.” Outcome: Inserted accessibility modifiers, announced validation errors via semantics, and added light haptics on success.
-
Prompt: “Add category icons in enum.” Outcome: Extended
Categoryenum with icon refs and updated UI (List/Report) to render icons next to labels. -
Prompt: “Add Material icons.” Outcome: Verified BOM and
material-icons-extendeddependency; exposed icons for immediate use. -
Prompt: “Add unit tests for InMemoryExpenseRepository and a simple Compose UI test for EntryScreen.” Outcome: Added repository tests (success, duplicate rejection, per-day totals) and a Compose test for validation/success flow; included
kotlinx-coroutines-test. -
Prompt: “
mockis unresolved.” Outcome: Identified missing Mockito Kotlin dependency; added minimal Gradle entry and imports. -
Prompt: “Compare current code to the Zobaze brief and output a checklist with Pass/Fail per requirement.” Outcome: Generated a gap report with file/line pointers to close misses (export action, empty states, grouping behavior).
-
Prompt: “Generate README.md for the module (features, architecture, how to run, decisions/trade-offs, ‘How I used AI’).” Outcome: Produced a concise README tailored to the current codebase.
-
Prompt: “Show receipt thumbnail in today’s list item; on click open dialog with full image.” Outcome: Added a thumbnail to the list item that, when clicked, opens a dialog showing the full-sized receipt image.
Notes: Prompts were consolidated and outcomes were tightened for clarity.
- Expense Entry: Add new expenses with title, amount, category, notes, and an optional receipt image.
- Daily Expense List: View expenses for any selected day using a calendar picker.
- Daily Totals: See the total amount and count of expenses for the selected day.
- 7-Day Report: Visualize category spending trends over the last week with a line chart.
- CSV Export: Share daily and category totals via the Android share sheet.
- Dynamic Chart Scaling: The report chart's Y-axis automatically adjusts to the data.
- Theme-Aware UI: Colors adapt to the system's light or dark theme.
- Image Previews: View receipt thumbnails in the list and tap to see the full image.
- Search & Filter: Search for expenses by title or filter by category.
- Monthly Reports: View aggregated expense data on a monthly basis.
- Cloud Sync: Back up and sync expenses across multiple devices.
| Expense List | Expense Entry | Report |
|---|---|---|
![]() |
![]() |
![]() |
- Architecture: MVVM with
ViewModel+StateFlow. - UI: Jetpack Compose (Material 3), Navigation-Compose.
- Data: Room database as single source of truth; repository abstraction.
- Time/Money:
java.time(Instant/LocalDate); amounts stored in paise/cents (Long) for accuracy. - Charts: Compose
Canvas(no external chart libs). - Export: CSV string → Android share intent.
app/
ui/
entry/ # EntryScreen, EntryViewModel
list/ # ExpenseListScreen, ExpenseListViewModel
report/ # ReportScreen, ReportViewModel
components/ # Reusable UI bits (dropdowns, dialogs, chart etc.)
navigation/ # NavGraph
theme/ # Material theme
main/ # Main screen, Wrapper screen
domain/
model/ # Expense, Category
repo/ # ExpenseRepository, implementations
data/
local/ # Entities, DAO, Database
mock/ # Mock data creation
util/ # Formatting, CSV builder, share helpers
tests/ # Unit + UI tests
- Bottom Nav: List (Today by Default) Report
- FAB: Add → Entry (bottom sheet form)
- Update Expense: Full screen update expense form
- Back: Entry → List; Report → List
- Open in Android Studio (latest stable).
- Use AGP 8+, Kotlin 2.x, JDK 17 recommended.
- Sync Gradle, then Run on device/emulator (minSdk 30, compileSdk 36).
If you must stay on Java 11, ensure Gradle toolchain and
jvmTargetare aligned across Kotlin/Java.
- Room vs In-Memory: Chose Room to satisfy persistence and mirror real usage.
- Date UX: A calendar picker allows for quick navigation to any date, providing more flexibility than simple next/previous day buttons.
- Charts: Kept to Canvas for zero dependencies and full control.
- Money type: Paise/Cents (Long) to avoid floating point rounding issues.


