Preserve explicit model and provider architecture (#30)

This commit is contained in:
Stephan D committed 2026-09-12 12:09:26 +02:00
1 parent 54f50ad6b7
commit 8b0662e340
10 files changed
+104 -7

No files matched your search

@@ -0,0 +1,11 @@
/// Stub response contracts, replaced by generated transport types at integration.
class AuthDTO {
const AuthDTO({required this.userId, required this.simulated});
final String userId;
final bool simulated;
}
class VerificationDTO {
const VerificationDTO({required this.simulated});
final bool simulated;
}
@@ -0,0 +1,13 @@
import '../dto/results.dart';
import '../models/auth.dart';
import '../models/verification.dart';
abstract final class AuthMapper {
static AuthResult fromDTO(AuthDTO dto) =>
AuthResult(userId: dto.userId, isSimulated: dto.simulated);
}
abstract final class VerificationMapper {
static VerificationResult fromDTO(VerificationDTO dto) =>
VerificationResult(isSimulated: dto.simulated);
}
@@ -1,3 +1,5 @@
import '../dto/results.dart';
import '../mappers/results.dart';
import '../models/auth.dart';
import 'contracts.dart';
import 'verification.dart';
@@ -18,7 +20,9 @@ class DummyLoginService implements LoginService, SimulationInfo {
Future<AuthResult> login(LoginRequest request) async {
await Future<void>.delayed(delay);
if (failure case final error?) throw AuthException(error);
return const AuthResult(userId: 'demo-user', isSimulated: true);
return AuthMapper.fromDTO(
const AuthDTO(userId: 'demo-user', simulated: true),
);
}
}
@@ -36,6 +40,8 @@ class DummySignupService implements SignupService, SimulationInfo {
Future<AuthResult> signup(SignupRequest request) async {
await Future<void>.delayed(delay);
if (failure case final error?) throw AuthException(error);
return const AuthResult(userId: 'demo-user', isSimulated: true);
return AuthMapper.fromDTO(
const AuthDTO(userId: 'demo-user', simulated: true),
);
}
}
@@ -1,3 +1,5 @@
import '../dto/results.dart';
import '../mappers/results.dart';
import '../models/verification.dart';
abstract interface class SimulationInfo {
@@ -30,7 +32,7 @@ class DummyVerificationService implements VerificationService, SimulationInfo {
}) async {
await Future<void>.delayed(delay);
if (sendFailure case final error?) throw VerificationException(error);
return const VerificationResult(isSimulated: true);
return VerificationMapper.fromDTO(const VerificationDTO(simulated: true));
}
@override
@@ -38,7 +40,9 @@ class DummyVerificationService implements VerificationService, SimulationInfo {
await Future<void>.delayed(delay);
switch (token) {
case 'demo-valid':
return const VerificationResult(isSimulated: true);
return VerificationMapper.fromDTO(
const VerificationDTO(simulated: true),
);
case 'demo-expired':
throw const VerificationException(VerificationError.expired);
case 'demo-internal':
@@ -204,7 +204,7 @@ class DummyWalletService implements WalletService {
@override
Future<AccountProfile> profile() async {
await _wait();
return WalletMapper.profile(_locale);
return WalletMapper.profile(ProfileDTO(_locale));
}
@override
@@ -213,7 +213,7 @@ class DummyWalletService implements WalletService {
if (!['en', 'ru'].contains(locale))
throw const WalletException(WalletError.unsupported);
_locale = locale;
return WalletMapper.profile(_locale);
return WalletMapper.profile(ProfileDTO(_locale));
}
// Kept separate from wallet fetch because LimitsService has a different result.
@@ -53,6 +53,11 @@ class OperationDTO {
final bool fail;
}
class ProfileDTO {
const ProfileDTO(this.locale);
final String locale;
}
abstract final class WalletMapper {
static CurrencyAccount account(AccountDTO d) => CurrencyAccount(
id: d.id,
@@ -85,5 +90,5 @@ abstract final class WalletMapper {
status: OperationStatus.values.byName(d.status),
createdAt: d.created,
);
static AccountProfile profile(String locale) => AccountProfile(locale);
static AccountProfile profile(ProfileDTO dto) => AccountProfile(dto.locale);
}