Repository navigation
Seven-stage architectural deepening pass across the template. Drives shallow modules toward real seams, ships a worked end-to-end auth example, and adds the canonical adapter for `RouteProviderInterceptor`. Also introduces `CONTEXT.md` capturing the template's architectural vocabulary.
Full details: #25.
Highlights
- Storage seam. `CoreLocalDataManager` / `LocalDataManager` now own `SharedPreferences` + `FlutterSecureStorage` directly; the pass-through `*PreferencesHelper` layers are gone. Hive runtime pulled (init, re-export, empty marker).
- Auth demo. Replaces the role-picker prototype with a phone + password flow that demonstrates the full data → domain → presentation slice. `MockAuthRemoteSource` is the single swap point for plugging in a real backend. Demo credentials: `0911357924/password1` and `0987654321/password2`.
- `AuthenticationCoordinator.openSignIn` grew a `returnTo` parameter and a pre-nav token guard — short-circuits the form when already authenticated, threads the redirect target back to the screen via the new typed `SigninRouteArgs` (works on native push, web push, and deep links).
- `AuthGateRouteInterceptor` is the canonical adapter for `RouteProviderInterceptor`: gates every provider except the auth route, redirects unauthenticated callers to `/signin?redirect=`. Sync token check via `CoreLocalDataManager.isAuthenticated`; cache bootstrapped once in `app_delegate`.
- Codegen templates stop emitting one-line coordinators for single-screen modules; repository / common usecase impls now teach the layer-translation pattern (try/catch, DTO→entity, error normalisation — each as a structured TODO).
- `AppBlocBase` retired — blocs extend `CoreBlocBase` directly.
Breaking changes for forks
- `AuthResponse`, `AuthSuccessResponse`, and `LoginResultType` are removed. `AuthUsecase.loginWithPhoneNumberPassword` now returns `Future<UserModel?>`.
- `SigninBloc` events (`UpdatePhoneEvent` / `UpdatePasswordEvent` / `LoginEvent`) and states (`SigninInitial` / `LoginSuccess` / `LoginFailed`) replaced the role-picker shape entirely. `_StateData` carries `phone` and `password`, nothing else.
- `AppBlocBase` is gone. Move existing blocs to `CoreBlocBase`.
- `CorePreferencesHelper` / `PreferencesHelper` and their impl/abstract pair are deleted. Inject `CoreLocalDataManager` or `LocalDataManager` directly.
- `CoreLocalHiveData` (the empty marker interface) and `Hive.initFlutter()` are gone. Re-add only if you actually use Hive.
- l10n keys `userRole`, `pleaseSelectARoleBeforeLoginMsg`, `thisRoleIsNotSupportedYet` are removed; `loginFailed` reworded. Added: `phoneNumber`, `password`, `phoneNumberHint`, `passwordHint`, `phoneRequired`, `passwordRequired`.
- The module generator's listing and common templates no longer emit a `*_coordinator.dart` file. Existing single-screen coordinators in your fork can be safely deleted; call routes directly via `pushBehavior.push(context, …)`.
Bug fixes (uncovered by Playwright e2e on the new auth flow)
- `InputContainer(isPassword: true)` would crash with `Unexpected null value` when no `controller` was supplied — `SignInScreenState` now owns explicit controllers. The latent widget-level null-bang at `input_container.dart:352` is left for a follow-up.
- `LocalDataManager` was bound as `@injectable` (factory), so every DI lookup returned a fresh instance with an empty token cache and the auth gate could never see a logged-in user. Both the class and the `CoreLocalDataManager` bridge are now `@lazySingleton`.
Verified end-to-end (Playwright)
- Cold-launch signin (success + `LoginFailed` branch)
- Deep-link gate (`/dev-mode-dashboard` → `/signin?redirect=…` → back to original)
- Pre-nav guard (404 → "Back to Homepage" → coordinator skips form when token cached)
- Module generator output (listing module: no coordinator file)