initial commit

This commit is contained in:
Jon Vanvik 2026-05-31 14:11:29 +02:00
commit 8de962eeb8
44 changed files with 4843 additions and 0 deletions

77
HANDOFF.md Normal file
View file

@ -0,0 +1,77 @@
# Handoff — PON Go iOS
Context for the next session/developer. Pairs with [`README.md`](README.md) and
[`MCMS_API.md`](MCMS_API.md).
## Status
Feature-complete and (per off-device typecheck + the user's Xcode builds)
compiling. Screens: Login, Settings, Dashboard (counts, total OLT traffic,
Health with tappable drill-downs, ONU-state breakdown, detailed-stats +
auto-refresh toggles), ONU list + detail (Overview with status/firmware+update/
optical-FEC/UNI/traffic, CPE DHCP, Config raw-JSON tree, Alarms, Logs; reset +
firmware behind hardened confirms), OLT list + detail (status/uptime/traffic/
environment/uplink/registration buckets, reset).
## Architecture
- `AppEnvironment` (`@MainActor @Observable`) owns the active `MCMSConnection`,
persists the non-secret `APIConfiguration` to UserDefaults, keeps credentials in
the Keychain, and routes `RootView` (Settings → Login → main `TabView`).
- Networking core: `APIConfiguration``SessionStore`/`APIClient` → repositories.
Mongo documents are kept as a dynamic `JSONValue` (`APIEnvelope.swift`) and read
via typed accessors on `MongoDocument` structs (`DeviceModels.swift`) — type the
fields you use, leave the rest raw.
- View models are `@MainActor @Observable` classes with a `LoadPhase` + `load()`.
## API gotchas (handled in code — don't regress)
- **Single-encode URLs.** `APIClient.makeRequest` builds the path with
`URLComponents.path` (encodes once, keeps `:` in MAC ids raw); `MCMSEndpoint`
keeps ids RAW. `appendingPathComponent` double-encoded MAC colons → MCMS
"invalid id". (Verified empirically.)
- **401 bounces to login; 403 does NOT**`APIError.requiresReauthentication` is
401-only (403 is permission/CSRF; re-login won't help). The `onAuthExpired` hook
flows `APIClient → MCMSConnection → AppEnvironment`.
- **Writes return `{"status":"success"}` with no `data`**`decodeEnvelope`
returns the type's empty value instead of throwing (so login + all writes work).
- **ONU registration is on OLT-STATE buckets** (`OLTRepository.registrationMap`),
not ONU-STATE. Parent OLT is `OLT.MAC Address`. Friendly names are `ONU.Name` /
`OLT.Name` (NOT `Netconf.Name`/`NETCONF.Name`, which default to the id), fetched
via `projection`.
- **CPE DHCP** = web helper `GET /api/cpe/onu/<id>/` (versionless, bare
`[code, cpe…]` array — `APIClient.getRaw`).
- **Firmware** = Procedure 7 (`FirmwareUpgrade.apply`, unit-tested against a real
config): GET ONU-CFG → write filename/version into the **inactive** bank → full-
doc PUT. Inactive-bank only; still test on a spare ONU before production.
- **Timestamps** are UTC `yyyy-MM-dd HH:mm:ss[.SSSSSS]` with a literal space
(`MongoTimestamp`, not ISO8601). Uptime = state `Time` `Online Time`.
- Everything is `/api/v1` except `/v3/tasks/configs/` (unused). Cookies may be
`__Host-`-prefixed (`SessionStore` matches either). `/api` is auto-appended to
the base URL in Settings.
## Known real-world notes
- One lab box (`mcms.lab.svorka.net`) once sent an illegal `Upgrade: h2` header
over HTTP/2 that iOS rejects (`-1005`). Fix is server-side (Apache `Protocols
http/1.1`) or an HTTP/1.1 reverse proxy; iOS has no supported "force HTTP/1.1".
- The base URL must include `/api`; Settings normalises this.
## Verify loop
`swiftc -typecheck` against the macOS SDK for the core + view models (see README).
Tricky SwiftUI bits: compile isolated snippets sans iOS-only modifiers. No iOS SDK
on the dev machine, so full builds are the user's Xcode step.
## Repo split
Recommended: consolidate the flat sources + `Assets.xcassets` into the Xcode
project and git-init that as the iOS repo (with `docs/MCMS_API.md` + the PDFs).
The included `.gitignore` covers Xcode/Swift build artifacts. The Android app is a
separate repo (`../mcms_android`), self-contained.
## Possible next steps
OLT bulk firmware (Procedure 8 task); Swift Charts for PM history; live optical on
the list rows; richer alarm handling; widen test coverage of the firmware PUT
against more ONU-CFG shapes.