Theory
What you built — the Pica architecture spine
Congratulations — you've built a complete, production-like app. Before assembling everything, look at what you made. Pica isn't a random pile of screens — it's a layered architecture, where each lesson added one layer:
┌─────────────────────────────────────────────┐
│ UI (Compose) MenuScreen, CartScreen, │ ← 2, 3, 4
│ LoginScreen, ScanScreen │
├─────────────────────────────────────────────┤
│ Presentation ViewModel + Event + │ ← 3 (MVI)
│ (MVI) UiState (StateFlow) │
├─────────────────────────────────────────────┤
│ Domain MenuItem, CartItem, │
│ Order │
├─────────────────────────────────────────────┤
│ Data (repository) MenuRepository, │ ← 5, 7, 8a, 9
│ AuthRepository, Order... │
├──────────────┬──────────────┬────────────────┤
│ Network │ Cache │ Auth │
│ Retrofit(5) │ Room(7) │ Token(8a) │
│ Interceptor │ │ Stripe(11) │
│ (9) │ │ QR(10) │
└──────────────┴──────────────┴────────────────┘
Tied together by: Koin DI (6)
Each lesson → one layer or capability:
| Lesson | What it added |
|---|---|
| 1–2 | Compose UI, a static menu |
| 3 | MVI state (the cart) |
| 4 | Navigation (Nav3) |
| 5 | Retrofit — menu from the server |
| 6 | Koin DI — tidies the wiring |
| 7 | Room cache — menu offline |
| 8a | Authentication — session token |
| 9 | Authenticated requests — orders |
| 10 | QR — table context |
| 11 | Stripe — payment |
| 12 | Release — signing, R8 |
The key is the directions: UI depends on presentation, presentation on data, data on network/cache. Never the reverse. That's why you can swap Retrofit for another client, or Room for another cache, and the UI never finds out. That's what "good architecture" is — not about beauty, but about being resilient to change.