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.