update database
This commit is contained in:
314
lib/features/auth/domain/entities/user.dart
Normal file
314
lib/features/auth/domain/entities/user.dart
Normal file
@@ -0,0 +1,314 @@
|
||||
/// Domain Entity: User
|
||||
///
|
||||
/// Represents a user account in the Worker application.
|
||||
/// Contains authentication, profile, and loyalty information.
|
||||
library;
|
||||
|
||||
/// User role enum
|
||||
enum UserRole {
|
||||
/// Customer/worker user
|
||||
customer,
|
||||
|
||||
/// Sales representative
|
||||
sales,
|
||||
|
||||
/// System administrator
|
||||
admin,
|
||||
|
||||
/// Accountant
|
||||
accountant,
|
||||
|
||||
/// Designer
|
||||
designer;
|
||||
}
|
||||
|
||||
/// User status enum
|
||||
enum UserStatus {
|
||||
/// Account pending approval
|
||||
pending,
|
||||
|
||||
/// Active account
|
||||
active,
|
||||
|
||||
/// Suspended account
|
||||
suspended,
|
||||
|
||||
/// Rejected account
|
||||
rejected;
|
||||
}
|
||||
|
||||
/// Loyalty tier enum
|
||||
enum LoyaltyTier {
|
||||
/// No tier
|
||||
none,
|
||||
|
||||
/// Gold tier (entry level)
|
||||
gold,
|
||||
|
||||
/// Platinum tier (mid level)
|
||||
platinum,
|
||||
|
||||
/// Diamond tier (highest level)
|
||||
diamond;
|
||||
|
||||
/// Get display name for tier
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case LoyaltyTier.none:
|
||||
return 'NONE';
|
||||
case LoyaltyTier.gold:
|
||||
return 'GOLD';
|
||||
case LoyaltyTier.platinum:
|
||||
return 'PLATINUM';
|
||||
case LoyaltyTier.diamond:
|
||||
return 'DIAMOND';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Company information
|
||||
class CompanyInfo {
|
||||
/// Company name
|
||||
final String? name;
|
||||
|
||||
/// Tax identification number
|
||||
final String? taxId;
|
||||
|
||||
/// Company address
|
||||
final String? address;
|
||||
|
||||
/// Business type
|
||||
final String? businessType;
|
||||
|
||||
/// Business license number
|
||||
final String? licenseNumber;
|
||||
|
||||
const CompanyInfo({
|
||||
this.name,
|
||||
this.taxId,
|
||||
this.address,
|
||||
this.businessType,
|
||||
this.licenseNumber,
|
||||
});
|
||||
|
||||
/// Create from JSON map
|
||||
factory CompanyInfo.fromJson(Map<String, dynamic> json) {
|
||||
return CompanyInfo(
|
||||
name: json['name'] as String?,
|
||||
taxId: json['tax_id'] as String?,
|
||||
address: json['address'] as String?,
|
||||
businessType: json['business_type'] as String?,
|
||||
licenseNumber: json['license_number'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
/// Convert to JSON map
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'tax_id': taxId,
|
||||
'address': address,
|
||||
'business_type': businessType,
|
||||
'license_number': licenseNumber,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// User Entity
|
||||
///
|
||||
/// Represents a complete user profile including:
|
||||
/// - Authentication credentials
|
||||
/// - Personal information
|
||||
/// - Company details (if applicable)
|
||||
/// - Loyalty program membership
|
||||
/// - Referral information
|
||||
class User {
|
||||
/// Unique user identifier
|
||||
final String userId;
|
||||
|
||||
/// Phone number (used for login)
|
||||
final String phoneNumber;
|
||||
|
||||
/// Full name
|
||||
final String fullName;
|
||||
|
||||
/// Email address
|
||||
final String? email;
|
||||
|
||||
/// User role
|
||||
final UserRole role;
|
||||
|
||||
/// Account status
|
||||
final UserStatus status;
|
||||
|
||||
/// Current loyalty tier
|
||||
final LoyaltyTier loyaltyTier;
|
||||
|
||||
/// Total loyalty points
|
||||
final int totalPoints;
|
||||
|
||||
/// Company information (optional)
|
||||
final CompanyInfo? companyInfo;
|
||||
|
||||
/// CCCD/ID card number
|
||||
final String? cccd;
|
||||
|
||||
/// Attachment URLs (ID cards, licenses, etc.)
|
||||
final List<String> attachments;
|
||||
|
||||
/// Address
|
||||
final String? address;
|
||||
|
||||
/// Avatar URL
|
||||
final String? avatarUrl;
|
||||
|
||||
/// Referral code (unique for this user)
|
||||
final String? referralCode;
|
||||
|
||||
/// ID of user who referred this user
|
||||
final String? referredBy;
|
||||
|
||||
/// ERPNext customer ID
|
||||
final String? erpnextCustomerId;
|
||||
|
||||
/// Account creation timestamp
|
||||
final DateTime createdAt;
|
||||
|
||||
/// Last update timestamp
|
||||
final DateTime updatedAt;
|
||||
|
||||
/// Last login timestamp
|
||||
final DateTime? lastLoginAt;
|
||||
|
||||
const User({
|
||||
required this.userId,
|
||||
required this.phoneNumber,
|
||||
required this.fullName,
|
||||
this.email,
|
||||
required this.role,
|
||||
required this.status,
|
||||
required this.loyaltyTier,
|
||||
required this.totalPoints,
|
||||
this.companyInfo,
|
||||
this.cccd,
|
||||
required this.attachments,
|
||||
this.address,
|
||||
this.avatarUrl,
|
||||
this.referralCode,
|
||||
this.referredBy,
|
||||
this.erpnextCustomerId,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
this.lastLoginAt,
|
||||
});
|
||||
|
||||
/// Check if user is active
|
||||
bool get isActive => status == UserStatus.active;
|
||||
|
||||
/// Check if user is pending approval
|
||||
bool get isPending => status == UserStatus.pending;
|
||||
|
||||
/// Check if user has company info
|
||||
bool get hasCompanyInfo => companyInfo != null && companyInfo!.name != null;
|
||||
|
||||
/// Check if user is an admin
|
||||
bool get isAdmin => role == UserRole.admin;
|
||||
|
||||
/// Check if user is a customer
|
||||
bool get isCustomer => role == UserRole.customer;
|
||||
|
||||
/// Get display name for user
|
||||
String get displayName => fullName;
|
||||
|
||||
/// Copy with method for immutability
|
||||
User copyWith({
|
||||
String? userId,
|
||||
String? phoneNumber,
|
||||
String? fullName,
|
||||
String? email,
|
||||
UserRole? role,
|
||||
UserStatus? status,
|
||||
LoyaltyTier? loyaltyTier,
|
||||
int? totalPoints,
|
||||
CompanyInfo? companyInfo,
|
||||
String? cccd,
|
||||
List<String>? attachments,
|
||||
String? address,
|
||||
String? avatarUrl,
|
||||
String? referralCode,
|
||||
String? referredBy,
|
||||
String? erpnextCustomerId,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
DateTime? lastLoginAt,
|
||||
}) {
|
||||
return User(
|
||||
userId: userId ?? this.userId,
|
||||
phoneNumber: phoneNumber ?? this.phoneNumber,
|
||||
fullName: fullName ?? this.fullName,
|
||||
email: email ?? this.email,
|
||||
role: role ?? this.role,
|
||||
status: status ?? this.status,
|
||||
loyaltyTier: loyaltyTier ?? this.loyaltyTier,
|
||||
totalPoints: totalPoints ?? this.totalPoints,
|
||||
companyInfo: companyInfo ?? this.companyInfo,
|
||||
cccd: cccd ?? this.cccd,
|
||||
attachments: attachments ?? this.attachments,
|
||||
address: address ?? this.address,
|
||||
avatarUrl: avatarUrl ?? this.avatarUrl,
|
||||
referralCode: referralCode ?? this.referralCode,
|
||||
referredBy: referredBy ?? this.referredBy,
|
||||
erpnextCustomerId: erpnextCustomerId ?? this.erpnextCustomerId,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
lastLoginAt: lastLoginAt ?? this.lastLoginAt,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is User &&
|
||||
other.userId == userId &&
|
||||
other.phoneNumber == phoneNumber &&
|
||||
other.fullName == fullName &&
|
||||
other.email == email &&
|
||||
other.role == role &&
|
||||
other.status == status &&
|
||||
other.loyaltyTier == loyaltyTier &&
|
||||
other.totalPoints == totalPoints &&
|
||||
other.cccd == cccd &&
|
||||
other.address == address &&
|
||||
other.avatarUrl == avatarUrl &&
|
||||
other.referralCode == referralCode &&
|
||||
other.referredBy == referredBy &&
|
||||
other.erpnextCustomerId == erpnextCustomerId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return Object.hash(
|
||||
userId,
|
||||
phoneNumber,
|
||||
fullName,
|
||||
email,
|
||||
role,
|
||||
status,
|
||||
loyaltyTier,
|
||||
totalPoints,
|
||||
cccd,
|
||||
address,
|
||||
avatarUrl,
|
||||
referralCode,
|
||||
referredBy,
|
||||
erpnextCustomerId,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'User(userId: $userId, phoneNumber: $phoneNumber, fullName: $fullName, '
|
||||
'role: $role, status: $status, loyaltyTier: $loyaltyTier, totalPoints: $totalPoints)';
|
||||
}
|
||||
}
|
||||
142
lib/features/auth/domain/entities/user_session.dart
Normal file
142
lib/features/auth/domain/entities/user_session.dart
Normal file
@@ -0,0 +1,142 @@
|
||||
/// 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)';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user