import 'package:dartz/dartz.dart'; | Custom Either from core/shared/either.dart |
new Dio() inside a DataSource | sl<ApiClient>() |
DataSource returns Either | DataSource throws; Repository maps to Either |
Repository lets DioException escape | Left(ServerFailure.fromDioError(e)) |
catch (_) {} swallows silently | AppLogger.error(..., stackTrace: st) then map |
e.toString() in ServerFailure.message | LocaleKeys.errorUnexpected — never leak internals |
Registering HiveStorageService in sl | Factory-cached per box; instantiate inside LocalDataSource |
emit(...) directly | safeEmit(...) always |
State.error({required String message}) | State.error({required Failure failure}) |
State.navigateToHome() | Derive navigation in the listener, not as state |
Cubit.call(context, ...) / BuildContext in Cubit | Cubit is UI-agnostic |
Navigator.of(context).push(MaterialPageRoute(...)) | NavigationService.push(AppRoute.x, arguments: XArgs(...)) |
arguments: {'id': 12} raw map | Typed XArgs class |
| Route registered in only 1–2 of 3 places | enum + generateRoute + _guardsFor — all three |
Text('Welcome') / Text('مرحبا') | LocaleKeys.welcome.tr(context) |
Colors.white / Colors.black | context.colors.<token> |
TextStyle(fontSize: 16, color: ...) | context.styles.regular16.copyWith(color: ...) |
EdgeInsets.only(left: 16) | EdgeInsetsDirectional.only(start: 16) |
MediaQuery.of(context).size.width | context.screenWidth |
| Inline regex for validation | Validator.validate*(context, v) |
registerSingleton<XCubit> | Cubit → registerFactory |
print(...) / debugPrint(...) / AppLogger.debug | AppLogger.info(msg, tag: 'ClassName') |
@freezed class (Freezed 3.x) | @freezed abstract class |
Editing .g.dart / .freezed.dart | Fix source; wait for build_runner |
Side effects inside builder | Always in listener; builder is pure |
AnimatedDotsLoader.show from builder | Only from listener |
TextEditingController in a StatefulWidget | Declare in Cubit; dispose in close() |
AppBar(...) anywhere | CustomAppBar(...) |
Scaffold or AppBar inside a body widget | Page only |
ListView(children: [...]) for 20+ items | ListView.builder |
Sort / filter large lists in builder | Do it in Cubit before emitting _Loaded |
setState inside BlocConsumer | Split: wrap only the stateful subtree |
| Timers / Streams not disposed | Dispose in close() / dispose() |