diff --git a/packages/wyatt_architecture/lib/src/domain/usecases/usecase.dart b/packages/wyatt_architecture/lib/src/domain/usecases/usecase.dart
index 3e2a39f4..ee6a2c26 100644
--- a/packages/wyatt_architecture/lib/src/domain/usecases/usecase.dart
+++ b/packages/wyatt_architecture/lib/src/domain/usecases/usecase.dart
@@ -1,27 +1,83 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
-//
+//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
-//
+//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
+//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+import 'dart:async';
+
import 'package:wyatt_architecture/src/core/exceptions/exceptions.dart';
+import 'package:wyatt_architecture/src/domain/usecases/observers.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
-typedef FutureResult = Future>;
+typedef FutureOrResult = FutureOr>;
typedef StreamResult = Stream>;
-typedef Res = Result;
-// ignore: one_member_abstracts
-abstract class UseCase {
- FutureResult call(Parameters params);
+/// Abstract class of a use case
+abstract class BaseUseCase {
+ /// Run use case scenarios
+ ReturnType execute(Parameters parameters);
+
+ /// Private function to implement main scenario
+ /// of your usecase.
+ ReturnType call(Parameters params);
+}
+
+/// Abstract class of a use case that deals specifically
+/// with the response and its state.
+abstract class UseCase
+ extends BaseUseCase>
+ with Observer {
+ FutureOr _onSuccess(ReturnType data);
+
+ /// Supports the result of the main scenario and integrates
+ /// some alternative scenarios if necessary.
+ @override
+ FutureOrResult execute(Parameters? parameters) =>
+ Result.tryCatchAsync(
+ () async {
+ await onStart(parameters);
+ final response = await call(parameters);
+ if (response.isErr) {
+ await onError(response.err);
+ } else if (response.isOk && response.ok != null) {
+ await _onSuccess(response.ok as ReturnType);
+ }
+
+ return response.ok!;
+ },
+ (error) => ClientException(
+ error.toString(),
+ ),
+ );
+}
+
+/// Abtstract classic usecase.
+abstract class AsyncUseCase
+ extends UseCase with AsyncObserver {
+ @override
+ FutureOr _onSuccess(ReturnType data) => onComplete(data);
+}
+
+/// Abstract specific usecase bases on streams
+abstract class StreamUseCase
+ extends UseCase>
+ with StreamObserver {
+ @override
+ FutureOr _onSuccess(Stream data) {
+ data.listen(
+ onData,
+ onDone: onDone,
+ );
+ }
}