fl-module-scaffold
Scaffolds a new feature module under apps/main/lib/presentation/modules using the bundled module generator
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Scaffolds a new feature module under apps/main/lib/presentation/modules using the bundled module generator
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Behavioral guidelines for Flutter base tasks: clarify ambiguity, keep changes simple and surgical, and define verifiable success criteria before coding.
Reviews UI-layer changes — screens, blocs, widgets, routes — against the template's StateBase + CoreBlocBase + fl_theme conventions
Awareness index of every reusable widget in fl_ui, fl_theme, fl_media, and core's common_widget — name, one-line purpose, when to reach for it instead of writing a new one
Builds the data layer with Freezed DTOs, Retrofit clients, the storage-seam local data manager, and repositories wired through injectable
Teaches and applies Flutter/Dart dependency injection with Injectable + GetIt, grounded in this repo's Clean Architecture and code generation conventions. Use when changing DI wiring, adding BLoCs/use cases/repositories/modules, using @Named/@preResolve/@factoryParam/env registrations, reviewing DI best practices, or setting up DI tests.
Writes unit and widget tests for blocs, repositories, and screens using bloc_test + mocktail
| name | fl-module-scaffold |
| description | Scaffolds a new feature module under apps/main/lib/presentation/modules using the bundled module generator |
| license | MIT |
| metadata | {"audience":"flutter-developers","framework":"flutter","pattern":"clean-architecture"} |
apps/main/.bloc/, views/, route, coordinator.The template ships an interactive generator that emits files matching the project's exact conventions. Always try this first.
make run_module_generator
# Choose: 1) common module 2) listing module 3) detail module
# 4) repository 5) usecase 6) model
Source: tools/module_generator/, templates in tools/module_generator/lib/res/templates/.
| Module type | What it scaffolds | Use for |
|---|---|---|
common module | Bloc + screen + route + coordinator with no list/detail bias | Forms, single-action screens |
listing module | List bloc with items, canLoadMore, refresh+load-more events | Browse/search screens |
detail module | Detail bloc parameterised by Args(initial, id), Get<X>Event | Item detail screens |
repository | Repo + impl in apps/main/lib/data/data_source/ | Wrap a Retrofit client |
usecase | Usecase class in apps/main/lib/domain/usecases/ | Wrap a repository |
model | Freezed model template under core/ or app | DTO between API and UI |
After generating, run make gen_all so freezed/injectable code is emitted, then register the new route.
apps/main/lib/presentation/modules/<feature>/
├── <feature>.dart # Barrel: exports route/bloc/screen (+ coordinator if compound)
├── <feature>_route.dart # IRoute → CustomRouter<Args>
├── <feature>_coordinator.dart # ONLY for compound modules / non-trivial entry — see CONTEXT.md
├── bloc/
│ ├── <feature>_bloc.dart # part directives for event/state/freezed
│ ├── <feature>_event.dart # abstract class + concrete events
│ └── <feature>_state.dart # _StateData (freezed) + state classes + _factories
└── views/
├── <feature>_screen.dart # StatefulWidget → StateBase<>
├── <feature>.action.dart # part of screen — handlers/listeners
└── widgets/ # screen-local widgets (optional)
The module generator omits the coordinator file when the chosen template's source map lacks a coordinator key (see tools/module_generator/lib/generator/module_generator_ext.dart). Simple modules call pushBehavior.push(context, FeatureScreen.routeName) directly; only compound modules and modules with non-trivial entry logic (arg translation, pre-nav guards) keep a coordinator. A one-line pushBehavior.push wrapper is shallow — don't add one.
Domain + data live alongside, not under presentation/:
apps/main/lib/domain/usecases/<feature>/<feature>_usecase.dart
apps/main/lib/data/data_source/<feature>_repository.dart (and *_impl.dart)
Before adding a screen-local widget under views/widgets/, check fl-ui-components — it catalogs every reusable widget already in fl_ui, fl_theme, fl_media, and common_widget. For shared widgets/services, add to core/ instead of apps/main/.
When a feature has more than one screen, do not flatten it into one oversized module or bypass the established presentation structure. Use a parent module that owns the parent barrel, coordinator, and route aggregator; each non-trivial child screen gets its own sub-module with bloc/ and views/.
<feature>/
├── <feature>.dart
├── <feature>_route.dart # aggregates child routes
├── <feature>_coordinator.dart
├── <child_a>/
│ ├── bloc/
│ └── views/
└── <child_b>/
├── bloc/
└── views/
If the user says a flow should follow a named project architecture, apply that architecture directly and ask before choosing a lighter UI structure.
Stick to the names below — _factories, Args, routeName, the part wiring — because other parts of the codebase rely on them.
fl-bloc-pattern.fl-extension-action.fl-route-config.IRoute (e.g. apps/main/lib/presentation/route/route.dart).make gen_all.make run_module_generator first.lib/presentation/modules/<feature>/.StateBase<T> and has a static String routeName.CoreBlocBase<E, S> and is @Injectable().IRoute and wraps the screen in BlocProvider.BuildContext using PushBehavior — added only for compound modules or non-trivial entry logic (see fl-route-config §Coordinator).IRoute.make gen_all run; generated files committed.