arch-atlas

Cart Controller

controllers/cart_controller.dart · Notifier<List<LocalCartItem>>

domain

Overview

Notifier owning the local cart state. Watches currentCustomerIdProvider; when the customer ID changes (login, account switch) it reloads from per-user SharedPreferences. No network calls live here — the backend cart is created later at checkout.

User Flow

  1. build() ref.watch(currentCustomerIdProvider) and on a non-null id different from _userId, triggers _loadFromStorage.
  2. _loadFromStorage reads via LocalStorageService.getLocalCartItems(userId).
  3. addToCart / updateQuantity / removeItem mutate state, then _saveToStorage persists.
  4. updateQuantity routes qty<=0 to removeItem.
  5. clearCart wipes state and clears the per-user key via LocalStorageService.clearLocalCartItems.

Cases & Edge Cases

  • If _userId is null when _saveToStorage runs, it logs and returns without writing — silent no-op when the user isn't loaded yet.
  • User switches account in-session → currentCustomerIdProvider changes → previous cart stays in memory until _loadFromStorage replaces it (brief stale window).
  • Guest mode has no customerId, so the cart is purely in-memory and is lost on app kill.

Code References

  • lib/src/features/shared/cart/controllers/cart_controller.dart:9 // CartController
  • lib/src/features/shared/cart/controllers/cart_controller.dart:15 // ref.watch(currentCustomerIdProvider)
  • lib/src/features/shared/cart/controllers/cart_controller.dart:42 // addToCart
  • lib/src/features/shared/cart/controllers/cart_controller.dart:130 // cartControllerProvider

API Calls

Empty — fill this in later. Open the manifest and add content here.

Notes

The explicit watch+_userId guard exists because Riverpod will rebuild whenever the customerId AsyncValue ticks even if the id is unchanged — without the diff check, every rebuild would re-read storage.