import '../models/identity.dart'; import '../models/limits.dart'; import '../transport/contracts.dart'; import 'contracts.dart'; /// Process-local backend stand-in. It never stores or sends document bytes. class DummyIdentityService implements IdentityService { DummyIdentityService({this.delay = const Duration(milliseconds: 450)}); final Duration delay; IdentityDTO _record = const IdentityDTO('unverified'); String? _lastKey; KycError? nextError; @override bool get isSimulated => true; Future _wait() async { await Future.delayed(delay); final error = nextError; nextError = null; if (error != null) throw KycException(error); } @override Future fetch() async { await _wait(); return IdentityMapper.fromDTO(_record); } @override Future submit({ required Photo passport, required Photo selfie, required String idempotencyKey, }) async { await _wait(); if (_lastKey == idempotencyKey) return IdentityMapper.fromDTO(_record); if (!IdentityMapper.fromDTO(_record).canSubmit) throw const KycException(KycError.conflict); if (passport.bytes.isEmpty || selfie.bytes.isEmpty) throw const KycException(KycError.incomplete); _lastKey = idempotencyKey; _record = IdentityDTO('pending', id: idempotencyKey); return IdentityMapper.fromDTO(_record); } /// Explicit demo-only human decision stand-in; unavailable in real adapters. void review(IdentityStatus status, {ReviewReason? reason}) { if (_record.status != 'pending') throw const KycException(KycError.conflict); if (![ IdentityStatus.approved, IdentityStatus.changesRequested, IdentityStatus.denied, ].contains(status)) throw const KycException(KycError.conflict); _record = IdentityDTO(status.name, id: _record.id, reason: reason?.name); } } /// Mimics backend policy evaluation. Widgets/providers never compute active caps. /// Values are illustrative fixtures, not the product's real limits policy. class DummyLimitsService implements LimitsService { DummyLimitsService(this.identity); final IdentityService identity; @override Future fetch() async { final record = await identity.fetch(); final approved = record.status == IdentityStatus.approved; return LimitsMapper.fromDTO( LimitsDTO( tier: approved ? 'verified' : 'basic', simulated: true, rows: [ LimitDTO( 'day', 'EUR', 10000, 250000, approved ? 250000 : 10000, (approved ? 250000 : 10000) - 4000, 3000, 1000, ), LimitDTO( 'month', 'EUR', 50000, 1000000, approved ? 1000000 : 50000, (approved ? 1000000 : 50000) - 19000, 18000, 1000, ), ], ), ); } }