tasq/lib/models/verification_session.dart

55 lines
1.7 KiB
Dart

import '../utils/app_time.dart';
/// A cross-device face verification session.
///
/// Created on web when no camera is detected. The web client generates a QR
/// code containing the session ID. The mobile client scans the QR, performs
/// liveness detection, uploads the photo, and marks the session completed.
class VerificationSession {
VerificationSession({
required this.id,
required this.userId,
required this.type,
this.contextId,
this.status = 'pending',
this.imageUrl,
required this.createdAt,
required this.expiresAt,
});
final String id;
final String userId;
final String type; // 'enrollment' or 'verification'
final String? contextId; // e.g. attendance_log_id
final String status; // 'pending', 'completed', 'expired'
final String? imageUrl;
final DateTime createdAt;
final DateTime expiresAt;
bool get isPending => status == 'pending';
bool get isCompleted => status == 'completed';
bool get isExpired =>
status == 'expired' || DateTime.now().toUtc().isAfter(expiresAt);
factory VerificationSession.fromMap(Map<String, dynamic> map) {
return VerificationSession(
id: map['id'] as String,
userId: map['user_id'] as String,
type: map['type'] as String,
contextId: map['context_id'] as String?,
status: (map['status'] as String?) ?? 'pending',
imageUrl: map['image_url'] as String?,
createdAt: AppTime.parse(map['created_at'] as String),
expiresAt: AppTime.parse(map['expires_at'] as String),
);
}
Map<String, dynamic> toJson() {
return {
'user_id': userId,
'type': type,
if (contextId != null) 'context_id': contextId,
};
}
}