/// Domain Entity: User Session /// /// Represents an active user session with device and authentication information. library; /// User Session Entity /// /// Contains information about an active user session: /// - Device details /// - Authentication tokens /// - Session timing class UserSession { /// Unique session identifier final String sessionId; /// User ID associated with this session final String userId; /// Unique device identifier final String deviceId; /// Device type (ios, android, web) final String? deviceType; /// Device name final String? deviceName; /// IP address final String? ipAddress; /// User agent string final String? userAgent; /// Refresh token for renewing access final String? refreshToken; /// Session expiration timestamp final DateTime expiresAt; /// Session creation timestamp final DateTime createdAt; /// Last activity timestamp final DateTime? lastActivity; const UserSession({ required this.sessionId, required this.userId, required this.deviceId, this.deviceType, this.deviceName, this.ipAddress, this.userAgent, this.refreshToken, required this.expiresAt, required this.createdAt, this.lastActivity, }); /// Check if session is expired bool get isExpired => DateTime.now().isAfter(expiresAt); /// Check if session is expiring soon (within 1 hour) bool get isExpiringSoon { final hoursUntilExpiry = expiresAt.difference(DateTime.now()).inHours; return hoursUntilExpiry > 0 && hoursUntilExpiry <= 1; } /// Check if session is active bool get isActive => !isExpired; /// Get device display name String get deviceDisplayName => deviceName ?? deviceType ?? 'Unknown Device'; /// Get time since last activity Duration? get timeSinceLastActivity { if (lastActivity == null) return null; return DateTime.now().difference(lastActivity!); } /// Copy with method for immutability UserSession copyWith({ String? sessionId, String? userId, String? deviceId, String? deviceType, String? deviceName, String? ipAddress, String? userAgent, String? refreshToken, DateTime? expiresAt, DateTime? createdAt, DateTime? lastActivity, }) { return UserSession( sessionId: sessionId ?? this.sessionId, userId: userId ?? this.userId, deviceId: deviceId ?? this.deviceId, deviceType: deviceType ?? this.deviceType, deviceName: deviceName ?? this.deviceName, ipAddress: ipAddress ?? this.ipAddress, userAgent: userAgent ?? this.userAgent, refreshToken: refreshToken ?? this.refreshToken, expiresAt: expiresAt ?? this.expiresAt, createdAt: createdAt ?? this.createdAt, lastActivity: lastActivity ?? this.lastActivity, ); } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is UserSession && other.sessionId == sessionId && other.userId == userId && other.deviceId == deviceId && other.deviceType == deviceType && other.deviceName == deviceName && other.ipAddress == ipAddress && other.refreshToken == refreshToken; } @override int get hashCode { return Object.hash( sessionId, userId, deviceId, deviceType, deviceName, ipAddress, refreshToken, ); } @override String toString() { return 'UserSession(sessionId: $sessionId, userId: $userId, deviceId: $deviceId, ' 'deviceType: $deviceType, expiresAt: $expiresAt, isActive: $isActive)'; } }