PONGo_ios/HANDOFF.md
Jon Vanvik 4cd259b9db Add next-session note: verify the un-compiled TLS-removal merge on the Mac
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 17:24:39 +02:00

96 lines
5.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Handoff — PON Go iOS
Context for the next session/developer. Pairs with [`README.md`](README.md) and
[`MCMS_API.md`](MCMS_API.md).
## Last session (2026-05-31)
Landed on `main`: a multi-agent code-review pass (correctness / concurrency /
security / cleanup — see [`CHANGELOG.md`](CHANGELOG.md)), then removal of the
self-signed TLS option (system trust only, parity with the Android client).
> ⚠️ **Verify on the next Mac build.** The code-review fixes were confirmed
> building on the Mac, but the **self-signed-TLS removal was merged to `main`
> un-compiled** — the Linux dev box that made the change has no Swift toolchain.
> First thing next session: build `main` and confirm it compiles. It's a small
> change (removed `ServerTrustPolicy.allowSelfSignedForHost` + the Settings
> toggle; the trust `switch` stays exhaustive), so it should be clean.
TLS consequence: **system trust only** now — a self-signed appliance (the lab box
`mcms.lab.svorka.net`) is unreachable until its CA is installed on the device
(MDM/configuration profile), or it gets a CA-trusted cert. `CHANGELOG.md` is
written to port these changes to the Android side. Merged branches
`code-review-fixes` and `remove-self-signed-tls` can be deleted.
## 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.