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

75
GUI-NOTES.md Normal file
View file

@ -0,0 +1,75 @@
# MCMS Mobile — GUI scaffold notes
The SwiftUI layer sits on top of the networking core from the kickoff brief. It's
a working skeleton you run against a live MCMS box, then refine.
## Layout
```
App/ MCMSMobileApp (@main), RootView routing, AppEnvironment
UI/ Shared components (badges, count tiles, load/error states, LoadPhase)
Features/
Settings/ Connection config + test (direct or proxy, self-signed toggle)
Login/ Email/password, Keychain prefill
Dashboard/ Device + alarm counts (VM + View)
ONUList/ Searchable ONU list (VM + View)
ONUDetail/ Stats / Config / Alarms / Logs tabs + Reset op (VM + View)
```
Flow: `RootView` shows **Settings** until a connection is configured, then
**Login**, then the main **TabView**. `AppEnvironment` owns the `MCMSConnection`,
persists the (non-secret) `APIConfiguration` to `UserDefaults`, and keeps
credentials in the Keychain.
## Putting it in Xcode
1. New iOS App (SwiftUI lifecycle), **deployment target iOS 17.0+**, built with
**Xcode 26 (iOS 26 SDK)**. The 26 SDK is required for App Store / TestFlight
submission and makes standard components adopt the Liquid Glass look on iOS 26
devices automatically — no code and no opt-out flag needed; the UI here is stock.
2. Delete the template `ContentView.swift` and the generated `App` struct — this
scaffold provides its own `@main` in `App/MCMSMobileApp.swift`.
3. Add the whole `MCMSMobile/` tree (networking core + this GUI). One module,
no external dependencies.
The view models use the `@Observable` macro and views use `@State`/`@Environment`
(iOS 17+). If you ever need to drop below iOS 17, revert those to
`ObservableObject`/`@Published` + `@StateObject`/`@EnvironmentObject` and
reinstate a `ContentUnavailableView` shim.
## App Transport Security (the gotcha)
TLS *trust* for self-signed certs is handled in code by `ServerTrustEvaluator`,
but **ATS is separate** and can still block the connection:
- **HTTPS to a self-signed host:** the trust delegate covers it; no Info.plist
change needed for cert validation itself. (Keep TLS 1.2+.)
- **Plain HTTP** (no TLS) or weak TLS: ATS blocks it by default. Add a *scoped*
exception for your host in Info.plist rather than a blanket allow:
```xml
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>10.2.10.29</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key><true/>
<key>NSIncludesSubdomains</key><false/>
</dict>
</dict>
</dict>
```
Avoid `NSAllowsArbitraryLoads`. Behind a proxy with a real cert, you need none of
this and should set the trust policy to `.system`.
## Known TODOs carried from the core
- Confirm `/api/v1` vs `/v1` and the `databases/selection` body key.
- The Mongo-document field accessors (ONU state/parent OLT, alarm severity/time,
stat counter keys) are best-effort guesses marked `// TODO` — pin them to the
real `openapi.json` and a live response. The Config tab's `JSONTreeView` shows
the full raw document, which helps you discover the true field paths quickly.
- Stats tab lists the latest sample's numeric counters; wire a chosen counter
into Swift Charts once the keys are known.