switchUser method

Future<DatumUserSwitchResult> switchUser({
  1. required String? oldUserId,
  2. required String newUserId,
  3. UserSwitchStrategy? strategy,
})

Switches the active user with configurable handling of unsynced data.

Strategies:

Returns DatumUserSwitchResult indicating success or failure with details.

Implementation

Future<DatumUserSwitchResult> switchUser({
  required String? oldUserId,
  required String newUserId,
  UserSwitchStrategy? strategy,
}) async {
  ensureNotDisposed();

  if (newUserId.isEmpty) {
    throw ArgumentError.value(newUserId, 'newUserId', 'Must not be empty');
  }

  final resolvedStrategy = strategy ?? config.defaultUserSwitchStrategy;
  _notifyObservers(
    (o) => o.onUserSwitchStart(oldUserId, newUserId, resolvedStrategy),
  );
  final hadUnsynced = await _hasUnsyncedData(oldUserId);

  try {
    // Execute the strategy. This will throw on failure for certain strategies.
    await _executeUserSwitchStrategy(
      resolvedStrategy,
      oldUserId,
      newUserId,
      hadUnsynced,
    );

    // If the strategy succeeds, proceed with success-related logic.
    _emitUserSwitchedEvent(oldUserId, newUserId, hadUnsynced);
    _logger.info('User switched from $oldUserId to $newUserId');
    // Stop auto-sync for the old user to prevent resource leaks.
    if (oldUserId != null) {
      stopAutoSync(userId: oldUserId);
    }

    // Return the success result.
    final result = DatumUserSwitchResult.success(
      previousUserId: oldUserId,
      newUserId: newUserId,
      unsyncedOperationsHandled: hadUnsynced ? 1 : 0,
    );
    _notifyObservers((o) => o.onUserSwitchEnd(result));
    return result;
  } on UserSwitchException catch (e) {
    // Handle specific user switch failures (e.g., promptIfUnsyncedData).
    _logger.warn('User switch rejected: ${e.message}');
    final result = DatumUserSwitchResult.failure(
      previousUserId: oldUserId,
      newUserId: newUserId,
      errorMessage: e.message,
    );
    _notifyObservers((o) => o.onUserSwitchEnd(result));
    return result;
  } on Object catch (e, stack) {
    // Handle any other unexpected errors during the switch.
    _logger.error('User switch failed', stack);
    final result = DatumUserSwitchResult.failure(
      previousUserId: oldUserId,
      newUserId: newUserId,
      errorMessage: 'User switch failed: $e',
    );
    _notifyObservers((o) => o.onUserSwitchEnd(result));
    return result;
  }
}