refactor(session): migrate V2 session listener initialization to improve dependency injection and role handling

This commit is contained in:
Achintha Isuru
2026-03-17 10:55:18 -04:00
parent b289ed3b02
commit ba5bf8e1d7
6 changed files with 37 additions and 44 deletions

View File

@@ -18,9 +18,8 @@ class CoreModule extends Module {
// 2. Register the base API service
i.addLazySingleton<BaseApiService>(() => ApiService(i.get<Dio>()));
// 2b. Wire the V2 session service with the API service.
// This uses a post-registration callback so the singleton gets
// its dependency as soon as the injector resolves BaseApiService.
// 2b. Register V2SessionService — wires the singleton with ApiService.
// Resolved eagerly by SessionListener.initState() after Modular is ready.
i.addLazySingleton<V2SessionService>(() {
final V2SessionService service = V2SessionService.instance;
service.setApiService(i.get<BaseApiService>());

View File

@@ -42,23 +42,10 @@ class V2SessionService with SessionHandlerMixin {
@override
Future<String?> fetchUserRole(String userId) async {
try {
// Wait for ApiService to be injected (happens after CoreModule.exportedBinds).
// On cold start, initializeAuthListener fires before DI is ready.
if (_apiService == null) {
debugPrint(
'[V2SessionService] ApiService not yet injected; '
'waiting for DI initialization...',
);
for (int i = 0; i < 10; i++) {
await Future<void>.delayed(const Duration(milliseconds: 200));
if (_apiService != null) break;
}
}
final BaseApiService? api = _apiService;
if (api == null) {
debugPrint(
'[V2SessionService] ApiService still null after waiting 2 s; '
'[V2SessionService] ApiService not injected; '
'cannot fetch user role.',
);
return null;
@@ -74,8 +61,16 @@ class V2SessionService with SessionHandlerMixin {
// Per V2 auth doc, GET /auth/session is used for app startup hydration.
_hydrateSessionStores(data);
final String? role = data['role'] as String?;
return role;
// Derive role from the presence of staff/business context.
// The session endpoint returns { user, tenant, business, vendor, staff }
// — there is no explicit "role" field.
final bool hasStaff = data['staff'] is Map<String, dynamic>;
final bool hasBusiness = data['business'] is Map<String, dynamic>;
if (hasStaff && hasBusiness) return 'BOTH';
if (hasStaff) return 'STAFF';
if (hasBusiness) return 'BUSINESS';
return null;
}
return null;
} catch (e) {