f0f8dfb68b
Four broken VMs refactored to derive read-state from IDataManager, three gaps closed: 1. TaskViewModel: tasksState / tasksByResidenceState / taskCompletionsState now derived via .map + .stateIn / combine. isLoading / loadError separated. 2. ResidenceViewModel: residencesState / myResidencesState / summaryState / residenceTasksState / residenceContractorsState all derived. 8 mutation states retained as independent (legit one-shot feedback). 3. ContractorViewModel: contractorsState / contractorDetailState derived. 4 mutation states retained. 4. DocumentViewModel: documentsState / documentDetailState derived. 6 mutation states retained. 5. AuthViewModel: currentUserState now derived from dataManager.currentUser. 10 other states stay independent (one-shot mutation feedback by design). 6. LookupsViewModel: accepts IDataManager ctor param for test injection consistency. Direct-exposure pattern preserved. Legacy ApiResult-wrapped states now derived from DataManager instead of manual _xxxState.value =. 7. NotificationPreferencesViewModel: preferencesState derived from new IDataManager.notificationPreferences. APILayer writes through on both getNotificationPreferences and updateNotificationPreferences. IDataManager also grew notificationPreferences: StateFlow<NotificationPreference?>. DataManager, InMemoryDataManager updated. No screen edits needed — screens consume viewModel.xxxState the same way; the source just switched. Architecture enforcement test comes in P3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>