4.9 KiB
4.9 KiB
Handoff — PON Go Android
Context for the next session/developer. Pairs with README.md and
docs/MCMS_API.md.
Architecture
core/— pure Kotlin, no Android UI deps. Mirrors the iOS networking core.- JSON: MCMS docs are heterogeneous Mongo documents, so we keep raw
kotlinx.serializationJsonElementtrees and read fields via the accessors inJson.kt(el["key"],.string/.int/.double/.array/.obj) — the analogue of the iOSJSONValue. Models (Models.kt) are thin wrappers over aJsonElementwith computed properties. ApiClient(OkHttp): builds versioned requests, injectsReferer+X-CSRFToken(writes), unwraps the{status,data}envelope, maps status codes toApiError, paginates via thenextcursor.Call.await()bridges OkHttp to coroutines with cancellation.- Repositories return model wrappers;
McmsConnectionwires it all; auth/cookies inNetworking.kt(SessionCookieJar+SessionStore), TLS policy inServerTrust, secrets inKeychainStore(EncryptedSharedPreferences).
- JSON: MCMS docs are heterogeneous Mongo documents, so we keep raw
ui/— Jetpack Compose. Navigation is state-based inMainActivity(aList<Screen>back stack +BackHandler), not Navigation-Compose — so detail screens and the dashboard drill-downs can take in-memory objects directly. Each screen has a plain state-holder class (…Model) exposingmutableStateOffields +suspend load()/refresh()— the analogue of the iOS@Observableview models. No androidxViewModel/DI.
Build / verify loop (this matters)
The dev machine had no kotlinc/gradle on PATH, but Android Studio provides
everything. Two loops:
- Full build (authoritative):
Needsexport JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" ./gradlew :app:assembleDebug --no-daemon --console=plainlocal.properties(sdk.dir=…, git-ignored). First run downloads deps to~/.gradle; afterwards it's ~20–60 s. This is what proves the whole app (UI + resources + manifest + icons) compiles. - Quick core-only check (no Gradle), when iterating on
core/: the bundled compiler at…/Android Studio.app/Contents/plugins/Kotlin/kotlinc/bin/kotlincwith-Xplugin=…/kotlinc/lib/kotlinx-serialization-compiler-plugin.jarand a classpath of Maven jars (kotlinx-serialization-json/core, okhttp, okio-jvm, kotlinx-coroutines-core-jvm). Compiles everycore/*.ktexceptKeychainStore.kt(androidx). Faster than a Gradle round-trip.
API gotchas (all handled in code — don't regress)
- Single-encode URLs. Ids stay RAW in
McmsEndpoint;ApiClientencodes the path once viaHttpUrl.addPathSegments. Pre-encoding double-encoded MAC colons (:→%3A→%253A) → MCMS "invalid id". - 401 bounces to login; 403 does NOT (permission/CSRF —
requiresReauthenticationis 401-only). - Writes return
{"status":"success"}with nodata— the unwrap tolerates it. - ONU registration lives on OLT-STATE buckets (
OltRepository.registrationMap), not ONU-STATE. Friendly names areONU.Name/OLT.Name(NOTNETCONF.Name). - CPE DHCP comes from the web helper
GET /api/cpe/onu/<id>/— a versionless, bare[code, cpe…]array (useApiClient.getRaw). - Firmware = Procedure 7: GET ONU-CFG → write filename/version into the
inactive bank → full-doc PUT (
FirmwareUpgrade.apply). Inactive-bank only, so service stays up until the ONU reboots. Still worth testing on a spare ONU. - Field paths were confirmed against live JSON; see
docs/MCMS_API.mdand the model accessors.
Trimmed vs iOS (intentional, easy to restore)
- ONU detail tabs are Overview / CPE / Logs / Config — no separate Alarms tab.
Current alarms live on ONU-STATE
"Alarm"buckets if you want to add it. - Config shows pretty-printed JSON text, not the collapsible tree the iOS app has.
- Dashboard ONU-state rows aren't tappable (the Health rows are). The iOS app drills ONU-state → filtered ONU list.
- Toggles use
rememberSaveable(survive rotation, not process death). Persist in prefs if you want parity with iOS@AppStorage. - Self-signed/cleartext: the TLS trust policy is in
ServerTrust. Plain-HTTP hosts also need ausesCleartextTraffic/network-security-config exception (Android's ATS analogue) — add when needed.
Repo split
This folder is self-contained (has its own docs/MCMS_API.md). To make it a git
repo: git init here; the included .gitignore already excludes build/,
.gradle/, local.properties, .idea/. Commit the Gradle wrapper
(gradlew, gradle/wrapper/*). The full dev-guide PDFs (323-1961-30x) live in
the iOS repo if you ever need the deep source.
Possible next steps
Restore the trimmed items above; add OLT firmware (Procedure 8 bulk task); per-ONU live-alarms view; charts for PM history; pull-to-refresh on lists; dark-theme polish; a proper app theme from the brand colours.