3.3 KiB
3.3 KiB
TT-005 — Riverpod Providers & Notifiers
Type: Story
Priority: High
Labels: state-management, riverpod
Depends on: TT-003, TT-004
Blocks: TT-006, TT-007, TT-008, TT-009
Summary
Implement all Riverpod providers and notifiers for each feature. This is the domain/application layer that connects the data layer (repositories) to the presentation layer (screens/widgets).
Providers to implement
Timer Feature
File: lib/features/timer/domain/timer_notifier.dart
@riverpod
class TimerNotifier extends _$TimerNotifier {
@override
TimerState build(); // reads DB for open entry on init
Future<void> start(Project project, {String? note});
Future<void> stop();
Future<void> discard();
void updateNote(String note);
}
- Uses a
dart:async Timer.periodic(1s)while running - On
build(): callstimeEntriesRepository.getActiveEntry()to restore state - See
.ai/features/timer.mdfor full state-machine spec
Projects Feature
File: lib/features/projects/domain/projects_provider.dart
@riverpod
Stream<List<Project>> activeProjects(ActiveProjectsRef ref);
@riverpod
Stream<List<Project>> allProjects(AllProjectsRef ref);
@riverpod
class ProjectsNotifier extends _$ProjectsNotifier {
Future<void> create({required String name, required int colorValue, String? description});
Future<void> update(Project project);
Future<void> archive(int id);
Future<void> delete(int id);
}
Entries Feature
File: lib/features/entries/domain/entries_provider.dart
@riverpod
Stream<List<TimeEntry>> entriesByDateRange(
EntriesByDateRangeRef ref, {required DateTime from, required DateTime to});
@riverpod
class EntriesNotifier extends _$EntriesNotifier {
Future<void> create(TimeEntry entry);
Future<void> update(TimeEntry entry);
Future<void> delete(int id);
}
Reports Feature
File: lib/features/reports/domain/reports_provider.dart
@riverpod
class ReportsNotifier extends _$ReportsNotifier {
@override
ReportData build();
void selectPeriod(ReportPeriod period); // day | week | month
void goToPrevious();
void goToNext();
void filterByProject(int? projectId);
}
@freezed
class ReportData with _$ReportData {
const factory ReportData({
required Duration totalDuration,
required Map<String, Duration> durationByProject,
required List<double> chartValues, // bars for fl_chart
required DateTime periodStart,
required DateTime periodEnd,
}) = _ReportData;
}
Acceptance Criteria
- All providers use
@riverpodannotation (code-gen) TimerNotifier.build()restores running timer from DB on app startTimerNotifierdisposes itsdart:async Timerviaref.onDispose- All providers inject repositories via
ref.watch(xxxRepositoryProvider) - Unit tests for
TimerNotifier(start/stop/discard/restore) - Unit tests for
ProjectsNotifier(CRUD operations)
Files to create
lib/features/timer/domain/timer_notifier.dartlib/features/projects/domain/projects_provider.dartlib/features/entries/domain/entries_provider.dartlib/features/reports/domain/reports_provider.dartlib/features/reports/domain/report_data.darttest/features/timer/timer_notifier_test.darttest/features/projects/projects_notifier_test.dart