feat(splash): route to device setup when a logged-in user has zero devices

Extend CheckSessionUseCase to fetch /devices after confirming the
session and return InitialRoute.deviceSetup when the list is empty
(or the call fails). The splash builder now injects a
SharedDevicesRepository alongside the user repository, and the app
router maps the new route to legacyDeviceSetup / deviceSetup per
shell. The legacy builder reads legacyDevicesProvider to derive
isFirstDevice so the setup screen adapts its copy accordingly.
This commit is contained in:
2026-04-17 11:13:48 +02:00
parent 5b6ed5cf16
commit fd8ef27185
5 changed files with 36 additions and 9 deletions

View File

@@ -51,12 +51,14 @@ const _legacySplashRouteMap = <InitialRoute, String>{
InitialRoute.onboarding: AppRoutes.legacyOnboarding,
InitialRoute.login: AppRoutes.legacyLogin,
InitialRoute.home: AppRoutes.controlPanel,
InitialRoute.deviceSetup: AppRoutes.legacyDeviceSetup,
};
const _paymentSplashRouteMap = <InitialRoute, String>{
InitialRoute.onboarding: AppRoutes.onboarding,
InitialRoute.login: AppRoutes.login,
InitialRoute.home: AppRoutes.dashboardHome,
InitialRoute.deviceSetup: AppRoutes.deviceSetup,
};
void configureAppRouter() {

View File

@@ -1,18 +1,28 @@
import 'package:legacy_auth/src/features/device_setup/presentation/device_setup_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:get_it/get_it.dart';
import 'package:go_router/go_router.dart';
import 'package:navigation/navigation.dart';
import 'package:sf_shared/sf_shared.dart';
class LegacyDeviceSetupBuilder {
const LegacyDeviceSetupBuilder();
Page<void> buildPage(BuildContext context, GoRouterState state) {
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
final navigationContract = GetIt.I<NavigationContract>();
return MaterialPage<void>(
key: state.pageKey,
child: LegacyDeviceSetupScreen(navigationContract: navigationContract),
child: Consumer(
builder: (context, ref, _) {
final devices = ref.watch(legacyDevicesProvider).value ?? [];
return LegacyDeviceSetupScreen(
navigationContract: navigationContract,
isFirstDevice: devices.isEmpty,
);
},
),
);
}
}

View File

@@ -6,11 +6,12 @@ import 'check_session_use_case.dart';
import 'initial_route.dart';
class CheckSessionUseCaseImpl implements CheckSessionUseCase {
CheckSessionUseCaseImpl(this._userRepository);
CheckSessionUseCaseImpl(this._userRepository, this._devicesRepository);
static const _onboardingSeenKey = 'onboarding_seen';
final UserRepository _userRepository;
final SharedDevicesRepository _devicesRepository;
@override
Future<InitialRoute> execute() async {
@@ -26,10 +27,23 @@ class CheckSessionUseCaseImpl implements CheckSessionUseCase {
try {
await _userRepository.getUserInfo();
return InitialRoute.home;
} catch (e) {
debugPrint('[CheckSessionUseCase] error: $e');
debugPrint('[CheckSession] no session: $e');
return InitialRoute.login;
}
try {
final devices = await _devicesRepository.getDevices();
if (devices.isEmpty) {
debugPrint('[CheckSession] → deviceSetup (0 devices)');
return InitialRoute.deviceSetup;
}
} catch (e) {
debugPrint('[CheckSession] devices check failed: $e');
return InitialRoute.deviceSetup;
}
debugPrint('[CheckSession] → home');
return InitialRoute.home;
}
}

View File

@@ -1 +1 @@
enum InitialRoute { login, home, onboarding }
enum InitialRoute { login, home, onboarding, deviceSetup }

View File

@@ -18,9 +18,10 @@ class SplashBuilder {
Page<void> buildPage(BuildContext context, GoRouterState state) {
final navigationContract = GetIt.I<NavigationContract>();
final remote = UserRemoteDatasourceImpl(GetIt.I<SaveFamilyRepository>());
final userRepository = UserRepositoryImpl(remote);
final checkSessionUseCase = CheckSessionUseCaseImpl(userRepository);
final repository = GetIt.I<SaveFamilyRepository>();
final userRepository = UserRepositoryImpl(UserRemoteDatasourceImpl(repository));
final devicesRepository = DevicesRepositoryImpl(DevicesRemoteDatasourceImpl(repository));
final checkSessionUseCase = CheckSessionUseCaseImpl(userRepository, devicesRepository);
return NoTransitionPage(
child: SplashScreen(