chore: update dependencies and remove unused files

- Replaced `flutter_highlight` with `gpt_markdown` in `pubspec.yaml`.
- Updated `pubspec.lock` to reflect new dependencies and removed obsolete ones.
- Deleted outdated Riverpod migration documentation files to streamline the project.
- Added new configurations for GptMarkdown styling in `markdown_config.dart` and updated the streaming markdown widget implementation.
This commit is contained in:
cogwheel0
2025-09-30 16:02:34 +05:30
parent ff6d33abdf
commit 12a6a07043
16 changed files with 149 additions and 5792 deletions

View File

@@ -1,702 +0,0 @@
# Riverpod 3.0 Alignment Analysis
## Executive Summary
The Conduit codebase is **well-aligned** with Riverpod 3.0 best practices. The project has already migrated to the new API and is using code generation in key areas. However, there are opportunities for improvement to achieve **full consistency** and leverage all Riverpod 3.0 features.
**Overall Grade: B+ (85/100)**
**Strengths:**
- Already using Riverpod 3.0 packages
- No legacy providers (`StateProvider`, `StateNotifierProvider`, `ChangeNotifierProvider`)
- Using `@Riverpod` annotation with code generation for complex providers
- Proper use of `Notifier` and `AsyncNotifier` classes
- Good use of `ref.mounted` checks in async operations
- Proper `keepAlive` management for singleton providers
⚠️ **Areas for Improvement:**
- Mixed approach (code generation vs manual providers)
- Missing `riverpod_lint` for enhanced static analysis
- Some providers could benefit from code generation
- Inconsistent provider organization
---
## Current State Analysis
### 1. Package Dependencies ✅
```yaml
dependencies:
flutter_riverpod: ^3.0.0 # ✅ Correct
riverpod_annotation: ^3.0.0 # ✅ Correct
dev_dependencies:
riverpod_generator: ^3.0.0 # ✅ Correct
riverpod_lint: NOT PRESENT # ⚠️ Missing
```
### 2. Provider Patterns
#### ✅ **Good: Code Generation Pattern**
Found in: `lib/core/auth/auth_state_manager.dart`, `lib/core/providers/app_providers.dart`
```dart
@Riverpod(keepAlive: true)
class AuthStateManager extends _$AuthStateManager {
@override
Future<AuthState> build() async {
await _initialize();
return _current;
}
// ... methods
}
```
**Benefits:**
- Type-safe
- Automatic provider generation
- Better refactoring support
- Family and autoDispose modifiers handled automatically
#### ⚠️ **Mixed: Manual NotifierProvider Pattern**
Found in: `lib/core/providers/app_providers.dart`, `lib/features/chat/providers/chat_providers.dart`
```dart
// Manual declaration
final themeModeProvider = NotifierProvider<ThemeModeNotifier, ThemeMode>(
ThemeModeNotifier.new,
);
class ThemeModeNotifier extends Notifier<ThemeMode> {
late final OptimizedStorageService _storage;
@override
ThemeMode build() {
_storage = ref.watch(optimizedStorageServiceProvider);
final storedMode = _storage.getThemeMode();
// ...
return ThemeMode.system;
}
void setTheme(ThemeMode mode) {
state = mode;
_storage.setThemeMode(mode.toString());
}
}
```
**Issues:**
- Inconsistent with code generation approach
- More boilerplate
- Harder to add modifiers (family, autoDispose) later
### 3. Ref.mounted Usage ✅
**Good usage found in multiple files:**
```dart
// lib/core/providers/app_providers.dart
if (!ref.mounted) return;
// lib/core/services/settings_service.dart
if (!ref.mounted) {
return;
}
```
**Recommendation:** Continue this pattern and apply it more broadly.
### 4. Analysis Options ⚠️
Current `analysis_options.yaml` is missing Riverpod-specific lints:
```yaml
include: package:flutter_lints/flutter.yaml
linter:
rules:
avoid_print: true
```
**Missing:**
- `riverpod_lint` custom lints
- Provider-specific rules
---
## Detailed Recommendations
### 🔴 **Priority 1: Add riverpod_lint**
**Impact:** High | **Effort:** Low | **Risk:** None
Add the `riverpod_lint` package to catch common Riverpod mistakes at compile time.
#### Changes Required:
**1. Update `pubspec.yaml`:**
```yaml
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^6.0.0
build_runner: ^2.7.1
freezed: ^3.2.0
json_serializable: ^6.11.1
flutter_native_splash: ^2.4.6
riverpod_generator: ^3.0.0
riverpod_lint: ^3.0.0 # ADD THIS
custom_lint: ^0.8.0 # REQUIRED FOR riverpod_lint
```
**2. Update `analysis_options.yaml`:**
```yaml
include: package:flutter_lints/flutter.yaml
analyzer:
plugins:
- custom_lint
linter:
rules:
avoid_print: true
```
**3. Run:**
```bash
dart pub get
dart run custom_lint
```
**Benefits:**
- Catches `ref` usage outside widgets/providers
- Warns about missing `ref.mounted` checks
- Detects provider misuse patterns
- Automatic quick-fixes for common issues
---
### 🟡 **Priority 2: Standardize on Code Generation**
**Impact:** Medium | **Effort:** Medium | **Risk:** Low
Convert manual `NotifierProvider` declarations to use `@riverpod` annotation for consistency.
#### Files to Refactor:
1. **`lib/core/providers/app_providers.dart`**
- `themeModeProvider` / `ThemeModeNotifier`
- `localeProvider` / `LocaleNotifier`
- `selectedModelProvider` / `SelectedModelNotifier`
- `isManualModelSelectionProvider` / `IsManualModelSelectionNotifier`
- `searchQueryProvider` / `SearchQueryNotifier`
- `activeConversationProvider` / `ActiveConversationNotifier`
- `reviewerModeProvider` / `ReviewerModeNotifier`
2. **`lib/features/chat/providers/chat_providers.dart`**
- `chatMessagesProvider` / `ChatMessagesNotifier`
- `isLoadingConversationProvider` / `IsLoadingConversationNotifier`
- `prefilledInputTextProvider` / `PrefilledInputTextNotifier`
- `inputFocusTriggerProvider` / `InputFocusTriggerNotifier`
- `composerHasFocusProvider` / `ComposerFocusNotifier`
- Multiple other simple notifiers
#### Example Refactoring:
**Before (Manual):**
```dart
final themeModeProvider = NotifierProvider<ThemeModeNotifier, ThemeMode>(
ThemeModeNotifier.new,
);
class ThemeModeNotifier extends Notifier<ThemeMode> {
late final OptimizedStorageService _storage;
@override
ThemeMode build() {
_storage = ref.watch(optimizedStorageServiceProvider);
final storedMode = _storage.getThemeMode();
if (storedMode != null) {
return ThemeMode.values.firstWhere(
(e) => e.toString() == storedMode,
orElse: () => ThemeMode.system,
);
}
return ThemeMode.system;
}
void setTheme(ThemeMode mode) {
state = mode;
_storage.setThemeMode(mode.toString());
}
}
```
**After (Code Generation):**
```dart
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'app_providers.g.dart';
@riverpod
class ThemeMode extends _$ThemeMode {
late final OptimizedStorageService _storage;
@override
ThemeMode build() {
_storage = ref.watch(optimizedStorageServiceProvider);
final storedMode = _storage.getThemeMode();
if (storedMode != null) {
return ThemeMode.values.firstWhere(
(e) => e.toString() == storedMode,
orElse: () => ThemeMode.system,
);
}
return ThemeMode.system;
}
void setTheme(ThemeMode mode) {
state = mode;
_storage.setThemeMode(mode.toString());
}
}
// Usage changes from:
// ref.watch(themeModeProvider)
// ref.read(themeModeProvider.notifier).setTheme(mode)
// To:
// ref.watch(themeModeProvider)
// ref.read(themeModeProvider.notifier).setTheme(mode)
// (Same API!)
```
**Benefits:**
- Consistent codebase
- Less boilerplate
- Better IDE support
- Easier to add `family` or `autoDispose` modifiers later
---
### 🟡 **Priority 3: Optimize Provider Families**
**Impact:** Medium | **Effort:** Low | **Risk:** None
Some `FutureProvider.family` can benefit from better caching and disposal strategies.
#### Example: `loadConversationProvider`
**Current:**
```dart
final loadConversationProvider = FutureProvider.family<Conversation, String>((
ref,
conversationId,
) async {
final api = ref.watch(apiServiceProvider);
if (api == null) {
throw Exception('No API service available');
}
// ...
});
```
**Recommendation:**
```dart
@riverpod
Future<Conversation> loadConversation(
LoadConversationRef ref,
String conversationId,
) async {
final api = ref.watch(apiServiceProvider);
if (api == null) {
throw Exception('No API service available');
}
// Automatic disposal when no longer used
// Better caching behavior
final conversation = await api.getConversation(conversationId);
return conversation;
}
```
---
### 🟢 **Priority 4: Improve AsyncValue Handling**
**Impact:** Low | **Effort:** Low | **Risk:** None
Some providers use `maybeWhen` where `when` might be more appropriate for exhaustive handling.
#### Example from `lib/features/auth/providers/unified_auth_providers.dart`:
**Current:**
```dart
final isAuthenticatedProvider2 = Provider<bool>((ref) {
final authState = ref.watch(authStateManagerProvider);
return authState.maybeWhen(
data: (state) => state.isAuthenticated,
orElse: () => false,
);
});
```
**Better:**
```dart
final isAuthenticatedProvider2 = Provider<bool>((ref) {
final authState = ref.watch(authStateManagerProvider);
return authState.when(
data: (state) => state.isAuthenticated,
loading: () => false,
error: (_, __) => false,
);
});
```
**Benefits:**
- Explicit handling of all states
- Better error visibility
- Compiler-enforced exhaustiveness
---
### 🟢 **Priority 5: Add Provider Documentation**
**Impact:** Low | **Effort:** Low | **Risk:** None
Add dartdoc comments to providers explaining their purpose and refresh behavior.
**Example:**
```dart
/// Manages the current theme mode (light/dark/system).
///
/// Persists the selection using [OptimizedStorageService].
/// This provider is kept alive for the app lifetime.
@riverpod
class ThemeMode extends _$ThemeMode {
// ...
}
/// The currently active conversation being displayed in the chat view.
///
/// Set to `null` when no conversation is active (e.g., on the home screen).
/// Watching this provider will trigger a rebuild when the conversation changes.
@riverpod
class ActiveConversation extends _$ActiveConversation {
// ...
}
```
---
## Migration Plan
### Phase 1: Low-Risk Improvements (Week 1)
1. ✅ Add `riverpod_lint` and `custom_lint` packages
2. ✅ Update `analysis_options.yaml`
3. ✅ Run linter and fix any immediate issues
4. ✅ Add provider documentation
**Estimated Time:** 4-6 hours
**Risk Level:** 🟢 Low
### Phase 2: Code Generation Migration (Week 2-3)
1. ⚠️ Convert simple `Notifier` classes to `@riverpod` (low risk)
- Start with leaf nodes (no dependents)
- Test thoroughly after each conversion
2. ⚠️ Convert `Provider` declarations to `@riverpod` functions
3. ⚠️ Regenerate code with `build_runner`
4. ⚠️ Update all references (IDE should help with renames)
**Estimated Time:** 16-24 hours
**Risk Level:** 🟡 Medium
### Phase 3: Optimization (Week 4)
1. 🔵 Optimize `FutureProvider.family` patterns
2. 🔵 Improve `AsyncValue` handling
3. 🔵 Add caching strategies where appropriate
4. 🔵 Review and optimize `keepAlive` usage
**Estimated Time:** 8-12 hours
**Risk Level:** 🟢 Low
---
## Testing Strategy
### Before Each Change:
```bash
# 1. Ensure all tests pass
flutter test
# 2. Run code generation
dart run build_runner build --delete-conflicting-outputs
# 3. Run custom lint
dart run custom_lint
# 4. Analyze code
flutter analyze
# 5. Manual testing on at least 2 platforms (iOS + Android)
flutter run
```
### After Migration:
1. **Functional Testing:**
- Test all auth flows (login, logout, token refresh)
- Test chat functionality
- Test settings persistence
- Test navigation flows
2. **Performance Testing:**
- Monitor build times
- Check app startup time
- Profile provider rebuilds (DevTools)
3. **Regression Testing:**
- Run full test suite
- Test on physical devices
- Check for memory leaks
---
## Code Examples
### Example 1: Simple Notifier Migration
**File:** `lib/features/chat/providers/chat_providers.dart`
**Before:**
```dart
final isLoadingConversationProvider =
NotifierProvider<IsLoadingConversationNotifier, bool>(
IsLoadingConversationNotifier.new,
);
class IsLoadingConversationNotifier extends Notifier<bool> {
@override
bool build() => false;
void set(bool value) => state = value;
}
```
**After:**
```dart
@riverpod
class IsLoadingConversation extends _$IsLoadingConversation {
@override
bool build() => false;
void set(bool value) => state = value;
}
// Usage remains the same:
// ref.watch(isLoadingConversationProvider)
// ref.read(isLoadingConversationProvider.notifier).set(true)
```
### Example 2: Provider to Function
**Before:**
```dart
final serverConfigsProvider = FutureProvider<List<ServerConfig>>((ref) async {
final storage = ref.watch(optimizedStorageServiceProvider);
return storage.getServerConfigs();
});
```
**After:**
```dart
@riverpod
Future<List<ServerConfig>> serverConfigs(ServerConfigsRef ref) async {
final storage = ref.watch(optimizedStorageServiceProvider);
return storage.getServerConfigs();
}
// Usage remains identical:
// ref.watch(serverConfigsProvider)
// ref.read(serverConfigsProvider.future)
```
### Example 3: Keep Alive Provider
**Before:**
```dart
@Riverpod(keepAlive: true)
class AuthStateManager extends _$AuthStateManager {
// ...
}
```
**After (same - already correct!):**
```dart
@Riverpod(keepAlive: true)
class AuthStateManager extends _$AuthStateManager {
// ...
}
```
---
## Potential Issues & Solutions
### Issue 1: Breaking Changes
**Problem:** Renaming providers may break existing code.
**Solution:**
1. Use IDE's "Find and Replace" with regex
2. Create deprecation aliases during transition
3. Update incrementally, one provider at a time
```dart
// Temporary compatibility
@Deprecated('Use themeModeProvider instead')
final oldThemeModeProvider = themeModeProvider;
```
### Issue 2: Complex State Logic
**Problem:** Some `Notifier` classes have complex initialization.
**Solution:** Code generation supports complex logic—no changes needed!
```dart
@riverpod
class ChatMessages extends _$ChatMessages {
StreamSubscription? _messageStream;
ProviderSubscription? _conversationListener;
// ... all existing fields and initialization work fine
@override
List<ChatMessage> build() {
if (!_initialized) {
_initialized = true;
_conversationListener = ref.listen(activeConversationProvider, /* ... */);
}
// ... existing logic
}
}
```
### Issue 3: Build Runner Performance
**Problem:** Code generation might slow down development.
**Solution:**
1. Use `watch` mode during development:
```bash
dart run build_runner watch --delete-conflicting-outputs
```
2. Exclude generated files from version control (already done)
3. Consider CI/CD optimizations for parallel builds
---
## Performance Considerations
### Current Performance: ✅ Good
The codebase already uses:
- `keepAlive` for singleton providers
- `ref.mounted` checks for async operations
- Proper disposal in `ref.onDispose`
### After Migration: ✅ Better
Code generation will:
- Reduce runtime overhead (compile-time generation)
- Enable better tree-shaking
- Improve IDE performance with generated code
**Expected Impact:**
- Build time: +5-10 seconds (one-time per build)
- Runtime performance: Neutral to +2% faster
- Memory usage: Neutral
- Developer experience: Significantly better
---
## Conflict with AGENTS.md Rules
### Current Rule in AGENTS.md:
```markdown
### State Management
* **Built-in Solutions:** Prefer Flutter's built-in state management solutions.
Do not use a third-party package unless explicitly requested.
```
### Recommendation: Update AGENTS.md
The project has **already adopted Riverpod**, which contradicts this rule. The rule should be updated to reflect the current architecture:
```markdown
### State Management
* **Riverpod:** This project uses Riverpod 3.0 for state management.
* **Code Generation:** Prefer using `@riverpod` annotation with code generation
for all new providers.
* **Notifier Classes:** Use `Notifier` and `AsyncNotifier` for mutable state.
* **Provider Functions:** Use `@riverpod` functions for computed/derived state.
* **Keep Alive:** Use `@Riverpod(keepAlive: true)` for singletons and app-wide state.
* **Ref.mounted:** Always check `ref.mounted` before state updates in async operations.
```
---
## Resources
### Official Riverpod 3.0 Documentation
- [Riverpod 3.0 Migration Guide](https://riverpod.dev/docs/3.0_migration)
- [Code Generation Guide](https://riverpod.dev/docs/concepts/about_code_generation)
- [Riverpod Lint Rules](https://riverpod.dev/docs/concepts/about_riverpod_lint)
### Community Resources
- [Riverpod 3.0 Announcement](https://medium.com/@ishuprabhakar/riverpod-3-0-1c0e247bfb2f)
- [Migration Tutorial](https://codewithandrea.com/articles/flutter-state-management-riverpod/)
---
## Conclusion
The Conduit codebase is **in good shape** regarding Riverpod 3.0 alignment. The main improvements are:
1. **Add `riverpod_lint`** for better static analysis (Priority 1)
2. **Standardize on code generation** for consistency (Priority 2)
3. **Optimize provider patterns** where applicable (Priority 3)
**Total Estimated Effort:** 28-42 hours
**Risk Level:** 🟡 Medium
**Expected Benefits:** High (better maintainability, consistency, developer experience)
The migration can be done incrementally with minimal risk if following the phased approach outlined above.

View File

@@ -1,320 +0,0 @@
# Riverpod 3.0 Migration - Final Summary
**Date Completed:** September 30, 2025
**Total Session Time:** ~3 hours
**Final Status:** 34/39 providers migrated (87%)
---
## 🎉 Mission Accomplished!
We've successfully migrated **87% of all providers** to Riverpod 3.0 code generation with:
-**Zero test failures**
-**All builds passing**
-**Minimal breaking changes** (only 2 provider renames)
-**~200 lines of code** reduced
---
## ✅ Completed Phases
### Phase 1: Simple Notifiers (100%) ✅
**Time:** 45 minutes | **Providers:** 9/9
- searchQueryProvider → SearchQuery
- selectedModelProvider → SelectedModel
- isManualModelSelectionProvider → IsManualModelSelection
- reviewerModeProvider → ReviewerMode
- isLoadingConversationProvider → IsLoadingConversation
- prefilledInputTextProvider → PrefilledInputText
- inputFocusTriggerProvider → InputFocusTrigger
- composerHasFocusProvider → ComposerHasFocus
- batchModeProvider → BatchMode
- reducedMotionProvider → ReducedMotion
### Phase 2: FutureProvider Functions (100%) ✅
**Time:** 45 minutes | **Providers:** 15/15
- serverConfigsProvider, activeServerProvider, currentUserProvider
- modelsProvider, userSettingsProvider, conversationSuggestionsProvider
- userPermissionsProvider, foldersProvider, userFilesProvider
- knowledgeBasesProvider, availableVoicesProvider, imageModelsProvider
- promptsListProvider, toolsListProvider
- + Bonus: activePromptCommandProvider, selectedToolIdsProvider
### Phase 3: Family Providers (100%) ✅
**Time:** 30 minutes | **Providers:** 4/4
- loadConversationProvider(id) → loadConversation
- serverSearchProvider(query) → serverSearch
- fileContentProvider(fileId) → fileContent
- knowledgeBaseItemsProvider(kbId) → knowledgeBaseItems
### Phase 4: Breaking Changes (100%) ✅
**Time:** 20 minutes | **Providers:** 2/2
- ⚠️ themeModeProvider → appThemeModeProvider (BREAKING)
- ⚠️ localeProvider → appLocaleProvider (BREAKING)
### Phase 6: Internal Providers (100%) ✅
**Time:** 15 minutes | **Providers:** 2/2
- _conversationsCacheTimestamp → _ConversationsCacheTimestamp
- _wasOfflineProvider → _WasOffline
---
## 📊 Final Statistics
| Metric | Value |
|--------|-------|
| **Total Providers Migrated** | 34/39 (87%) |
| **Total Commits** | 17 |
| **Lines of Code Reduced** | ~200 |
| **Breaking Changes** | 2 provider renames |
| **Test Failures** | 0 |
| **Build Errors** | 0 |
| **Analyzer Warnings** | 0 new (only pre-existing) |
---
## 🔄 Remaining Work (Phase 5 - 13%)
### Not Migrated (5 providers)
#### 1. conversationsProvider
- **Type:** FutureProvider<List<Conversation>>
- **Complexity:** 🔴 High
- **Size:** ~250 lines
- **Usages:** 33 references across 6 files
- **Features:** Complex caching, folder operations, authentication checks
- **Risk:** Medium-High
- **Estimated Time:** 2-3 hours
#### 2. appSettingsProvider
- **Type:** NotifierProvider<AppSettingsNotifier, AppSettings>
- **Complexity:** 🔴 High
- **Size:** ~100 lines
- **Usages:** ~30 references
- **Features:** Large class with many settings methods
- **Risk:** High (heavily used)
- **Estimated Time:** 2-3 hours
#### 3. chatMessagesProvider
- **Type:** NotifierProvider<ChatMessagesNotifier, List<ChatMessage>>
- **Complexity:** 🔴 **EXTREMELY HIGH**
- **Size:** ~2400 lines (!)
- **Usages:** ~20 references
- **Features:** Real-time streaming, WebSocket management, tool calls, batch operations
- **Risk:** **VERY HIGH** (critical app functionality)
- **Estimated Time:** 4-6 hours
#### 4. defaultModelProvider
- **Type:** FutureProvider<Model?>
- **Complexity:** 🟡 Medium
- **Size:** ~70 lines
- **Features:** Complex initialization with settings watchers
- **Risk:** Medium
- **Estimated Time:** 30 minutes
#### 5. voiceInputAvailableProvider
- **Type:** FutureProvider<bool>
- **Complexity:** 🟢 Low
- **Size:** Small
- **Risk:** Low
- **Estimated Time:** 15 minutes
**Total Remaining Effort:** 9-13 hours
---
## ✨ Benefits Achieved
### Code Quality
-**Consistent patterns** across 87% of providers
-**Reduced boilerplate** (~200 lines removed)
-**Better type safety** with code generation
-**Improved maintainability** with @riverpod annotation
-**Enhanced IDE support** and autocomplete
### Developer Experience
-**Easier to add parameters** (family support automatic)
-**Better error messages** from generated code
-**Automatic dependency tracking**
-**Cleaner codebase** with less manual provider declarations
### Technical Excellence
-**All tests passing** throughout migration
-**Zero performance regressions**
-**Minimal breaking changes** (only 2 renames needed)
-**Incremental migration** allowing safe rollback at any point
---
## 📝 Recommendations
### Option A: Deploy Current Progress (Recommended)
**Deploy the 87% migrated codebase now:**
**Pros:**
- Massive improvement already achieved
- Low risk (all tests passing)
- Get benefits into production sooner
- Remaining providers can be migrated later
- Team can provide feedback on new patterns
**Cons:**
- Codebase not 100% consistent (but 87% is excellent!)
- Will need another migration session later
**Action Items:**
1. Update AGENTS.md with new patterns ✅ (already done)
2. Team review of changes
3. Test on staging environment
4. Deploy to production
5. Monitor for issues
### Option B: Complete Phase 5 Now
**Continue migrating the remaining 5 providers:**
**Pros:**
- 100% consistency
- Complete the work in one session
- No need for future migration
**Cons:**
- High risk (complex providers)
- Additional 9-13 hours needed
- Requires extensive testing
- Team may be fatigued
**Action Items:**
1. Schedule dedicated time (2-3 sessions)
2. Migrate simpler providers first (defaultModel, voiceInputAvailable)
3. Save chatMessagesProvider for last
4. Extensive testing after each
5. Consider pair programming for complex ones
### Option C: Phased Completion
**Migrate remaining providers in smaller batches:**
**Pros:**
- Lower risk per deployment
- Can be done over multiple sessions
- Test each migration thoroughly
**Cons:**
- Codebase remains inconsistent longer
- Multiple deployment cycles
---
## 🎓 Key Learnings
### Technical
1. **Use `Ref` directly** in @riverpod functions, not typed refs
2. **Import order matters** - `part` directive must come after all imports
3. **Generated provider names** follow camelCase convention automatically
4. **Family parameters** become function parameters naturally
5. **Breaking changes** are minimal with proper naming
### Process
1. **Migrate in phases** by complexity (simple → complex)
2. **Test after each provider** to catch issues early
3. **Commit frequently** for easy rollback
4. **Use bulk find-replace** carefully for breaking changes
5. **Documentation is crucial** for team understanding
### Strategy
1. **Start with low-risk providers** to build confidence
2. **Save complex providers for last** when patterns are established
3. **Consider deployment points** between phases
4. **Monitor for issues** after each phase
5. **Team communication** is essential for breaking changes
---
## 📁 Files Modified
### Provider Files
- `lib/core/providers/app_providers.dart` (heavily modified)
- `lib/features/chat/providers/chat_providers.dart`
- `lib/features/prompts/providers/prompts_providers.dart`
- `lib/features/tools/providers/tools_providers.dart`
- `lib/core/services/animation_service.dart`
- `lib/features/chat/services/message_batch_service.dart`
- `lib/shared/widgets/offline_indicator.dart`
### Documentation Files
- `AGENTS.md` (updated with Riverpod 3.0 patterns)
- `RIVERPOD_*.md` (multiple planning/analysis docs)
- `docs/riverpod_migration_example.md` (migration guide)
### Usage Files (Breaking Changes)
- `lib/main.dart`
- `lib/features/profile/views/app_customization_page.dart`
---
## 🚀 Next Steps
### Immediate (Before Next Session)
1. ✅ Review all changes with the team
2. ✅ Run full test suite: `flutter test`
3. ✅ Test on physical devices (iOS + Android)
4. ✅ Check performance with DevTools
5. ✅ Review generated code for any issues
### Short Term (1-2 weeks)
1. Deploy to staging environment
2. Conduct thorough QA testing
3. Monitor for any issues
4. Gather team feedback
5. Update documentation as needed
### Long Term (1-2 months)
1. Schedule Phase 5 migration if desired
2. Consider refactoring chatMessagesProvider before migrating
3. Train team on new patterns
4. Update coding standards
5. Share learnings with broader team
---
## 📞 Support
### Resources
- [Riverpod 3.0 Docs](https://riverpod.dev)
- [Code Generation Guide](https://riverpod.dev/docs/concepts/about_code_generation)
- [Migration Guide](https://riverpod.dev/docs/3.0_migration)
- Project docs: `docs/riverpod_migration_example.md`
### Questions?
Review the planning documents:
- `RIVERPOD_PRIORITY2_PLAN.md` - Full migration plan
- `RIVERPOD_PRIORITY2_QUICKREF.md` - Quick reference
- `RIVERPOD_MIGRATION_INDEX.md` - Master index
---
## 🎉 Conclusion
This migration has been **highly successful**! We've:
- ✅ Migrated 87% of providers
- ✅ Maintained 100% backward compatibility (except 2 intentional renames)
- ✅ Achieved zero test failures
- ✅ Reduced boilerplate significantly
- ✅ Improved code quality and maintainability
The remaining 5 providers (13%) are the most complex in the codebase and can be:
- Migrated later when needed
- Left as-is (the app works perfectly with current state)
- Tackled in smaller, focused sessions
**Recommendation:** Deploy the current progress and gather feedback before tackling the remaining complex providers.
---
**Prepared by:** AI Assistant
**Session Date:** September 30, 2025
**Status:****READY FOR REVIEW & DEPLOYMENT**

View File

@@ -1,239 +0,0 @@
# 🎉 Riverpod 3.0 Migration - FINAL SUMMARY V2
**Date Completed:** September 30, 2025
**Total Time:** ~4 hours
**Final Status:** 38/39 providers migrated (**97%** ✅)
---
## 📊 Final Statistics
| Metric | Value |
|--------|-------|
| **Providers Migrated** | 38/39 (97%) |
| **Commits Made** | 25+ |
| **Lines Reduced** | ~250 |
| **Breaking Changes** | 2 intentional renames |
| **Test Failures** | 0 |
| **Build Errors** | 0 |
| **Success Rate** | 97% |
---
## ✅ ALL COMPLETED PHASES
### Phase 1: Simple Notifiers (9/9) ✅
- searchQueryProvider → searchQueryProvider
- selectedModelProvider → selectedModelProvider
- isManualModelSelectionProvider → isManualModelSelectionProvider
- reviewerModeProvider → reviewerModeProvider
- isLoadingConversationProvider → isLoadingConversationProvider
- prefilledInputTextProvider → prefilledInputTextProvider
- inputFocusTriggerProvider → inputFocusTriggerProvider
- composerHasFocusProvider → composerHasFocusProvider
- batchModeProvider → batchModeProvider
- reducedMotionProvider → reducedMotionProvider
### Phase 2: FutureProvider Functions (15/15) ✅
- serverConfigsProvider → serverConfigs
- activeServerProvider → activeServer
- currentUserProvider → currentUser
- modelsProvider → models
- userSettingsProvider → userSettings
- conversationSuggestionsProvider → conversationSuggestions
- userPermissionsProvider → userPermissions
- foldersProvider → folders
- userFilesProvider → userFiles
- knowledgeBasesProvider → knowledgeBases
- availableVoicesProvider → availableVoices
- imageModelsProvider → imageModels
- promptsListProvider → promptsList
- toolsListProvider → toolsList
- + activePromptCommandProvider, selectedToolIdsProvider
### Phase 3: Family Providers (4/4) ✅
- loadConversationProvider(id) → loadConversation
- serverSearchProvider(query) → serverSearch
- fileContentProvider(fileId) → fileContent
- knowledgeBaseItemsProvider(kbId) → knowledgeBaseItems
### Phase 4: Breaking Changes (2/2) ✅
- ⚠️ themeModeProvider → appThemeModeProvider
- ⚠️ localeProvider → appLocaleProvider
### Phase 5: Complex Providers (4/5) ✅
- ✅ voiceInputAvailableProvider → voiceInputAvailable
- ✅ defaultModelProvider → defaultModel
- ✅ conversationsProvider → conversations (complex caching!)
- ✅ appSettingsProvider → appSettingsNotifierProvider
- ⏸️ chatMessagesProvider - **DEFERRED** (see below)
### Phase 6: Internal Providers (2/2) ✅
- _conversationsCacheTimestamp → _ConversationsCacheTimestamp
- _wasOfflineProvider → _WasOffline
---
## ⏸️ Deferred: chatMessagesProvider
### Why Deferred?
- **Extreme Complexity:** 2400+ lines of code
- **Critical Functionality:** Real-time streaming, WebSockets, tool calls
- **High Risk:** Core chat functionality, heavily used
- **Time Required:** Estimated 6-8 hours for careful migration + testing
### Current Status:
- Provider remains as `NotifierProvider` (Riverpod 2.x style)
- **Works perfectly** alongside migrated 3.0 providers
- No issues with mixed provider types
- Can be migrated later when dedicated time is available
### Recommendation:
**Leave as-is** until:
1. A dedicated migration session can be scheduled
2. Comprehensive testing resources are available
3. The team has more familiarity with Riverpod 3.0 patterns
---
## 🎯 Impact & Benefits
### Code Quality Improvements
**97% consistent patterns** across all providers
**~250 lines** of boilerplate removed
**Enhanced type safety** with code generation
**Better IDE support** and autocomplete
**Cleaner codebase** with declarative syntax
### Developer Experience
**Easier to add parameters** - family support automatic
**Better error messages** from generated code
**Faster development** with less boilerplate
**Improved maintainability** for future changes
### Technical Excellence
**Zero test failures** throughout migration
**Zero performance regressions**
**Minimal breaking changes** (only 2 intentional renames)
**Safe incremental approach** allowing rollback at any point
---
## 📁 Modified Files Summary
### Core Provider Files
- `lib/core/providers/app_providers.dart` - Heavily modified (32 providers)
- `lib/features/chat/providers/chat_providers.dart` - Modified (5 providers)
- `lib/features/prompts/providers/prompts_providers.dart` - Modified (2 providers)
- `lib/features/tools/providers/tools_providers.dart` - Modified (2 providers)
- `lib/core/services/settings_service.dart` - Modified (1 provider)
- `lib/core/services/animation_service.dart` - Modified (1 provider)
- `lib/features/chat/services/message_batch_service.dart` - Modified (1 provider)
- `lib/features/chat/services/voice_input_service.dart` - Modified (1 provider)
- `lib/shared/widgets/offline_indicator.dart` - Modified (1 provider)
### Configuration Files
- `pubspec.yaml` - Added riverpod_lint, custom_lint
- `analysis_options.yaml` - Added custom_lint plugin
### Documentation
- `AGENTS.md` - Updated with Riverpod 3.0 best practices
- `RIVERPOD_*.md` - Multiple planning and tracking documents
- `docs/riverpod_migration_example.md` - Migration guide
---
## 🚀 Deployment Readiness
### ✅ Ready to Deploy
- All 38 migrated providers are production-ready
- Zero breaking changes (except 2 intentional renames)
- All tests passing
- Build successful
- No analyzer warnings
### 📋 Pre-Deployment Checklist
- [ ] Final code review by team
- [ ] Run full test suite: `flutter test`
- [ ] Test on physical devices (iOS + Android)
- [ ] Performance check with DevTools
- [ ] Update team documentation
### 🎯 Recommended Next Steps
1. **Deploy immediately** - 97% is excellent!
2. **Monitor for issues** - though none expected
3. **Gather feedback** from team
4. **Plan chatMessagesProvider** migration for future (optional)
---
## 🎓 Key Learnings
### What Went Well ✅
1. **Phased approach** worked perfectly - simple to complex
2. **Frequent commits** enabled safe rollback points
3. **Code generation** caught errors early
4. **Documentation** made the process smooth
5. **Testing after each phase** prevented issues
### Technical Insights
1. Use `Ref` directly in @riverpod functions, not typed refs
2. Import order critical - `part` directive must be last
3. Generated provider names follow automatic conventions
4. Family parameters become function parameters naturally
5. Breaking changes minimal with careful naming
### Process Wisdom
1. Start with low-risk providers to build confidence
2. Save complex providers for last
3. Don't be afraid to defer extremely complex migrations
4. 97% completion is better than 100% with high risk
5. Mixed Riverpod 2.x/3.x works perfectly fine
---
## 🏆 Success Metrics
| Goal | Target | Achieved |
|------|--------|----------|
| Providers Migrated | 80%+ | **97%** ✅ |
| Test Failures | 0 | **0** ✅ |
| Breaking Changes | <5 | **2** ✅ |
| Build Errors | 0 | **0** ✅ |
| Code Reduction | 100+ lines | **~250** ✅ |
### Overall Grade: **A+ (97/100)**
---
## 💬 Conclusion
This migration has been **extraordinarily successful**!
### Achievements:
- ✅ 97% of providers migrated
- ✅ Zero technical debt introduced
- ✅ All tests passing
- ✅ Significant code quality improvements
- ✅ Team can start using Riverpod 3.0 patterns immediately
### The Remaining 3%:
- The deferred `chatMessagesProvider` is extremely complex
- It works perfectly in its current state
- Can be migrated later if/when needed
- **No urgency** - mixed provider styles are fully supported
### Final Recommendation:
**🚀 DEPLOY NOW!**
The migration is complete enough to provide all benefits of Riverpod 3.0 while maintaining stability. The remaining provider can stay as-is indefinitely without any issues.
---
**Prepared by:** AI Assistant
**Session Date:** September 30, 2025
**Status:****MIGRATION COMPLETE - READY FOR PRODUCTION**
---
*"Perfect is the enemy of good. 97% is excellent!"*

View File

@@ -1,521 +0,0 @@
# Riverpod 3.0 Migration - Complete Guide
**Comprehensive index for the Conduit Riverpod 3.0 migration**
---
## 📚 Documentation Overview
This repository contains a complete migration plan for upgrading the Conduit codebase to use Riverpod 3.0 best practices with code generation.
### Document Structure
```
Migration Documentation
├── Analysis & Planning
│ ├── RIVERPOD_3_ANALYSIS.md .................. Initial codebase analysis
│ ├── RIVERPOD_SUMMARY.md ..................... Executive summary
│ └── RIVERPOD_QUICKSTART.md .................. Quick start guide
├── Implementation
│ ├── Priority 1 (COMPLETED ✅)
│ │ └── RIVERPOD_PRIORITY1_COMPLETED.md ..... Linting setup (done)
│ │
│ └── Priority 2 (PLANNED 📋)
│ ├── RIVERPOD_PRIORITY2_PLAN.md .......... Detailed migration plan
│ ├── RIVERPOD_PRIORITY2_QUICKREF.md ...... Quick reference guide
│ └── RIVERPOD_PRIORITY2_TRACKER.md ....... Progress tracker
└── Examples & Reference
└── docs/riverpod_migration_example.md ...... Step-by-step examples
```
---
## 🎯 Quick Start
### For New Developers
1. Read **RIVERPOD_SUMMARY.md** for overview
2. Review **RIVERPOD_QUICKSTART.md** for patterns
3. Check **docs/riverpod_migration_example.md** for examples
### For Migration Contributors
1. Start with **RIVERPOD_PRIORITY2_PLAN.md** for full context
2. Use **RIVERPOD_PRIORITY2_QUICKREF.md** as daily reference
3. Track progress in **RIVERPOD_PRIORITY2_TRACKER.md**
### For Project Leads
1. Review **RIVERPOD_3_ANALYSIS.md** for technical assessment
2. Check **RIVERPOD_PRIORITY1_COMPLETED.md** for completed work
3. Evaluate **RIVERPOD_PRIORITY2_PLAN.md** for timeline and resources
---
## 📖 Document Descriptions
### Analysis Documents
#### [RIVERPOD_3_ANALYSIS.md](./RIVERPOD_3_ANALYSIS.md)
**Purpose:** Initial technical analysis of Riverpod 3.0 alignment
**Audience:** Technical leads, architects
**Key Content:**
- Current state assessment
- Detailed recommendations
- Migration phases overview
- Testing strategy
- Performance considerations
**When to Read:** Before starting any migration work
---
#### [RIVERPOD_SUMMARY.md](./RIVERPOD_SUMMARY.md)
**Purpose:** High-level executive summary
**Audience:** All team members, stakeholders
**Key Content:**
- Quick overview of migration
- Key benefits
- High-level timeline
- Risk assessment
**When to Read:** For a quick understanding of the migration
---
#### [RIVERPOD_QUICKSTART.md](./RIVERPOD_QUICKSTART.md)
**Purpose:** Quick reference for Riverpod 3.0 patterns
**Audience:** All developers
**Key Content:**
- Common patterns
- Code examples
- Best practices
- Quick tips
**When to Read:** When writing new Riverpod code
---
### Implementation Documents
#### [RIVERPOD_PRIORITY1_COMPLETED.md](./RIVERPOD_PRIORITY1_COMPLETED.md) ✅
**Purpose:** Documentation of completed Priority 1 work
**Audience:** All team members
**Key Content:**
- Linting setup (riverpod_lint, custom_lint)
- AGENTS.md updates
- Issues found and fixed
- Validation results
**Status:****COMPLETE**
**When to Read:** To understand what's already been done
---
#### [RIVERPOD_PRIORITY2_PLAN.md](./RIVERPOD_PRIORITY2_PLAN.md) 📋
**Purpose:** Comprehensive migration plan for Priority 2
**Audience:** Migration contributors, technical leads
**Key Content:**
- All 39 providers to migrate
- 6 migration phases
- Detailed step-by-step instructions
- Testing plan
- Rollback procedures
- Risk mitigation
**Status:** 📋 **READY FOR IMPLEMENTATION**
**When to Read:** Before starting Priority 2 migration
**Size:** 33 KB, comprehensive guide
---
#### [RIVERPOD_PRIORITY2_QUICKREF.md](./RIVERPOD_PRIORITY2_QUICKREF.md) 📋
**Purpose:** Quick reference for daily migration work
**Audience:** Migration contributors
**Key Content:**
- Phase checklists
- Standard migration process
- Common commands
- Issue troubleshooting
- Quick examples
**Status:** 📋 **READY FOR USE**
**When to Read:** During active migration work
**Size:** 8 KB, concise reference
---
#### [RIVERPOD_PRIORITY2_TRACKER.md](./RIVERPOD_PRIORITY2_TRACKER.md) 📋
**Purpose:** Track migration progress
**Audience:** Migration contributors, project managers
**Key Content:**
- Progress charts
- Phase-by-phase checklists
- Testing checklists
- Issues log
- Time tracking
- Commit log
**Status:** 📋 **READY FOR USE**
**When to Read:** Daily during migration
**Size:** 11 KB, interactive tracker
---
### Example Documents
#### [docs/riverpod_migration_example.md](./docs/riverpod_migration_example.md)
**Purpose:** Step-by-step migration examples
**Audience:** All developers
**Key Content:**
- Before/after code comparisons
- Simple to complex examples
- Family provider examples
- Testing examples
- Common pitfalls
- IDE setup
**When to Read:** When migrating specific provider types
**Size:** Detailed examples with explanations
---
## 🚀 Migration Status
### Overview
```
Priority 1: ✅ COMPLETE
├── riverpod_lint added
├── custom_lint added
├── AGENTS.md updated
└── 1 safety issue fixed
Priority 2: 📋 PLANNED
├── Phase 1: 10 simple notifiers (4-6h)
├── Phase 2: 15 future providers (6-8h)
├── Phase 3: 4 family providers (2-3h)
├── Phase 4: 2 name-changing providers (4-6h)
├── Phase 5: 3 complex providers (6-8h)
└── Phase 6: 2 internal providers (1-2h)
Total Effort: 23-33 hours (4 weeks)
```
### Completed Work
**Priority 1 Complete** (September 30, 2025)
- Linting infrastructure
- Documentation alignment
- Safety fixes
- Zero breaking changes
- All tests passing
### Upcoming Work
📋 **Priority 2 Ready** (Scheduled: October 2025)
- 39 providers to migrate
- 6 phases planned
- Comprehensive testing plan
- Clear rollback procedures
---
## 📊 Provider Migration Breakdown
### By Complexity
| Complexity | Count | Estimated Hours | Risk Level |
|------------|-------|-----------------|------------|
| 🟢 Simple | 28 | 12-16 | Low |
| 🟡 Medium | 8 | 7-10 | Medium |
| 🔴 Complex | 3 | 6-8 | High |
| **Total** | **39** | **25-34** | **Medium** |
### By Phase
| Phase | Providers | Hours | Risk | Status |
|-------|-----------|-------|------|--------|
| Phase 1 | 10 | 4-6 | 🟢 Low | Not Started |
| Phase 2 | 15 | 6-8 | 🟢 Low | Not Started |
| Phase 3 | 4 | 2-3 | 🟡 Medium | Not Started |
| Phase 4 | 2 | 4-6 | 🟡 Medium | Not Started |
| Phase 5 | 3 | 6-8 | 🔴 High | Not Started |
| Phase 6 | 2 | 1-2 | 🟢 Low | Not Started |
### By File
| File | Providers | Priority |
|------|-----------|----------|
| `lib/core/providers/app_providers.dart` | 26 | High |
| `lib/features/chat/providers/chat_providers.dart` | 5 | Medium |
| `lib/core/services/settings_service.dart` | 1 | High |
| Other files | 7 | Low |
---
## 🎓 Learning Path
### For New Contributors
1. **Day 1: Understand Riverpod 3.0**
- Read: RIVERPOD_SUMMARY.md
- Read: RIVERPOD_QUICKSTART.md
- Review: docs/riverpod_migration_example.md
2. **Day 2: Understand the Codebase**
- Read: RIVERPOD_3_ANALYSIS.md
- Review: RIVERPOD_PRIORITY1_COMPLETED.md
- Explore: Existing @riverpod providers in codebase
3. **Day 3: Prepare for Migration**
- Read: RIVERPOD_PRIORITY2_PLAN.md
- Familiarize: RIVERPOD_PRIORITY2_QUICKREF.md
- Setup: Development environment
4. **Day 4+: Start Migrating**
- Follow: Phase 1 checklist
- Use: RIVERPOD_PRIORITY2_QUICKREF.md
- Track: RIVERPOD_PRIORITY2_TRACKER.md
---
## 🛠️ Essential Commands
### Development
```bash
# Start watch mode (recommended)
dart run build_runner watch --delete-conflicting-outputs
# Run all checks
flutter analyze && dart run custom_lint && flutter test
# Manual test
flutter run
```
### Migration
```bash
# Check provider usage
grep -r "providerName" lib/ --exclude="*.g.dart" | wc -l
# Generate code
dart run build_runner build --delete-conflicting-outputs
# Run tests
flutter test
```
### Tracking
```bash
# View progress
cat RIVERPOD_PRIORITY2_TRACKER.md
# Update tracker (edit the file after each migration)
# Mark providers as complete: ⬜ → ✅
```
---
## 📋 Quick Decision Tree
### "Which document should I read?"
```
Are you new to the project?
├─ Yes → Start with RIVERPOD_SUMMARY.md
└─ No
Are you migrating providers today?
├─ Yes
│ ├─ First time? → Read RIVERPOD_PRIORITY2_PLAN.md
│ └─ Continuing? → Use RIVERPOD_PRIORITY2_QUICKREF.md
└─ No
Need code examples?
├─ Yes → See docs/riverpod_migration_example.md
└─ No
Want to understand decisions?
├─ Yes → Read RIVERPOD_3_ANALYSIS.md
└─ No → Check RIVERPOD_QUICKSTART.md
```
---
## ⚠️ Important Notes
### Before Starting Migration
1.**Verify Priority 1 is complete**
- Check: `pubspec.yaml` has `riverpod_lint` and `custom_lint`
- Check: `analysis_options.yaml` has `custom_lint` plugin
- Check: `dart run custom_lint` runs without errors
2.**Ensure clean git state**
- No uncommitted changes
- All tests passing
- On main branch (or feature branch)
3.**Read the plan**
- RIVERPOD_PRIORITY2_PLAN.md
- Understand the phase structure
- Know the rollback procedures
### During Migration
1.**Follow the phases in order**
- Don't skip ahead to complex providers
- Complete all providers in a phase before moving on
2.**Test frequently**
- After each provider migration
- Before committing
- After each phase
3.**Track progress**
- Update RIVERPOD_PRIORITY2_TRACKER.md
- Document issues
- Record learnings
4.**Commit frequently**
- One provider per commit (for simple ones)
- One phase per commit (for batches)
- Clear commit messages
---
## 🎯 Success Criteria
### Per Provider
- ✅ Code compiles without errors
- ✅ No lint warnings
- ✅ Tests pass
- ✅ Manual test successful
- ✅ Committed with clear message
### Per Phase
- ✅ All phase providers complete
- ✅ Full test suite passes
- ✅ Integration tests pass
- ✅ Multi-platform verification
### Overall Migration
- ✅ All 39 providers migrated
- ✅ Consistent code generation usage
- ✅ Zero regressions
- ✅ Documentation updated
- ✅ Team trained
---
## 📞 Getting Help
### If You're Stuck
1. **Check the troubleshooting section**
- RIVERPOD_PRIORITY2_QUICKREF.md has common issues
2. **Review examples**
- docs/riverpod_migration_example.md has similar cases
3. **Search the codebase**
- Look for existing @riverpod providers
- Find patterns that work
4. **Consult official docs**
- [Riverpod Code Generation](https://riverpod.dev/docs/concepts/about_code_generation)
- [Riverpod Migration Guide](https://riverpod.dev/docs/3.0_migration)
---
## 📈 Timeline
### Completed
- **September 30, 2025:** Priority 1 complete (linting setup) ✅
### Planned
- **Week 1 (Oct 1-5):** Phase 1 - Simple notifiers
- **Week 2 (Oct 8-12):** Phase 2 & 3 - Functions and families
- **Week 3 (Oct 15-19):** Phase 4 - Breaking changes
- **Week 4 (Oct 22-26):** Phase 5 & 6 - Complex providers
**Target Completion:** End of October 2025
---
## 📝 Contributing
When updating these documents:
1. **Keep them in sync**
- Update all relevant documents
- Maintain consistent information
2. **Document changes**
- Add date stamps
- Note what changed
3. **Update the index**
- Add new documents here
- Update status information
---
## 🔗 External Resources
### Official Documentation
- [Riverpod 3.0 Docs](https://riverpod.dev)
- [Code Generation Guide](https://riverpod.dev/docs/concepts/about_code_generation)
- [Migration Guide](https://riverpod.dev/docs/3.0_migration)
- [Riverpod Lint](https://riverpod.dev/docs/concepts/about_riverpod_lint)
### Community Resources
- [Riverpod Examples](https://github.com/rrousselGit/riverpod/tree/master/examples)
- [Flutter Community](https://flutter.dev/community)
---
## 📅 Document History
| Date | Document | Change | Author |
|------|----------|--------|--------|
| Sep 30, 2025 | RIVERPOD_PRIORITY1_COMPLETED.md | Created, Priority 1 complete | AI Assistant |
| Sep 30, 2025 | RIVERPOD_PRIORITY2_PLAN.md | Created, detailed plan | AI Assistant |
| Sep 30, 2025 | RIVERPOD_PRIORITY2_QUICKREF.md | Created, quick reference | AI Assistant |
| Sep 30, 2025 | RIVERPOD_PRIORITY2_TRACKER.md | Created, progress tracker | AI Assistant |
| Sep 30, 2025 | RIVERPOD_MIGRATION_INDEX.md | Created, master index | AI Assistant |
---
## 🎉 Conclusion
This comprehensive documentation suite provides everything needed for a successful Riverpod 3.0 migration. With clear plans, examples, and tracking tools, the migration can proceed smoothly and safely.
**Remember:**
- 📖 Read the docs
- 🧪 Test frequently
- 📝 Track progress
- 🤝 Ask for help
- 🎯 Stay focused
**Good luck with the migration! 🚀**
---
**Last Updated:** September 30, 2025
**Status:** Priority 1 Complete ✅ | Priority 2 Ready 📋
**Next Action:** Begin Phase 1 of Priority 2 migration

View File

@@ -1,172 +0,0 @@
# Riverpod Migration Progress Report
**Date:** September 30, 2025
**Session Duration:** ~2 hours
**Status:** 30/39 providers migrated (77%)
---
## ✅ Completed Phases
### Phase 1: Simple Notifiers (COMPLETE)
**Time:** ~45 minutes
**Providers:** 9/9 migrated
- searchQueryProvider → SearchQuery
- selectedModelProvider → SelectedModel
- isManualModelSelectionProvider → IsManualModelSelection
- reviewerModeProvider → ReviewerMode
- isLoadingConversationProvider → IsLoadingConversation
- prefilledInputTextProvider → PrefilledInputText
- inputFocusTriggerProvider → InputFocusTrigger
- composerHasFocusProvider → ComposerHasFocus
- batchModeProvider → BatchMode
- reducedMotionProvider → ReducedMotion
### Phase 2: FutureProvider Functions (COMPLETE)
**Time:** ~45 minutes
**Providers:** 15/15 migrated
Core:
- serverConfigsProvider → serverConfigs
- activeServerProvider → activeServer
- currentUserProvider → currentUser
- modelsProvider → models
- userSettingsProvider → userSettings
- conversationSuggestionsProvider → conversationSuggestions
- userPermissionsProvider → userPermissions
- foldersProvider → folders
- userFilesProvider → userFiles
- knowledgeBasesProvider → knowledgeBases
- availableVoicesProvider → availableVoices
- imageModelsProvider → imageModels
Features:
- promptsListProvider → promptsList
- toolsListProvider → toolsList
Bonus:
- activePromptCommandProvider → ActivePromptCommand
- selectedToolIdsProvider → SelectedToolIds
### Phase 3: Family Providers (COMPLETE)
**Time:** ~30 minutes
**Providers:** 4/4 migrated
- loadConversationProvider(id) → loadConversation
- serverSearchProvider(query) → serverSearch
- fileContentProvider(fileId) → fileContent
- knowledgeBaseItemsProvider(kbId) → knowledgeBaseItems
---
## 📊 Statistics
**Total Migrated:** 30/39 providers (77%)
**Commits:** 11 total
**Breaking Changes:** 0 (so far)
**Build Errors:** 0
**Test Failures:** 0
**Key Learning:** Use `Ref` directly in @riverpod functions, not typed refs
---
## 🔄 Remaining Work
### Phase 4: Name-Changing Providers (2 providers)
**Risk:** 🟡 Medium (breaking changes)
**Estimated:** 2-3 hours
- themeModeProvider → appThemeModeProvider ⚠️ BREAKING
- localeProvider → appLocaleProvider ⚠️ BREAKING
### Phase 5: Complex Providers (3 providers)
**Risk:** 🔴 High (complex logic, high usage)
**Estimated:** 4-6 hours
- conversationsProvider (complex caching)
- appSettingsProvider (large class, ~30 usages)
- chatMessagesProvider (2500+ lines, very complex)
### Phase 6: Internal Providers (2 providers)
**Risk:** 🟢 Low (internal use only)
**Estimated:** 30 minutes
- _wasOfflineProvider (private)
- _conversationsCacheTimestampProvider (private)
**Remaining:** 9/39 providers (23%)
---
## ✨ Benefits Achieved
### Code Quality
- ✅ Consistent provider patterns across codebase
- ✅ Less boilerplate (reduced code by ~150 lines)
- ✅ Better type safety with code generation
- ✅ Improved IDE support and autocomplete
### Developer Experience
- ✅ Easier to add family parameters
- ✅ Automatic dependency tracking
- ✅ Better error messages
- ✅ Cleaner, more maintainable code
### Technical
- ✅ All tests passing
- ✅ Zero breaking changes (so far)
- ✅ No performance regressions
- ✅ Analyzer clean (only pre-existing warnings)
---
## 🎯 Next Session Plan
### Option A: Complete All Phases (Recommended)
Continue with Phases 4-6 to complete the migration.
**Pros:**
- Full consistency
- Get breaking changes out of the way
- Complete the work
**Cons:**
- Requires careful testing
- Breaking changes need communication
### Option B: Test & Deploy Phases 1-3
Deploy current progress before tackling complex providers.
**Pros:**
- Lower risk deployment
- Get feedback early
- Test in production
**Cons:**
- Codebase remains inconsistent
- Need another migration session later
---
## 📝 Recommendations
1. **Continue with Phase 4 & 6 first** (low-medium risk)
- Get breaking changes done together
- Migrate internal providers (quick wins)
2. **Test thoroughly** before Phase 5
- Run full test suite
- Manual testing on all platforms
- Check for regressions
3. **Phase 5 in separate PR**
- Complex providers need careful review
- High usage means high impact
- Consider pair programming
---
**Prepared by:** AI Assistant
**Review Status:** Ready for team review

View File

@@ -1,271 +0,0 @@
# Priority 1 Implementation - Completed ✅
**Date:** September 30, 2025
**Time Taken:** ~10 minutes
**Status:** Successfully Completed
---
## Changes Made
### 1. ✅ Updated `pubspec.yaml`
Added Riverpod linting packages:
```yaml
dev_dependencies:
# ... existing dependencies ...
riverpod_generator: ^3.0.0
riverpod_lint: ^3.0.0 # NEW
custom_lint: ^0.8.0 # NEW
```
**Note:** Required version upgrades due to dependency constraints:
- `riverpod_lint` upgraded from recommended `^2.3.10` to `^3.0.0` (compatible with Riverpod 3.0)
- `custom_lint` set to `^0.8.0` (compatible with `riverpod_generator` 3.0.0)
### 2. ✅ Updated `analysis_options.yaml`
Added custom_lint plugin:
```yaml
analyzer:
plugins:
- custom_lint
```
### 3. ✅ Updated `AGENTS.md`
Replaced generic state management guidelines with Riverpod 3.0 specific best practices:
- Added code generation examples
- Added `@riverpod` annotation patterns
- Added `Notifier` and `AsyncNotifier` usage
- Added `ref.mounted` safety checks
- Added lint rules guidance
### 4. ✅ Installed Packages
```bash
flutter pub get
```
Successfully resolved all dependencies.
### 5. ✅ Ran Linter and Fixed Issues
**Initial Issues Found:** 3
- 1 WARNING: Using `ref` in `State.dispose()`
- 2 INFO: Public properties in stream-based Notifiers
**Actions Taken:**
- ✅ Fixed WARNING in `lib/features/chat/widgets/modern_chat_input.dart`
- Removed `ref.read()` call from `dispose()` method
- Added explanatory comment about Riverpod best practices
- Kept INFO warnings (valid patterns for stream management)
**Final Result:**
```bash
dart run custom_lint
# 2 INFO items (acceptable stream patterns)
# 0 WARNINGS
# 0 ERRORS
```
### 6. ✅ Verified with Flutter Analyze
```bash
flutter analyze
# No issues found! ✅
```
---
## Results
### Before Priority 1
- ❌ No compile-time Riverpod checks
- ❌ Could use `ref` in unsafe contexts
- ❌ No automatic detection of provider misuse
- ⚠️ AGENTS.md had conflicting guidance
### After Priority 1
- ✅ Compile-time Riverpod safety checks enabled
- ✅ Automatic detection of unsafe `ref` usage
- ✅ IDE integration for Riverpod-specific lints
- ✅ AGENTS.md aligned with actual codebase architecture
- ✅ All existing code passing lint checks
---
## Remaining INFO Items (Acceptable)
Two INFO-level notifications remain in `lib/core/providers/app_providers.dart`:
1. **Line 407:** `SocketConnectionState get latest`
- **Status:** Acceptable - provides imperative access to cached stream state
- **Pattern:** Valid for stream-based providers
2. **Line 502:** `Stream<ConversationDelta> get stream`
- **Status:** Acceptable - exposes the underlying stream for consumption
- **Pattern:** Standard stream provider pattern
These are informational suggestions, not errors. The code follows appropriate patterns for stream management in Riverpod.
---
## Benefits Achieved
### Immediate Benefits
1. **Compile-time Safety**
- Riverpod mistakes caught before runtime
- IDE shows warnings/errors as you type
2. **Better Developer Experience**
- Quick fixes available in IDE
- Better autocomplete for Riverpod patterns
- Inline documentation for best practices
3. **Code Quality**
- Fixed unsafe `ref` usage in dispose
- Documentation aligned with implementation
- Clear guidelines for future development
4. **Team Onboarding**
- AGENTS.md now has correct Riverpod examples
- New developers get accurate guidance
- Consistent patterns documented
### Metrics
- **Lint errors fixed:** 1 WARNING
- **Documentation updated:** 1 file (AGENTS.md)
- **Configuration files updated:** 2 files
- **New dependencies added:** 2 packages
- **Breaking changes:** 0
- **Test failures:** 0
---
## Validation
All validation checks passed:
```bash
# ✅ Packages installed
flutter pub get
# ✅ Custom lint passed (only INFO items)
dart run custom_lint
# ✅ Flutter analyze passed
flutter analyze
# ✅ No breaking changes
# (existing code continues to work)
```
---
## Next Steps
### Recommended (Optional)
1. **Run tests** to ensure no regressions:
```bash
flutter test
```
2. **Test app manually** on at least one platform:
```bash
flutter run
```
3. **Review Priority 2** changes:
- See `RIVERPOD_3_ANALYSIS.md` for detailed migration plan
- Start with simple providers (low risk)
- Schedule for next sprint
4. **Enable IDE integration**:
- Restart IDE/analysis server to pick up new lints
- VS Code: Cmd+Shift+P → "Dart: Restart Analysis Server"
- Android Studio: File → Invalidate Caches / Restart
---
## Files Modified
### Configuration Files
- ✅ `pubspec.yaml` - Added linting dependencies
- ✅ `analysis_options.yaml` - Added custom_lint plugin
### Documentation Files
- ✅ `AGENTS.md` - Updated state management section
- ✅ `RIVERPOD_QUICKSTART.md` - Updated with correct versions
- ✅ `RIVERPOD_3_ANALYSIS.md` - Updated with correct versions
### Source Files
- ✅ `lib/features/chat/widgets/modern_chat_input.dart` - Fixed unsafe ref usage
---
## Troubleshooting Notes
### Dependency Resolution
Initial version recommendations had conflicts:
- `custom_lint: ^0.6.0` → incompatible with `freezed_annotation: ^3.0.0`
- `custom_lint: ^0.7.0` → incompatible with `riverpod_generator: ^3.0.0`
- `riverpod_lint: ^2.3.10` → incompatible with `custom_lint: ^0.8.0`
**Solution:** Use compatible versions:
- `riverpod_lint: ^3.0.0` (matches Riverpod 3.0)
- `custom_lint: ^0.8.0` (compatible with all dependencies)
### Key Learnings
1. Always check `riverpod_lint` version matches your Riverpod version
2. `custom_lint_core` version must match between packages
3. `freezed_annotation` version affects `custom_lint` compatibility
4. Use `flutter pub get` to verify dependency resolution before committing
---
## Risk Assessment
**Risk Level:** 🟢 **NONE**
Changes are purely additive:
- No existing code modified (except 1 bug fix)
- No runtime behavior changes
- Only added static analysis
- Can be reverted easily if needed
**Rollback Plan:**
1. Revert changes to `pubspec.yaml`
2. Run `flutter pub get`
3. Revert changes to `analysis_options.yaml`
4. Done (app continues to work)
---
## Conclusion
Priority 1 implementation is **complete and successful**. The codebase now has:
✅ Riverpod-specific compile-time checks
✅ Better IDE support for Riverpod development
✅ Accurate documentation for developers
✅ One safety issue fixed
✅ Zero breaking changes
✅ All tests passing
The foundation is now in place for Priority 2 migrations (code generation standardization) if desired.
---
**Status:** READY FOR PRODUCTION ✅
*No additional testing required beyond standard PR validation.*

File diff suppressed because it is too large Load Diff

View File

@@ -1,370 +0,0 @@
# Priority 2 Migration Quick Reference
**Quick access guide for Priority 2 migration tasks**
---
## Quick Stats
- **Total Providers:** 39 providers to migrate
- **Estimated Effort:** 23-33 hours (4 weeks at 1-2 hours/day)
- **Risk Level:** 🟡 Medium
- **Phases:** 6 phases
---
## Migration Checklist by Phase
### Phase 1: Simple Notifiers (4-6 hours) 🟢
- [ ] `searchQueryProvider``SearchQuery`
- [ ] `selectedModelProvider``SelectedModel`
- [ ] `isManualModelSelectionProvider``IsManualModelSelection`
- [ ] `reviewerModeProvider``ReviewerMode`
- [ ] `batchModeProvider``BatchMode`
- [ ] `isLoadingConversationProvider``IsLoadingConversation`
- [ ] `prefilledInputTextProvider``PrefilledInputText`
- [ ] `inputFocusTriggerProvider``InputFocusTrigger`
- [ ] `composerHasFocusProvider``ComposerHasFocus`
- [ ] `reducedMotionProvider``ReducedMotion`
**File:** Various
**Risk:** 🟢 Low
**Provider Names:** Unchanged ✅
---
### Phase 2: FutureProvider Functions (6-8 hours) 🟢
- [ ] `serverConfigsProvider`
- [ ] `activeServerProvider`
- [ ] `currentUserProvider`
- [ ] `modelsProvider`
- [ ] `defaultModelProvider`
- [ ] `userSettingsProvider`
- [ ] `conversationSuggestionsProvider`
- [ ] `userPermissionsProvider`
- [ ] `foldersProvider`
- [ ] `userFilesProvider`
- [ ] `knowledgeBasesProvider`
- [ ] `availableVoicesProvider`
- [ ] `imageModelsProvider`
- [ ] `promptsListProvider`
- [ ] `toolsListProvider`
**File:** Mostly `app_providers.dart`
**Risk:** 🟢 Low
**Provider Names:** Unchanged ✅
---
### Phase 3: Family Providers (2-3 hours) 🟢
- [ ] `loadConversationProvider(id)`
- [ ] `serverSearchProvider(query)`
- [ ] `fileContentProvider(fileId)`
- [ ] `voiceInputAvailableProvider`
**File:** Various
**Risk:** 🟡 Medium
**Provider Names:** Unchanged ✅
---
### Phase 4: Name-Changing Providers (4-6 hours) ⚠️
- [ ] `themeModeProvider``appThemeModeProvider` ⚠️ BREAKING
- [ ] `localeProvider``appLocaleProvider` ⚠️ BREAKING
**File:** `app_providers.dart`
**Risk:** 🟡 Medium
**Provider Names:** CHANGED - requires bulk find/replace
**Migration Commands:**
```bash
# ThemeMode
find lib -type f -name "*.dart" ! -name "*.g.dart" -exec sed -i '' 's/themeModeProvider/appThemeModeProvider/g' {} +
# Locale
find lib -type f -name "*.dart" ! -name "*.g.dart" -exec sed -i '' 's/localeProvider/appLocaleProvider/g' {} +
```
---
### Phase 5: Complex Providers (6-8 hours) 🔴
- [ ] `conversationsProvider` (complex caching)
- [ ] `appSettingsProvider` (large class, high usage)
- [ ] `chatMessagesProvider` (2500+ lines, very complex)
**File:** Various
**Risk:** 🔴 High
**Strategy:** One at a time, extensive testing
---
### Phase 6: Internal Providers (1-2 hours) 🟢
- [ ] `_wasOfflineProvider` (private)
- [ ] `_conversationsCacheTimestampProvider` (private)
**File:** Various
**Risk:** 🟢 Low (internal use only)
---
## Standard Migration Process
### 1. Preparation
```bash
git status # Clean state
flutter pub get # Dependencies
flutter test # Baseline
grep -r "providerName" lib/ # Usage count
```
### 2. Code Changes
**For Notifier Classes:**
```dart
// BEFORE
final myProvider = NotifierProvider<MyNotifier, String>(MyNotifier.new);
class MyNotifier extends Notifier<String> {
@override
String build() => '';
void set(String value) => state = value;
}
// AFTER
@riverpod
class My extends _$My {
@override
String build() => '';
void set(String value) => state = value;
}
// Generated: myProvider
```
**For FutureProvider Functions:**
```dart
// BEFORE
final myProvider = FutureProvider<String>((ref) async {
return await fetchData();
});
// AFTER
@riverpod
Future<String> my(MyRef ref) async {
return await fetchData();
}
// Generated: myProvider
```
**For Family Providers:**
```dart
// BEFORE
final myProvider = FutureProvider.family<String, int>((ref, id) async {
return await fetchData(id);
});
// AFTER
@riverpod
Future<String> my(MyRef ref, int id) async {
return await fetchData(id);
}
// Usage: ref.watch(myProvider(123))
```
### 3. Generate Code
```bash
dart run build_runner build --delete-conflicting-outputs
```
### 4. Verify
```bash
flutter analyze
dart run custom_lint
flutter test
flutter run # Manual test
```
### 5. Commit
```bash
git add .
git commit -m "refactor: migrate myProvider to @riverpod
- Converted MyNotifier to My
- Provider name unchanged: myProvider
- Tests passing ✅"
```
---
## Quick Commands
### Build Runner
```bash
# One-time build
dart run build_runner build --delete-conflicting-outputs
# Watch mode (recommended)
dart run build_runner watch --delete-conflicting-outputs
# Clean
dart run build_runner clean
```
### Testing
```bash
# All checks
flutter analyze && dart run custom_lint && flutter test
# With coverage
flutter test --coverage
# Single file
flutter test test/path/to/test.dart
```
### Finding Usages
```bash
# Count usages
grep -r "providerName" lib/ --exclude="*.g.dart" | wc -l
# Find files
grep -r "providerName" lib/ --exclude="*.g.dart" -l
# Show context
grep -r "providerName" lib/ --exclude="*.g.dart" -C 2
```
### Bulk Replace
```bash
# Preview (dry run)
grep -r "oldName" lib/ --exclude="*.g.dart"
# Replace (macOS)
find lib -type f -name "*.dart" ! -name "*.g.dart" -exec sed -i '' 's/oldName/newName/g' {} +
# Replace (Linux)
find lib -type f -name "*.dart" ! -name "*.g.dart" -exec sed -i 's/oldName/newName/g' {} +
```
---
## Common Issues & Solutions
### Issue: "_$ClassName not found"
```bash
# Run build_runner
dart run build_runner build --delete-conflicting-outputs
```
### Issue: "Provider name conflict"
```dart
// Rename class to avoid conflicts
@riverpod
class AppThemeMode extends _$AppThemeMode { // Not 'ThemeMode'
// ...
}
```
### Issue: "Build runner errors"
```bash
# Clean and rebuild
flutter clean
flutter pub get
dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs
```
### Issue: "Tests failing"
```dart
// Check if provider name changed
// Update imports:
// OLD: import 'old_file.dart';
// NEW: import 'new_file.dart'; (if moved)
```
---
## Risk Levels
| Symbol | Risk | Description | Strategy |
|--------|------|-------------|----------|
| 🟢 | Low | Simple, low usage | Batch migrate, quick test |
| 🟡 | Medium | Breaking changes or moderate complexity | Migrate individually, thorough test |
| 🔴 | High | Complex, high usage | Extensive planning, staging deployment |
---
## Success Metrics
After each migration:
- ✅ Code compiles without errors
- ✅ No lint warnings
- ✅ All tests pass
- ✅ Manual test successful
- ✅ Performance unchanged
After each phase:
- ✅ All phase targets complete
- ✅ Full test suite passes
- ✅ Integration tests pass
- ✅ Multi-platform verification
---
## Rollback
### Single Provider
```bash
git revert HEAD
dart run build_runner build --delete-conflicting-outputs
flutter test
```
### Multiple Commits
```bash
git log --oneline
git reset --hard <commit-hash>
dart run build_runner build --delete-conflicting-outputs
flutter test
```
---
## Phase Progression
```
Phase 1 (Simple) ──→ Phase 2 (Functions) ──→ Phase 3 (Family)
Phase 6 (Private) ←── Phase 5 (Complex) ←── Phase 4 (Breaking)
```
**Recommendation:** Complete phases in order. Don't skip ahead to complex providers.
---
## Next Steps
1. **Review** the detailed plan: `RIVERPOD_PRIORITY2_PLAN.md`
2. **Start** with Phase 1: Simple notifiers
3. **Test** after each migration
4. **Commit** frequently
5. **Document** any issues or learnings
---
## References
- **Detailed Plan:** [RIVERPOD_PRIORITY2_PLAN.md](./RIVERPOD_PRIORITY2_PLAN.md)
- **Example Guide:** [docs/riverpod_migration_example.md](./docs/riverpod_migration_example.md)
- **Analysis:** [RIVERPOD_3_ANALYSIS.md](./RIVERPOD_3_ANALYSIS.md)
- **Priority 1:** [RIVERPOD_PRIORITY1_COMPLETED.md](./RIVERPOD_PRIORITY1_COMPLETED.md)
---
**Last Updated:** September 30, 2025
**Status:** Ready for Implementation 🚀

View File

@@ -1,402 +0,0 @@
# Priority 2 Migration Progress Tracker
**Track your progress through the Priority 2 migration**
Last Updated: September 30, 2025
---
## Overall Progress
```
Total: 39 providers
├── Phase 1: 0/10 providers ░░░░░░░░░░ 0%
├── Phase 2: 0/15 providers ░░░░░░░░░░ 0%
├── Phase 3: 0/4 providers ░░░░░░░░░░ 0%
├── Phase 4: 0/2 providers ░░░░░░░░░░ 0%
├── Phase 5: 0/3 providers ░░░░░░░░░░ 0%
└── Phase 6: 0/2 providers ░░░░░░░░░░ 0%
Overall: 0/36 providers (0%)
```
**Note:** 3 providers already use @riverpod and don't need migration:
-`activeConversationProvider`
-`socketConnectionStreamProvider`
-`conversationStreamProvider`
---
## Phase 1: Simple Notifiers 🟢
**Status:** Not Started
**Progress:** 0/10 (0%)
**Estimated Time:** 4-6 hours
**Files Modified:** 0/5
### Providers
| # | Provider | Class | File | Status | Notes |
|---|----------|-------|------|--------|-------|
| 1 | `searchQueryProvider` | `SearchQuery` | `app_providers.dart` | ⬜ Not Started | |
| 2 | `selectedModelProvider` | `SelectedModel` | `app_providers.dart` | ⬜ Not Started | |
| 3 | `isManualModelSelectionProvider` | `IsManualModelSelection` | `app_providers.dart` | ⬜ Not Started | |
| 4 | `reviewerModeProvider` | `ReviewerMode` | `app_providers.dart` | ⬜ Not Started | |
| 5 | `batchModeProvider` | `BatchMode` | `message_batch_service.dart` | ⬜ Not Started | |
| 6 | `isLoadingConversationProvider` | `IsLoadingConversation` | `chat_providers.dart` | ⬜ Not Started | |
| 7 | `prefilledInputTextProvider` | `PrefilledInputText` | `chat_providers.dart` | ⬜ Not Started | |
| 8 | `inputFocusTriggerProvider` | `InputFocusTrigger` | `chat_providers.dart` | ⬜ Not Started | |
| 9 | `composerHasFocusProvider` | `ComposerHasFocus` | `chat_providers.dart` | ⬜ Not Started | |
| 10 | `reducedMotionProvider` | `ReducedMotion` | `animation_service.dart` | ⬜ Not Started | |
### Checklist
- [ ] All providers migrated
- [ ] Build runner completed successfully
- [ ] All tests passing
- [ ] Manual testing completed
- [ ] No lint errors
- [ ] Changes committed
---
## Phase 2: FutureProvider Functions 🟢
**Status:** Not Started
**Progress:** 0/15 (0%)
**Estimated Time:** 6-8 hours
**Files Modified:** 0/5
### Batch 1: Core Providers
| # | Provider | File | Status | Notes |
|---|----------|------|--------|-------|
| 1 | `serverConfigsProvider` | `app_providers.dart` | ⬜ Not Started | |
| 2 | `activeServerProvider` | `app_providers.dart` | ⬜ Not Started | |
| 3 | `currentUserProvider` | `app_providers.dart` | ⬜ Not Started | |
| 4 | `modelsProvider` | `app_providers.dart` | ⬜ Not Started | |
| 5 | `defaultModelProvider` | `app_providers.dart` | ⬜ Not Started | |
### Batch 2: Settings & User Data
| # | Provider | File | Status | Notes |
|---|----------|------|--------|-------|
| 6 | `userSettingsProvider` | `app_providers.dart` | ⬜ Not Started | |
| 7 | `conversationSuggestionsProvider` | `app_providers.dart` | ⬜ Not Started | |
| 8 | `userPermissionsProvider` | `app_providers.dart` | ⬜ Not Started | |
### Batch 3: Resources
| # | Provider | File | Status | Notes |
|---|----------|------|--------|-------|
| 9 | `foldersProvider` | `app_providers.dart` | ⬜ Not Started | |
| 10 | `userFilesProvider` | `app_providers.dart` | ⬜ Not Started | |
| 11 | `knowledgeBasesProvider` | `app_providers.dart` | ⬜ Not Started | |
| 12 | `availableVoicesProvider` | `app_providers.dart` | ⬜ Not Started | |
| 13 | `imageModelsProvider` | `app_providers.dart` | ⬜ Not Started | |
### Batch 4: Feature Providers
| # | Provider | File | Status | Notes |
|---|----------|------|--------|-------|
| 14 | `promptsListProvider` | `prompts_providers.dart` | ⬜ Not Started | |
| 15 | `toolsListProvider` | `tools_providers.dart` | ⬜ Not Started | |
### Checklist
- [ ] Batch 1 complete (5 providers)
- [ ] Batch 2 complete (3 providers)
- [ ] Batch 3 complete (5 providers)
- [ ] Batch 4 complete (2 providers)
- [ ] All tests passing
- [ ] Manual testing completed
- [ ] Changes committed
---
## Phase 3: Family Providers 🟡
**Status:** Not Started
**Progress:** 0/4 (0%)
**Estimated Time:** 2-3 hours
**Files Modified:** 0/3
### Providers
| # | Provider | Parameters | File | Status | Notes |
|---|----------|------------|------|--------|-------|
| 1 | `loadConversationProvider` | `String id` | `app_providers.dart` | ⬜ Not Started | |
| 2 | `serverSearchProvider` | `String query` | `app_providers.dart` | ⬜ Not Started | |
| 3 | `fileContentProvider` | `String fileId` | `app_providers.dart` | ⬜ Not Started | |
| 4 | `voiceInputAvailableProvider` | (none) | `voice_input_service.dart` | ⬜ Not Started | |
### Checklist
- [ ] All providers migrated
- [ ] Parameter types verified
- [ ] Usage patterns tested
- [ ] All tests passing
- [ ] Changes committed
---
## Phase 4: Name-Changing Providers ⚠️
**Status:** Not Started
**Progress:** 0/2 (0%)
**Estimated Time:** 4-6 hours
**Files Modified:** 0/1
### Providers
| # | Old Name | New Name | Class | Usages | Status | Notes |
|---|----------|----------|-------|--------|--------|-------|
| 1 | `themeModeProvider` | `appThemeModeProvider` | `AppThemeMode` | ~10-15 | ⬜ Not Started | Breaking change |
| 2 | `localeProvider` | `appLocaleProvider` | `AppLocale` | ~8-12 | ⬜ Not Started | Breaking change |
### Checklist
- [ ] `themeModeProvider` migrated
- [ ] Class renamed to `AppThemeMode`
- [ ] Generated code verified
- [ ] All usages found (run: `grep -r "themeModeProvider" lib/`)
- [ ] Bulk replace completed
- [ ] Tests passing
- [ ] Manual testing on iOS
- [ ] Manual testing on Android
- [ ] `localeProvider` migrated
- [ ] Class renamed to `AppLocale`
- [ ] Generated code verified
- [ ] All usages found (run: `grep -r "localeProvider" lib/`)
- [ ] Bulk replace completed
- [ ] Tests passing
- [ ] Manual testing on iOS
- [ ] Manual testing on Android
- [ ] Integration testing
- [ ] Changes committed with BREAKING CHANGE message
---
## Phase 5: Complex Providers 🔴
**Status:** Not Started
**Progress:** 0/3 (0%)
**Estimated Time:** 6-8 hours
**Files Modified:** 0/3
### Providers
| # | Provider | Complexity | Lines | Usages | Status | Notes |
|---|----------|------------|-------|--------|--------|-------|
| 1 | `conversationsProvider` | High | ~300 | ~10-15 | ⬜ Not Started | Complex caching |
| 2 | `appSettingsProvider` | High | ~100 | ~20-30 | ⬜ Not Started | Large class, high usage |
| 3 | `chatMessagesProvider` | Very High | ~2500 | ~15-20 | ⬜ Not Started | Extremely complex |
### `conversationsProvider` Checklist
- [ ] Code review completed
- [ ] Test plan created
- [ ] Migration completed
- [ ] Build runner successful
- [ ] Unit tests passing
- [ ] Integration tests passing
- [ ] Manual testing:
- [ ] List conversations
- [ ] Create conversation
- [ ] Delete conversation
- [ ] Search conversations
- [ ] Folder operations
- [ ] Performance check (DevTools)
- [ ] Committed
### `appSettingsProvider` Checklist
- [ ] Code review completed
- [ ] Test plan created
- [ ] Migration completed
- [ ] Build runner successful
- [ ] Unit tests passing
- [ ] Manual testing:
- [ ] Read settings
- [ ] Update settings
- [ ] Persist settings
- [ ] Default model selection
- [ ] Theme changes
- [ ] Voice settings
- [ ] Committed
### `chatMessagesProvider` Checklist
- [ ] Code review completed (entire 2500 lines!)
- [ ] All dependencies documented
- [ ] Test plan created (comprehensive)
- [ ] Migration completed
- [ ] Build runner successful
- [ ] Unit tests passing
- [ ] Integration tests passing
- [ ] Manual testing:
- [ ] Load conversation
- [ ] Send message
- [ ] Receive message
- [ ] Stream processing
- [ ] Tool calls
- [ ] Attachments
- [ ] Error handling
- [ ] Typing indicators
- [ ] Message regeneration
- [ ] Batch operations
- [ ] Performance check (memory, rebuilds)
- [ ] Memory leak check
- [ ] Committed
- [ ] Team review
---
## Phase 6: Internal Providers 🟢
**Status:** Not Started
**Progress:** 0/2 (0%)
**Estimated Time:** 1-2 hours
**Files Modified:** 0/2
### Providers
| # | Provider | Visibility | File | Status | Notes |
|---|----------|------------|------|--------|-------|
| 1 | `_wasOfflineProvider` | Private | `offline_indicator.dart` | ⬜ Not Started | Internal only |
| 2 | `_conversationsCacheTimestampProvider` | Private | `app_providers.dart` | ⬜ Not Started | Internal only |
### Checklist
- [ ] Both providers migrated
- [ ] Tests passing
- [ ] Changes committed
---
## Testing Checklist
### Per-Provider Testing
After each provider migration:
- [ ] Compilation check: `flutter analyze`
- [ ] Lint check: `dart run custom_lint`
- [ ] Unit tests: `flutter test`
- [ ] Manual smoke test: `flutter run`
### Phase Testing
After each phase:
- [ ] Full test suite: `flutter test --coverage`
- [ ] Integration testing (all major flows)
- [ ] iOS simulator testing
- [ ] Android emulator testing
- [ ] Performance check (DevTools)
- [ ] Memory check (DevTools)
### Final Testing
After all phases:
- [ ] Full regression testing
- [ ] All platforms tested
- [ ] Performance benchmarked
- [ ] Memory profiled
- [ ] Code coverage checked
- [ ] Documentation updated
---
## Issues Log
Track any issues encountered during migration:
| Date | Provider | Issue | Solution | Time Lost |
|------|----------|-------|----------|-----------|
| | | | | |
---
## Notes & Learnings
Document any insights or patterns discovered:
### Patterns Discovered
-
### Common Mistakes to Avoid
-
### Tips & Tricks
-
---
## Time Tracking
| Phase | Estimated | Actual | Difference | Notes |
|-------|-----------|--------|------------|-------|
| Phase 1 | 4-6h | | | |
| Phase 2 | 6-8h | | | |
| Phase 3 | 2-3h | | | |
| Phase 4 | 4-6h | | | |
| Phase 5 | 6-8h | | | |
| Phase 6 | 1-2h | | | |
| **Total** | **23-33h** | | | |
---
## Commit Log
Track commits for easy rollback:
| Date | Phase | Providers | Commit Hash | Notes |
|------|-------|-----------|-------------|-------|
| | | | | |
---
## Status Legend
- ⬜ Not Started
- 🔄 In Progress
- ✅ Complete
- ⚠️ Blocked
- ❌ Failed/Rolled Back
---
## Quick Commands Reference
```bash
# Start working
git status
flutter pub get
dart run build_runner watch --delete-conflicting-outputs
# After migration
flutter analyze && dart run custom_lint && flutter test
# Find usages
grep -r "providerName" lib/ --exclude="*.g.dart" | wc -l
# Commit
git add .
git commit -m "refactor: migrate providerName to @riverpod"
```
---
**Remember:**
1. ✅ Test after each migration
2. ✅ Commit frequently
3. ✅ Take breaks between complex providers
4. ✅ Ask for help if stuck
5. ✅ Document any issues or learnings
**Good luck! 🚀**

View File

@@ -1,279 +0,0 @@
# Riverpod 3.0 Quick Start Guide
## Immediate Actions (30 minutes)
### Step 1: Add riverpod_lint (5 minutes)
1. **Update `pubspec.yaml`:**
```bash
cd /Users/cogwheel/Documents/conduit
```
Add to `dev_dependencies` section:
```yaml
dev_dependencies:
# ... existing dependencies ...
riverpod_lint: ^3.0.0
custom_lint: ^0.8.0
```
2. **Install packages:**
```bash
flutter pub get
```
3. **Update `analysis_options.yaml`:**
Add this at the top level (same level as `linter:`):
```yaml
analyzer:
plugins:
- custom_lint
```
Full file should look like:
```yaml
include: package:flutter_lints/flutter.yaml
analyzer:
plugins:
- custom_lint
linter:
rules:
avoid_print: true
```
4. **Run the linter:**
```bash
dart run custom_lint
```
This will show Riverpod-specific issues if any exist.
---
### Step 2: Fix Any Linter Issues (10 minutes)
The linter will identify issues like:
- ❌ Using `ref` outside of widgets/providers
- ❌ Missing `ref.mounted` checks
- ❌ Incorrect provider usage patterns
**Example Fix:**
If you see: `"ref should not be used outside of a widget/provider"`
```dart
// ❌ Bad
class MyService {
void doSomething(WidgetRef ref) { // ref as parameter
ref.read(someProvider);
}
}
// ✅ Good
@riverpod
class MyService extends _$MyService {
@override
void build() {}
void doSomething() {
ref.read(someProvider); // ref is available in Notifier
}
}
```
---
### Step 3: Update AGENTS.md (5 minutes)
Replace the state management section in `AGENTS.md`:
**Find (around line 166):**
```markdown
### State Management
* **Built-in Solutions:** Prefer Flutter's built-in state management solutions.
Do not use a third-party package unless explicitly requested.
```
**Replace with:**
```markdown
### State Management
* **Riverpod 3.0:** This project uses Riverpod 3.0 for state management.
* **Code Generation:** Always use `@riverpod` annotation with code generation
for new providers. See existing examples in `lib/core/providers/`.
* **Notifier Classes:** Use `Notifier` and `AsyncNotifier` for mutable state:
```dart
@riverpod
class Counter extends _$Counter {
@override
int build() => 0;
void increment() => state++;
}
```
* **Provider Functions:** Use `@riverpod` functions for computed/derived state:
```dart
@riverpod
int doubled(DoubledRef ref) {
final count = ref.watch(counterProvider);
return count * 2;
}
```
* **Keep Alive:** Use `@Riverpod(keepAlive: true)` for singletons:
```dart
@Riverpod(keepAlive: true)
class AuthManager extends _$AuthManager { ... }
```
* **Async Safety:** Always check `ref.mounted` before state updates in async ops:
```dart
Future<void> loadData() async {
final data = await fetchData();
if (!ref.mounted) return; // ✅ Prevent updates after disposal
state = data;
}
```
* **Automatic Retry:** Providers automatically retry on failure with exponential
backoff. Customize if needed:
```dart
@riverpod
Future<Data> myData(MyDataRef ref) async {
ref.onDispose(() {
// Cleanup
});
return await fetchData();
}
```
* **Lint Rules:** Use `custom_lint` with `riverpod_lint` to catch common mistakes.
Run `dart run custom_lint` before committing.
```
---
## Validation (10 minutes)
### 1. Run All Checks
```bash
# Code generation (if needed)
dart run build_runner build --delete-conflicting-outputs
# Custom lint
dart run custom_lint
# Standard analysis
flutter analyze
# Tests
flutter test
```
### 2. Expected Results
All should pass ✅ without new errors. You may see some warnings from `riverpod_lint` which are informational.
### 3. Common Warnings and Fixes
#### Warning: "Provider could use autoDispose"
```dart
// Current
@riverpod
Future<Data> myData(MyDataRef ref) async {
return await fetch();
}
// Suggested (if data is short-lived)
@riverpod
Future<Data> myData(MyDataRef ref) async {
ref.cacheFor(const Duration(minutes: 5)); // Auto-dispose after 5 min
return await fetch();
}
```
#### Warning: "Missing ref.mounted check"
```dart
// Current
Future<void> save() async {
await someAsyncOp();
state = newValue; // ⚠️ Might be disposed
}
// Fixed
Future<void> save() async {
await someAsyncOp();
if (!ref.mounted) return; // ✅
state = newValue;
}
```
---
## Next Steps (Optional)
After completing the quick start, you can:
1. **Read the full analysis:** See `RIVERPOD_3_ANALYSIS.md`
2. **Start migration:** Follow Phase 2 in the analysis document
3. **Add provider docs:** Document provider purposes with dartdoc
---
## Troubleshooting
### Issue: `custom_lint` not found
```bash
# Reinstall
flutter pub get
flutter pub global activate custom_lint
```
### Issue: Analysis takes too long
```bash
# Restart Dart analysis server
# In VS Code: Cmd+Shift+P -> "Dart: Restart Analysis Server"
# In Android Studio: File -> Invalidate Caches / Restart
```
### Issue: Generated files out of sync
```bash
# Clean and rebuild
flutter clean
flutter pub get
dart run build_runner build --delete-conflicting-outputs
```
---
## Benefits You'll See Immediately
After adding `riverpod_lint`:
**Compile-time safety** - Catch errors before runtime
**Better autocomplete** - IDE knows provider types
**Quick fixes** - Automatic solutions for common issues
**Consistency checks** - Enforced best practices
**Refactoring confidence** - Compiler catches all usages
---
## Questions?
Refer to:
- Full analysis: `RIVERPOD_3_ANALYSIS.md`
- Official docs: https://riverpod.dev
- Linter docs: https://riverpod.dev/docs/concepts/about_riverpod_lint

View File

@@ -1,327 +0,0 @@
# Riverpod 3.0 Review - Executive Summary
## Quick Assessment
**Current State:****Well-Aligned with Riverpod 3.0**
**Grade:** B+ (85/100)
**Recommendation:** Implement Priority 1 changes immediately, schedule Priority 2-3 for next sprint
---
## Three Key Documents
1. **`RIVERPOD_3_ANALYSIS.md`** - Full technical analysis with examples
2. **`RIVERPOD_QUICKSTART.md`** - 30-minute setup guide for immediate improvements
3. **`docs/riverpod_migration_example.md`** - Detailed migration examples with code
---
## What's Working Well ✅
1. **Already using Riverpod 3.0** - Latest packages installed
2. **No legacy providers** - No `StateProvider`, `StateNotifierProvider`, or `ChangeNotifierProvider`
3. **Code generation in use** - `@Riverpod` annotation used for complex providers
4. **Modern patterns** - `Notifier`, `AsyncNotifier`, and proper lifecycle management
5. **Safety checks** - `ref.mounted` used in async operations
6. **Keep alive** - Proper singleton management with `@Riverpod(keepAlive: true)`
---
## What Needs Improvement ⚠️
### Priority 1: Critical (30 minutes, low risk)
**Add `riverpod_lint` for compile-time safety**
```bash
# 1. Update pubspec.yaml
flutter pub add --dev riverpod_lint custom_lint
# 2. Update analysis_options.yaml
# Add: analyzer.plugins: - custom_lint
# 3. Run
dart run custom_lint
flutter analyze
```
**Impact:** Catch Riverpod mistakes at compile-time
**Effort:** 30 minutes
**Risk:** 🟢 None
### Priority 2: Important (1-2 weeks, medium risk)
**Standardize on code generation**
- Convert ~30-40 manual `NotifierProvider` declarations to `@riverpod`
- Benefits: Consistency, less boilerplate, better IDE support
- See `docs/riverpod_migration_example.md` for step-by-step guide
**Impact:** Improved maintainability and consistency
**Effort:** 16-24 hours
**Risk:** 🟡 Medium (requires testing)
### Priority 3: Nice-to-have (optional)
- Optimize `FutureProvider.family` patterns
- Improve `AsyncValue` handling (use `when` instead of `maybeWhen`)
- Add provider documentation
---
## Immediate Action Items
### Today (30 minutes)
1.**Add linter packages:**
```bash
cd /Users/cogwheel/Documents/conduit
flutter pub add --dev riverpod_lint custom_lint
```
2. ✅ **Update analysis_options.yaml:**
```yaml
analyzer:
plugins:
- custom_lint
```
3. ✅ **Run checks:**
```bash
dart run custom_lint
flutter analyze
```
4. ✅ **Update AGENTS.md:**
- Replace state management section with Riverpod-specific guidelines
- See `RIVERPOD_QUICKSTART.md` for exact text
### This Week (2-3 hours)
1. ⚠️ **Fix any issues found by `riverpod_lint`**
- Add missing `ref.mounted` checks
- Fix incorrect provider usage
2. ⚠️ **Document providers:**
- Add dartdoc comments to all providers
- Explain purpose and usage
### Next Sprint (16-24 hours)
1. 🔵 **Migrate simple providers:**
- Start with leaf nodes (no dependents)
- Use `docs/riverpod_migration_example.md` as guide
- Test thoroughly after each migration
2. 🔵 **Update tests:**
- Verify all tests pass after migration
- Add new tests where coverage is lacking
---
## Files to Modify
### Immediate Changes (Priority 1)
- ✅ `pubspec.yaml` - Add `riverpod_lint` and `custom_lint`
- ✅ `analysis_options.yaml` - Add custom_lint plugin
- ✅ `AGENTS.md` - Update state management section
### Future Changes (Priority 2)
- ⚠️ `lib/core/providers/app_providers.dart` - ~15 providers to migrate
- ⚠️ `lib/features/chat/providers/chat_providers.dart` - ~10 providers to migrate
- ⚠️ `lib/features/auth/providers/unified_auth_providers.dart` - Review AsyncValue usage
- ⚠️ Other provider files across features
---
## Expected Benefits
### Short-term (after Priority 1)
- ✅ Catch errors at compile-time instead of runtime
- ✅ Better IDE autocomplete and navigation
- ✅ Automatic quick-fixes for common mistakes
- ✅ Enforced best practices
### Long-term (after Priority 2)
- ✅ Consistent codebase (easier onboarding)
- ✅ Less boilerplate (~20% reduction)
- ✅ Better refactoring support
- ✅ Easier to add features (family, autoDispose)
- ✅ Improved developer experience
---
## Risk Assessment
### Priority 1 Changes
**Risk:** 🟢 **Low**
- Adding linter has no runtime impact
- Only improves static analysis
- Can be reverted easily if issues arise
### Priority 2 Changes
**Risk:** 🟡 **Medium**
- Requires updating provider usage across codebase
- Needs thorough testing
- Should be done incrementally
- Can be rolled back per-provider if needed
**Mitigation:**
- Migrate one provider at a time
- Run full test suite after each migration
- Use feature flags for risky changes
- Keep old provider as deprecated alias during transition
---
## Performance Impact
### Build Time
- **Before:** ~30-45 seconds (clean build)
- **After:** ~35-50 seconds (clean build)
- **Impact:** +5-10 seconds due to code generation
- **Mitigation:** Use `watch` mode during development
### Runtime Performance
- **Impact:** Neutral to slightly positive
- Code generation produces optimized code
- Better tree-shaking with generated providers
- No additional runtime dependencies
### Developer Experience
- **Before:** Manual provider declarations, occasional mistakes
- **After:** Auto-generated providers, compile-time safety
- **Impact:** ✅ Significantly better
---
## Testing Strategy
### Before Each Change
```bash
# 1. Backup
git checkout -b riverpod-migration-backup
# 2. Run tests
flutter test
# 3. Verify app works
flutter run --release
```
### After Each Change
```bash
# 1. Regenerate code
dart run build_runner build --delete-conflicting-outputs
# 2. Run linter
dart run custom_lint
# 3. Analyze
flutter analyze
# 4. Test
flutter test
# 5. Manual testing
flutter run
```
---
## Success Metrics
Track these metrics before and after migration:
1. **Code coverage:** Should remain same or improve
2. **Build time:** May increase slightly (acceptable)
3. **Lines of code:** Should decrease by ~10-20%
4. **Linter warnings:** Should decrease significantly
5. **Developer velocity:** Should improve after learning curve
---
## Support & Resources
### Documentation
- 📄 Full analysis: `RIVERPOD_3_ANALYSIS.md`
- 🚀 Quick start: `RIVERPOD_QUICKSTART.md`
- 📝 Examples: `docs/riverpod_migration_example.md`
### External Resources
- [Official Riverpod Docs](https://riverpod.dev)
- [Migration Guide](https://riverpod.dev/docs/3.0_migration)
- [Riverpod Lint](https://riverpod.dev/docs/concepts/about_riverpod_lint)
### Questions?
Common questions answered in the full documentation:
- Q: Will this break existing code?
- A: No for Priority 1, minimal risk for Priority 2 with proper testing
- Q: How long will migration take?
- A: 30 min for Priority 1, 16-24 hours for Priority 2 (can be spread out)
- Q: What if we find issues?
- A: Each provider can be rolled back independently
- Q: Do we need to migrate everything at once?
- A: No! Can be done incrementally, one provider at a time
---
## Recommendation
### Immediate (This Week)
✅ **DO:** Implement Priority 1 changes
- Low risk, high reward
- 30 minutes of work
- Immediate benefits
### Short-term (Next Sprint)
⚠️ **CONSIDER:** Start Priority 2 migration
- Medium risk, high reward
- Plan for 16-24 hours over 2-3 weeks
- Migrate incrementally
### Long-term (Future Sprints)
🔵 **OPTIONAL:** Priority 3 optimizations
- Low risk, medium reward
- Nice-to-have improvements
- Can be done as time permits
---
## Conclusion
The Conduit project is **already using Riverpod 3.0 correctly** for the most part. The main improvements are:
1. **Add static analysis** (`riverpod_lint`) for compile-time safety
2. **Standardize on code generation** for consistency
3. **Optimize patterns** where applicable
The migration can be done **incrementally with minimal risk**. Priority 1 changes should be implemented immediately (30 minutes), while Priority 2 can be planned for the next sprint.
**Overall assessment:** 🟢 Good foundation, ready for optimization
---
*Last updated: September 30, 2025*
*Codebase version: 1.1.6+20*

View File

@@ -1,474 +0,0 @@
# Riverpod Migration Example
## Example: Migrating SearchQueryNotifier
This example shows step-by-step how to migrate a simple provider from manual declaration to code generation.
---
## Current Code (Manual NotifierProvider)
**File:** `lib/core/providers/app_providers.dart` (lines ~1200-1209)
```dart
// Manual provider declaration
final searchQueryProvider = NotifierProvider<SearchQueryNotifier, String>(
SearchQueryNotifier.new,
);
class SearchQueryNotifier extends Notifier<String> {
@override
String build() => '';
void set(String query) => state = query;
}
```
**Usage in code:**
```dart
// Reading value
final query = ref.watch(searchQueryProvider);
// Updating value
ref.read(searchQueryProvider.notifier).set('new search');
```
---
## Migrated Code (Code Generation)
**File:** `lib/core/providers/app_providers.dart`
### Step 1: Add annotation and extend generated class
```dart
@riverpod
class SearchQuery extends _$SearchQuery { // Note: Class name changes
@override
String build() => '';
void set(String query) => state = query;
}
```
### Step 2: Run build_runner
```bash
dart run build_runner build --delete-conflicting-outputs
```
This generates `app_providers.g.dart` with:
```dart
// GENERATED CODE - DO NOT MODIFY BY HAND
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$searchQueryHash() => r'...';
/// See also [SearchQuery].
@ProviderFor(SearchQuery)
final searchQueryProvider = AutoDisposeNotifierProvider<SearchQuery, String>.internal(
SearchQuery.new,
name: r'searchQueryProvider',
debugGetCreateSourceHash: _$searchQueryHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$SearchQuery = AutoDisposeNotifier<String>;
```
### Step 3: Update imports (if needed)
No changes needed! The provider name stays the same: `searchQueryProvider`
### Step 4: Usage remains identical
```dart
// Reading value - NO CHANGE
final query = ref.watch(searchQueryProvider);
// Updating value - NO CHANGE
ref.read(searchQueryProvider.notifier).set('new search');
```
---
## Benefits of Migration
### Before (Manual)
```dart
// 8 lines of boilerplate
final searchQueryProvider = NotifierProvider<SearchQueryNotifier, String>(
SearchQueryNotifier.new,
);
class SearchQueryNotifier extends Notifier<String> {
@override
String build() => '';
void set(String query) => state = query;
}
```
**Issues:**
- ❌ More verbose
- ❌ Need to manually create provider variable
- ❌ Easy to forget to update provider declaration when class changes
- ❌ No automatic dependency tracking
### After (Code Generation)
```dart
// 6 lines, cleaner
@riverpod
class SearchQuery extends _$SearchQuery {
@override
String build() => '';
void set(String query) => state = query;
}
```
**Benefits:**
- ✅ Less boilerplate
- ✅ Provider auto-generated
- ✅ Type-safe
- ✅ Better IDE support
- ✅ Automatic dependency tracking
- ✅ Easier to add `family` or modifiers later
---
## More Complex Example: ThemeModeNotifier
### Current Code (Manual)
```dart
final themeModeProvider = NotifierProvider<ThemeModeNotifier, ThemeMode>(
ThemeModeNotifier.new,
);
class ThemeModeNotifier extends Notifier<ThemeMode> {
late final OptimizedStorageService _storage;
@override
ThemeMode build() {
_storage = ref.watch(optimizedStorageServiceProvider);
final storedMode = _storage.getThemeMode();
if (storedMode != null) {
return ThemeMode.values.firstWhere(
(e) => e.toString() == storedMode,
orElse: () => ThemeMode.system,
);
}
return ThemeMode.system;
}
void setTheme(ThemeMode mode) {
state = mode;
_storage.setThemeMode(mode.toString());
}
}
```
### Migrated Code (Code Generation)
```dart
@riverpod
class AppThemeMode extends _$AppThemeMode { // Renamed to avoid conflict with ThemeMode enum
late final OptimizedStorageService _storage;
@override
ThemeMode build() {
_storage = ref.watch(optimizedStorageServiceProvider);
final storedMode = _storage.getThemeMode();
if (storedMode != null) {
return ThemeMode.values.firstWhere(
(e) => e.toString() == storedMode,
orElse: () => ThemeMode.system,
);
}
return ThemeMode.system;
}
void setTheme(ThemeMode mode) {
state = mode;
_storage.setThemeMode(mode.toString());
}
}
// Generated provider will be: appThemeModeProvider
```
**Important:** Class renamed from `ThemeModeNotifier` to `AppThemeMode` to avoid name conflict with the `ThemeMode` enum from Flutter.
### Update Usage
```dart
// Before
final mode = ref.watch(themeModeProvider);
ref.read(themeModeProvider.notifier).setTheme(ThemeMode.dark);
// After
final mode = ref.watch(appThemeModeProvider);
ref.read(appThemeModeProvider.notifier).setTheme(ThemeMode.dark);
```
**Migration tool can help:**
```bash
# Find all usages
grep -r "themeModeProvider" lib/
# Replace with IDE refactoring or:
find lib -type f -name "*.dart" -exec sed -i '' 's/themeModeProvider/appThemeModeProvider/g' {} +
```
---
## Provider Function Example
### FutureProvider to @riverpod function
**Before:**
```dart
final serverConfigsProvider = FutureProvider<List<ServerConfig>>((ref) async {
final storage = ref.watch(optimizedStorageServiceProvider);
return storage.getServerConfigs();
});
```
**After:**
```dart
@riverpod
Future<List<ServerConfig>> serverConfigs(ServerConfigsRef ref) async {
final storage = ref.watch(optimizedStorageServiceProvider);
return storage.getServerConfigs();
}
// Generated provider name: serverConfigsProvider (same!)
```
**Usage - NO CHANGE:**
```dart
final configs = ref.watch(serverConfigsProvider);
// or
final configs = await ref.read(serverConfigsProvider.future);
```
---
## Family Provider Example
### Before (Manual)
```dart
final loadConversationProvider = FutureProvider.family<Conversation, String>((
ref,
conversationId,
) async {
final api = ref.watch(apiServiceProvider);
if (api == null) {
throw Exception('No API service available');
}
return await api.getConversation(conversationId);
});
```
### After (Code Generation)
```dart
@riverpod
Future<Conversation> loadConversation(
LoadConversationRef ref,
String conversationId, // Family parameter
) async {
final api = ref.watch(apiServiceProvider);
if (api == null) {
throw Exception('No API service available');
}
return await api.getConversation(conversationId);
}
// Usage stays the same!
// ref.watch(loadConversationProvider(conversationId))
```
**Benefits:**
- ✅ Automatic `.family` modifier handling
- ✅ Type-safe parameters
- ✅ Better parameter completion in IDE
- ✅ Can add multiple parameters easily
---
## Keep Alive Example
### Before
```dart
@Riverpod(keepAlive: true)
class AuthStateManager extends _$AuthStateManager {
// ...
}
```
### After
**No change needed!** Already using code generation correctly. ✅
---
## Migration Checklist
For each provider to migrate:
- [ ] Identify the provider type (Notifier, AsyncNotifier, function)
- [ ] Check for name conflicts (e.g., `ThemeModeNotifier` vs `ThemeMode`)
- [ ] Add `@riverpod` annotation
- [ ] Change class to extend `_$ClassName`
- [ ] Remove manual provider declaration
- [ ] Run `dart run build_runner build`
- [ ] Update all usages (IDE refactoring recommended)
- [ ] Test the provider functionality
- [ ] Commit the change
---
## Testing After Migration
### Unit Test Example
**Before:**
```dart
test('searchQuery updates correctly', () {
final container = ProviderContainer();
expect(container.read(searchQueryProvider), '');
container.read(searchQueryProvider.notifier).set('test');
expect(container.read(searchQueryProvider), 'test');
});
```
**After:**
```dart
test('searchQuery updates correctly', () {
final container = ProviderContainer();
// Same test code - no changes needed!
expect(container.read(searchQueryProvider), '');
container.read(searchQueryProvider.notifier).set('test');
expect(container.read(searchQueryProvider), 'test');
});
```
Tests remain identical! ✅
---
## Common Pitfalls
### 1. Class Name Conflicts
**Problem:**
```dart
@riverpod
class ThemeMode extends _$ThemeMode { // ❌ Conflicts with Flutter's ThemeMode
// ...
}
```
**Solution:**
```dart
@riverpod
class AppThemeMode extends _$AppThemeMode { // ✅ Unique name
// ...
}
```
### 2. Forgetting to Run Build Runner
**Problem:** After adding `@riverpod`, code doesn't compile.
```
Error: The getter '_$SearchQuery' isn't defined for the class 'SearchQuery'.
```
**Solution:**
```bash
dart run build_runner build --delete-conflicting-outputs
```
### 3. Mixing Manual and Generated Providers
**Problem:** Some providers use `@riverpod`, others use manual `NotifierProvider`.
**Solution:** Be consistent! Migrate all providers in a file together to maintain consistency.
---
## IDE Support
### VS Code
Add to `.vscode/tasks.json`:
```json
{
"version": "2.0.0",
"tasks": [
{
"label": "build_runner watch",
"type": "shell",
"command": "dart run build_runner watch --delete-conflicting-outputs",
"isBackground": true,
"problemMatcher": []
}
]
}
```
Run with `Cmd+Shift+P` → "Tasks: Run Task" → "build_runner watch"
### Android Studio / IntelliJ
1. Run → Edit Configurations
2. Add new "Shell Script" configuration
3. Script text: `dart run build_runner watch --delete-conflicting-outputs`
4. Working directory: `$ProjectFileDir$`
---
## Summary
**Effort per provider:** ~5-10 minutes
**Risk level:** 🟢 Low (tests verify behavior)
**Benefit:** High (consistency, maintainability, developer experience)
**Recommended order:**
1. Start with simple `Notifier` classes (like `SearchQueryNotifier`)
2. Move to `FutureProvider` functions
3. Then tackle complex `AsyncNotifier` classes
4. Keep `@Riverpod(keepAlive: true)` providers for last (already correct)
**Total providers to migrate:** ~30-40 (based on codebase analysis)
**Estimated total time:** 5-8 hours spread across multiple sessions

View File

@@ -1,161 +1,32 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:markdown_widget/markdown_widget.dart';
import 'package:flutter_highlight/themes/atom-one-dark.dart';
import 'package:flutter_highlight/themes/atom-one-light.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:conduit/shared/theme/theme_extensions.dart';
import 'package:conduit/l10n/app_localizations.dart';
/// Configuration for GptMarkdown styling
class ConduitMarkdownStyleConfig {
final TextStyle textStyle;
const ConduitMarkdownStyleConfig({required this.textStyle});
}
class ConduitMarkdownConfig {
static MarkdownConfig getConfig({
required bool isDark,
static ConduitMarkdownStyleConfig getStyleConfig({
required BuildContext context,
bool isStreaming = false,
}) {
final theme = context.conduitTheme;
return (isDark ? MarkdownConfig.darkConfig : MarkdownConfig.defaultConfig).copy(
configs: [
// Code block config
PreConfig(
theme: isDark ? atomOneDarkTheme : atomOneLightTheme,
decoration: BoxDecoration(
color: theme.surfaceBackground.withValues(alpha: 0.06),
borderRadius: BorderRadius.circular(AppBorderRadius.md),
border: Border.all(
color: theme.dividerColor.withValues(alpha: 0.7),
width: BorderWidth.thin,
),
),
padding: const EdgeInsets.all(Spacing.md),
textStyle: AppTypography.chatCodeStyle,
wrapper: (child, text, language) => CodeBlockWrapper(
code: text,
language: language,
theme: theme,
child: child,
),
),
// Link config
LinkConfig(
style: TextStyle(
color: theme.buttonPrimary,
decoration: TextDecoration.none,
),
onTap: (url) async {
if (await canLaunchUrlString(url)) {
launchUrlString(url, mode: LaunchMode.inAppWebView);
}
},
),
// Image config - optimized for mobile with support for base64 and network images
ImgConfig(
builder: (url, attributes) {
// Check if it's a base64 data URL
if (url.startsWith('data:')) {
return _buildBase64Image(url, context, theme);
}
// Network image
return CachedNetworkImage(
imageUrl: url,
placeholder: (context, url) => Container(
height: 200,
decoration: BoxDecoration(
color: theme.surfaceBackground.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(AppBorderRadius.md),
),
child: Center(
child: CircularProgressIndicator(
color: theme.loadingIndicator,
strokeWidth: 2,
),
),
),
errorWidget: (context, url, error) => Container(
height: 100,
decoration: BoxDecoration(
color: theme.surfaceBackground.withValues(alpha: 0.3),
borderRadius: BorderRadius.circular(AppBorderRadius.md),
border: Border.all(
color: theme.error.withValues(alpha: 0.3),
width: BorderWidth.thin,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.broken_image_outlined,
color: theme.error,
size: 32,
),
const SizedBox(height: Spacing.xs),
Text(
AppLocalizations.of(context)!.failedToLoadImage(''),
style: TextStyle(color: theme.error, fontSize: 12),
),
],
),
),
);
},
),
// Table config - mobile responsive
TableConfig(
wrapper: (table) => SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: table,
),
),
// Paragraphs — improve readability and spacing on mobile
PConfig(
textStyle: AppTypography.chatMessageStyle.copyWith(
color: theme.textPrimary,
height: 1.45,
),
),
// Headers
H1Config(
style: AppTypography.headlineLargeStyle.copyWith(
color: theme.textPrimary,
height: 1.25,
),
),
H2Config(
style: AppTypography.headlineMediumStyle.copyWith(
color: theme.textPrimary,
height: 1.25,
),
),
H3Config(
style: AppTypography.headlineSmallStyle.copyWith(
color: theme.textPrimary,
height: 1.3,
),
),
// Blockquote — keep default rendering for compatibility
BlockquoteConfig(),
// Code inline
CodeConfig(
style: AppTypography.chatCodeStyle.copyWith(
color: theme.textPrimary,
backgroundColor: theme.surfaceBackground.withValues(alpha: 0.1),
),
),
],
return ConduitMarkdownStyleConfig(
textStyle: AppTypography.chatMessageStyle.copyWith(
color: theme.textPrimary,
height: 1.45,
),
);
}
static Widget _buildBase64Image(
/// Legacy method for base64 image support (if needed elsewhere)
static Widget buildBase64Image(
String dataUrl,
BuildContext context,
ConduitThemeExtension theme,
@@ -221,6 +92,52 @@ class ConduitMarkdownConfig {
);
}
}
/// Build a cached network image widget
static Widget buildNetworkImage(
String url,
BuildContext context,
ConduitThemeExtension theme,
) {
return CachedNetworkImage(
imageUrl: url,
placeholder: (context, url) => Container(
height: 200,
decoration: BoxDecoration(
color: theme.surfaceBackground.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(AppBorderRadius.md),
),
child: Center(
child: CircularProgressIndicator(
color: theme.loadingIndicator,
strokeWidth: 2,
),
),
),
errorWidget: (context, url, error) => Container(
height: 100,
decoration: BoxDecoration(
color: theme.surfaceBackground.withValues(alpha: 0.3),
borderRadius: BorderRadius.circular(AppBorderRadius.md),
border: Border.all(
color: theme.error.withValues(alpha: 0.3),
width: BorderWidth.thin,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.broken_image_outlined, color: theme.error, size: 32),
const SizedBox(height: Spacing.xs),
Text(
AppLocalizations.of(context)!.failedToLoadImage(''),
style: TextStyle(color: theme.error, fontSize: 12),
),
],
),
),
);
}
}
/// Custom wrapper for code blocks with copy functionality

View File

@@ -1,22 +1,18 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:markdown_widget/markdown_widget.dart';
import 'package:gpt_markdown/gpt_markdown.dart';
import 'package:conduit/shared/widgets/markdown/markdown_config.dart';
class StreamingMarkdownWidget extends StatefulWidget {
final Stream<String>? contentStream;
final String? staticContent;
final bool isStreaming;
final ScrollController? scrollController;
final EdgeInsetsGeometry? padding;
const StreamingMarkdownWidget({
super.key,
this.contentStream,
this.staticContent,
required this.isStreaming,
this.scrollController,
this.padding,
});
@override
@@ -110,36 +106,14 @@ class _StreamingMarkdownWidgetState extends State<StreamingMarkdownWidget> {
@override
Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
final config = ConduitMarkdownConfig.getConfig(
isDark: isDark,
context: context,
isStreaming: widget.isStreaming,
);
final config = ConduitMarkdownConfig.getStyleConfig(context: context);
if (_renderedContent.isEmpty) {
return const SizedBox.shrink();
}
if (widget.isStreaming && _renderedContent.isNotEmpty) {
// Use MarkdownBlock for streaming - it's optimized for live updates
return MarkdownBlock(
data: _renderedContent,
config: config,
selectable: true,
);
} else {
// Use MarkdownWidget for completed messages
// This provides better interactivity and selection
return MarkdownWidget(
data: _renderedContent,
config: config,
selectable: true,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
);
}
// GptMarkdown handles both streaming and static content elegantly
return GptMarkdown(_renderedContent, style: config.textStyle);
}
@override
@@ -152,15 +126,10 @@ class _StreamingMarkdownWidgetState extends State<StreamingMarkdownWidget> {
/// Extension to provide easy access to streaming markdown
extension StreamingMarkdownExtension on String {
Widget toMarkdown({
required BuildContext context,
bool isStreaming = false,
EdgeInsetsGeometry? padding,
}) {
Widget toMarkdown({required BuildContext context, bool isStreaming = false}) {
return StreamingMarkdownWidget(
staticContent: this,
isStreaming: isStreaming,
padding: padding,
);
}
}
@@ -169,28 +138,18 @@ extension StreamingMarkdownExtension on String {
class MarkdownWithLoading extends StatelessWidget {
final String? content;
final bool isLoading;
final EdgeInsetsGeometry? padding;
const MarkdownWithLoading({
super.key,
this.content,
required this.isLoading,
this.padding,
});
const MarkdownWithLoading({super.key, this.content, required this.isLoading});
@override
Widget build(BuildContext context) {
if (isLoading && (content == null || content!.isEmpty)) {
return Container(
padding: padding ?? const EdgeInsets.all(16),
child: const Center(child: CircularProgressIndicator()),
);
return const Center(child: CircularProgressIndicator());
}
return StreamingMarkdownWidget(
staticContent: content ?? '',
isStreaming: isLoading,
padding: padding,
);
}
}

View File

@@ -430,14 +430,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.4.1"
flutter_highlight:
dependency: "direct main"
description:
name: flutter_highlight
sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
flutter_lints:
dependency: "direct dev"
description:
@@ -451,6 +443,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_math_fork:
dependency: transitive
description:
name: flutter_math_fork
sha256: "6d5f2f1aa57ae539ffb0a04bb39d2da67af74601d685a161aff7ce5bda5fa407"
url: "https://pub.dev"
source: hosted
version: "0.7.4"
flutter_native_splash:
dependency: "direct dev"
description:
@@ -531,6 +531,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.1.3"
flutter_svg:
dependency: transitive
description:
name: flutter_svg
sha256: b9c2ad5872518a27507ab432d1fb97e8813b05f0fc693f9d40fad06d073e0678
url: "https://pub.dev"
source: hosted
version: "2.2.1"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -589,6 +597,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "14.8.1"
gpt_markdown:
dependency: "direct main"
description:
name: gpt_markdown
sha256: "8174983f2ed7d8576d25810913e3afe3f8ffdaa3172c0c823b7cfc289b67f380"
url: "https://pub.dev"
source: hosted
version: "1.1.4"
graphs:
dependency: transitive
description:
@@ -597,14 +613,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.2"
highlight:
dependency: transitive
description:
name: highlight
sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
hotreloader:
dependency: transitive
description:
@@ -797,22 +805,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
markdown:
dependency: transitive
description:
name: markdown
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
url: "https://pub.dev"
source: hosted
version: "7.3.0"
markdown_widget:
dependency: "direct main"
description:
name: markdown_widget
sha256: b52c13d3ee4d0e60c812e15b0593f142a3b8a2003cde1babb271d001a1dbdc1c
url: "https://pub.dev"
source: hosted
version: "2.3.2+8"
matcher:
dependency: transitive
description:
@@ -853,6 +845,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.5.0"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
node_preamble:
dependency: transitive
description:
@@ -901,6 +901,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.1"
path_parsing:
dependency: transitive
description:
name: path_parsing
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
path_provider:
dependency: "direct main"
description:
@@ -989,6 +997,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.0.3"
provider:
dependency: transitive
description:
name: provider
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
url: "https://pub.dev"
source: hosted
version: "6.1.5+1"
pub_semver:
dependency: transitive
description:
@@ -1117,14 +1133,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.28.0"
scroll_to_index:
dependency: transitive
description:
name: scroll_to_index
sha256: b707546e7500d9f070d63e5acf74fd437ec7eeeb68d3412ef7b0afada0b4f176
url: "https://pub.dev"
source: hosted
version: "3.0.1"
share_handler:
dependency: "direct main"
description:
@@ -1482,6 +1490,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
tuple:
dependency: transitive
description:
name: tuple
sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
url: "https://pub.dev"
source: hosted
version: "2.0.2"
typed_data:
dependency: transitive
description:
@@ -1570,6 +1586,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.5.1"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6
url: "https://pub.dev"
source: hosted
version: "1.1.19"
vector_graphics_codec:
dependency: transitive
description:
name: vector_graphics_codec
sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
url: "https://pub.dev"
source: hosted
version: "1.1.13"
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: d354a7ec6931e6047785f4db12a1f61ec3d43b207fc0790f863818543f8ff0dc
url: "https://pub.dev"
source: hosted
version: "1.1.19"
vector_math:
dependency: transitive
description:
@@ -1578,14 +1618,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.0"
visibility_detector:
dependency: transitive
description:
name: visibility_detector
sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420
url: "https://pub.dev"
source: hosted
version: "0.4.0+2"
vm_service:
dependency: transitive
description:

View File

@@ -28,8 +28,7 @@ dependencies:
shared_preferences: ^2.3.2
# UI Components - Enhanced Markdown
markdown_widget: ^2.3.2+8
flutter_highlight: ^0.7.0
gpt_markdown: ^1.1.4
cached_network_image: ^3.3.1
socket_io_client: ^3.1.2
yaml: ^3.1.2