orderBy('due_date')->get(); return ApiDataTransformer::snakeToCamel($todos->toArray()); } public function show(string $id) { return Todo::with('type')->findOrFail($id); } public function store(Request $request) { $data = $request->validate([ 'id' => 'nullable|string', 'etag' => 'nullable|string', 'title' => 'required|string', 'description' => 'nullable|string', 'type_id' => 'nullable|exists:todo_types,id', 'url' => 'nullable|url', 'due_date' => 'nullable|date', 'recurring' => 'nullable|string', 'priority' => 'nullable|integer', 'status' => 'nullable|string', 'parent' => 'nullable|string', 'object' => 'nullable|string', ]); $data['id'] = $data['id'] ?? (string) Str::uuid(); $now = now(); $data['created_at'] = $data['created_at'] ?? $now; $data['last_modified'] = $now; $todo = Todo::create($data); return response()->json($todo, 201); } public function update(Request $request, string $id) { $todo = Todo::findOrFail($id); $data = $request->validate([ 'etag' => 'nullable|string', 'title' => 'sometimes|required|string', 'description' => 'nullable|string', 'type_id' => 'nullable|exists:todo_types,id', 'url' => 'nullable|url', 'due_date' => 'nullable|date', 'recurring' => 'nullable|string', 'priority' => 'nullable|integer', 'status' => 'nullable|string', 'parent' => 'nullable|string', 'object' => 'nullable|string', ]); $data['last_modified'] = now(); $todo->update($data); return response()->json($todo); } public function destroy(string $id) { $todo = Todo::findOrFail($id); $todo->delete(); return response()->noContent(); } }