feat(android-terminal): Phase A — core infrastructure

Foundation work for the Android tablet POS app. Adds the singletons that
every screen needs (config persistence, network awareness, auth) without
touching the existing screen stubs yet — Phases B–F will build on these.

- gradle: bcrypt 0.10.2 pinned (used in Phase C for offline PIN verify)
- LoyaltyApi: + GET /api/v1/store/loyalty/categories endpoint
- ApiModels: + category_ids on StampRequest / PointsEarnRequest,
  + CategoryItem / CategoryListResponse
- DeviceConfigRepository: DataStore wrapper for the paired-tablet state
  (api_url, auth_token, store_id/code/name, cached program/pins/categories
  JSON, per-seller language, resetDevice())
- AuthInterceptor: rewrites every request's host to the paired api_url
  and adds Bearer auth — Retrofit keeps a placeholder baseUrl since the
  real URL only exists post-pair
- NetworkMonitor: Flow<Boolean> isOnline from ConnectivityManager
- StaffPinRepository / CategoryRepository: cache-or-refresh pattern,
  Moshi-serialized to DataStore
- AppModule: wires AuthInterceptor before the logging interceptor
- strings.xml: ~50 strings × 4 locales (en authoritative; fr/de/lb
  translated, mirroring the loyalty backend's i18n approach)

Verified by ./gradlew assembleDebug — clean build, only pre-existing
warnings (Theme statusBarColor deprecation, Moshi-kapt deprecation).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-05 22:11:15 +02:00
parent 90b5b3d135
commit 3531ab8405
14 changed files with 695 additions and 1 deletions

View File

@@ -44,6 +44,9 @@ mlkitBarcode = "17.3.0"
# DataStore (preferences)
datastore = "1.1.2"
# bcrypt — pure-Java, used to verify staff PIN hashes locally on the tablet
bcrypt = "0.10.2"
# Testing
junit = "4.13.2"
junitAndroid = "1.2.1"
@@ -100,6 +103,9 @@ mlkit-barcode = { group = "com.google.mlkit", name = "barcode-scanning", version
# DataStore
datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" }
# bcrypt
bcrypt = { group = "at.favre.lib", name = "bcrypt", version.ref = "bcrypt" }
# Testing
junit = { group = "junit", name = "junit", version.ref = "junit" }
junit-android = { group = "androidx.test.ext", name = "junit", version.ref = "junitAndroid" }