Assemble the full stack in Solution:
- record Task(String id, String title, boolean done) (domain)
- interface TaskRepository { void save(Task t); Optional<Task> find(String id); List<Task> all(); }
- static class InMemoryTaskRepository implements TaskRepository
- static class TaskService with constructor (TaskRepository r):
- Task create(String id, String title) — blank title throws
IllegalArgumentException; saves and returns
- Task complete(String id) — missing id throws
NoSuchElementException; marks done and saves
- List<Task> pending() — all not-done tasks (insertion order)
- record TaskView(String id, String title) (DTO)
- static List<TaskView> pendingViews(TaskService s) — the controller
function mapping pending() to views.
Then the test drives the whole graph: repo → service → views.
Difficulty: intermediate