Presentation
A Riverpod notifier calls the use case. The note tile does not import Riverpod. Beamer reports the screen.
The page and the notifier live in presentation/features/notes/. The tile lives in ui/note_tile.dart. That split is the point of this track: a feature owns its screen, and a presentational widget owns nothing about Riverpod.
NotesPage watches notesProvider and calls save on the notifier. NoteTile takes a title and a body. The tile file imports Flutter only.
Beamer is the router adapter. presentation/router/notes_location.dart builds the notes page inside ScreenReporter, which calls NotesMonitoring.setScreen when the location is shown. Repeats of the same path and title are dropped once a client exists.
Future<String?> save(String title, String body) async {
try {
await ref.read(saveNoteUseCaseProvider).execute(title: title, body: body);
final notes = await ref.read(listNotesUseCaseProvider).execute();
state = AsyncData(notes);
return null;
} on ValidationFailure catch (error) {
return error.message;
}
}null means the list state was replaced and the page clears the fields. A string means the form shows that message and the list stays as it was. A blank title never reaches the store.
lib/presentation/features/notes/notes_page.dartwatches the provider and draws the formlib/presentation/features/notes/notes_controller.dartcalls the use caseslib/ui/note_tile.darttakes a title and a bodylib/presentation/router/notes_location.dartbuilds the page and reports the screen
Next: Composition root.