initial commit
This commit is contained in:
commit
ca3d7d05e0
56 changed files with 3875 additions and 0 deletions
92
HANDOFF.md
Normal file
92
HANDOFF.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# Handoff — PON Go Android
|
||||
|
||||
Context for the next session/developer. Pairs with [`README.md`](README.md) and
|
||||
[`docs/MCMS_API.md`](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.serialization` `JsonElement` trees and read fields via the accessors
|
||||
in `Json.kt` (`el["key"]`, `.string/.int/.double/.array/.obj`) — the analogue
|
||||
of the iOS `JSONValue`. Models (`Models.kt`) are thin wrappers over a
|
||||
`JsonElement` with computed properties.
|
||||
- `ApiClient` (OkHttp): builds versioned requests, injects `Referer` +
|
||||
`X-CSRFToken` (writes), unwraps the `{status,data}` envelope, maps status
|
||||
codes to `ApiError`, paginates via the `next` cursor. `Call.await()` bridges
|
||||
OkHttp to coroutines with cancellation.
|
||||
- Repositories return model wrappers; `McmsConnection` wires it all; auth/cookies
|
||||
in `Networking.kt` (`SessionCookieJar` + `SessionStore`), TLS policy in
|
||||
`ServerTrust`, secrets in `KeychainStore` (EncryptedSharedPreferences).
|
||||
- **`ui/`** — Jetpack Compose. Navigation is **state-based** in `MainActivity`
|
||||
(a `List<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`) exposing
|
||||
`mutableStateOf` fields + `suspend load()/refresh()` — the analogue of the iOS
|
||||
`@Observable` view models. No androidx `ViewModel`/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):**
|
||||
```
|
||||
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
|
||||
./gradlew :app:assembleDebug --no-daemon --console=plain
|
||||
```
|
||||
Needs `local.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/kotlinc`
|
||||
with `-Xplugin=…/kotlinc/lib/kotlinx-serialization-compiler-plugin.jar` and a
|
||||
classpath of Maven jars (kotlinx-serialization-json/core, okhttp, okio-jvm,
|
||||
kotlinx-coroutines-core-jvm). Compiles every `core/*.kt` except
|
||||
`KeychainStore.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`; `ApiClient` encodes the
|
||||
path once via `HttpUrl.addPathSegments`. Pre-encoding double-encoded MAC colons
|
||||
(`:` → `%3A` → `%253A`) → MCMS "invalid id".
|
||||
- **401 bounces to login; 403 does NOT** (permission/CSRF — `requiresReauthentication`
|
||||
is 401-only).
|
||||
- **Writes return `{"status":"success"}` with no `data`** — the unwrap tolerates it.
|
||||
- **ONU registration lives on OLT-STATE buckets** (`OltRepository.registrationMap`),
|
||||
not ONU-STATE. Friendly names are `ONU.Name` / `OLT.Name` (NOT `NETCONF.Name`).
|
||||
- **CPE DHCP** comes from the web helper `GET /api/cpe/onu/<id>/` — a versionless,
|
||||
bare `[code, cpe…]` array (use `ApiClient.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.md` and 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 a `usesCleartextTraffic`/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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue