# TeamsISO Phase C — WPF MVVM UI Plan

**Goal:** Operator-facing WPF UI bound to `IIsoController`. Displays the live participant list, lets operators enable/disable per-participant ISO outputs, set the global framerate / resolution / aspect / audio mode, view engine alerts, and see basic system health. Plus a WiX MSI installer and a release CI pipeline.

**Architecture:** MVVM with no third-party MVVM framework — small managed `ObservableObject` and `RelayCommand` helpers. The view models bind directly to `IIsoController`'s observables. UI runs on the WPF dispatcher; observable subscriptions marshal back via a captured `SynchronizationContext`. App.xaml.cs constructs the engine on startup and disposes on exit.

**Tech stack:** WPF on .NET 8, MVVM hand-rolled, no external UI library yet (MaterialDesignThemes can be added in a polish pass).

## File structure additions

```
src/TeamsISO.App/
├── App.xaml / App.xaml.cs              (DI bootstrap)
├── MainWindow.xaml / MainWindow.xaml.cs
├── ViewModels/
│   ├── ObservableObject.cs
│   ├── RelayCommand.cs
│   ├── MainViewModel.cs
│   ├── ParticipantViewModel.cs
│   ├── GlobalSettingsViewModel.cs
│   └── AlertBannerViewModel.cs
├── Converters/
│   ├── BoolToVisibilityConverter.cs
│   └── EnumDescriptionConverter.cs
└── TeamsISO.App.csproj

src/TeamsISO.Installer/
└── TeamsISO.Installer.wixproj          (MSI installer; v5)
```

## Tasks

1. **MVVM helpers** — `ObservableObject` base implementing `INotifyPropertyChanged`; `RelayCommand` and `AsyncRelayCommand`.
2. **GlobalSettingsViewModel** — exposes Framerate, Resolution, Aspect, Audio as bindable selected values; `Apply` command calls `controller.SetGlobalSettingsAsync`.
3. **ParticipantViewModel** — wraps a `Participant`, exposes IsEnabled, CustomOutputName, and current status; `EnableCommand` and `DisableCommand` call the controller.
4. **AlertBannerViewModel** — collects `EngineAlert`s and exposes the most recent one with a "dismiss" command.
5. **MainViewModel** — top-level. Owns the controller. Exposes `ObservableCollection<ParticipantViewModel>`, the settings VM, and the banner VM.
6. **MainWindow.xaml** — DataGrid for participants with toggle column, settings panel docked to the right, alert banner docked top.
7. **Converters** — bool→visibility, enum→display string.
8. **App.xaml.cs** — wires DI: build engine + controller + main view model, set MainWindow's DataContext, dispose on exit.
9. **WiX installer (Phase C-2)** — separate task; can ship after the UI is alive.

Each step ships as its own commit. Tag `phase-c-complete` after MainWindow renders and the controller is bound.
