MotorSignal-App/lib/services/auth/account_lifecycle_service.dart

60 lines
2.1 KiB
Dart

import 'package:flutter/foundation.dart';
import '../../database/database.dart';
import '../cloud/account_cloud_cleanup_service.dart';
import 'auth_service.dart';
/// Coordinates destructive account work while preserving device-local rides.
class AccountLifecycleService {
final AuthService _auth;
final CloudAccountCleanup _cloud;
final AppDatabase _db;
AccountLifecycleService({required this._auth, required this._cloud, required this._db});
Future<void> deleteAccount({String? password}) async {
final user = _auth.currentUser;
if (user == null || user.isAnonymous) throw StateError('A permanent account is required.');
final uid = user.uid;
var stage = 'reauth';
try {
debugPrint('[DELETE_FLOW] reauth start');
await _auth.reauthenticate(password: password);
debugPrint('[DELETE_FLOW] reauth success');
stage = 'cloud cleanup';
debugPrint('[DELETE_FLOW] cloud cleanup start');
await _cloud.deleteCloudData();
debugPrint('[DELETE_FLOW] cloud cleanup success');
stage = 'Firebase deletion';
debugPrint('[DELETE_FLOW] auth delete start');
await _auth.deleteCurrentUser();
debugPrint('[DELETE_FLOW] auth delete success');
stage = 'local ownership cleanup';
debugPrint('[DELETE_FLOW] local ownership clear start');
await _db.clearCloudOwnerUid(uid);
debugPrint('[DELETE_FLOW] local ownership clear success');
} catch (error, stackTrace) {
final message = error.toString().replaceAll(
RegExp(r'Bearer\s+\S+', caseSensitive: false),
'Bearer [REDACTED]',
);
final clippedMessage = message.length > 240
? message.substring(0, 240)
: message;
final appFrames = stackTrace
.toString()
.split('\n')
.where((line) => line.contains('package:motorcycle_dash/'))
.take(5)
.join(' | ');
debugPrint(
'[DELETE_FLOW] failure stage=$stage type=${error.runtimeType} '
'message=$clippedMessage',
);
if (appFrames.isNotEmpty) {
debugPrint('[DELETE_FLOW] failure frames=$appFrames');
}
rethrow;
}
}
}