feat(01-02): create AuthUser data model

- AuthUser class wraps Supabase User for clean architecture
- Includes fromSupabase() factory constructor for conversion
- Provides copyWith() method for immutable updates
- Contains essential fields: id, email, created_at, email_verified
- Optional fields: display_name, avatar_url, last_sign_in_at
- Proper null safety and equality operators implemented
This commit is contained in:
Dani B
2026-01-28 09:09:50 -05:00
parent f1d15fd693
commit c45bb22971

View File

@@ -0,0 +1,110 @@
import 'package:supabase_flutter/supabase_flutter.dart';
/// AuthUser data model representing a user in the authentication system.
///
/// This model provides a clean abstraction over Supabase's User model,
/// following clean architecture principles for the data layer.
class AuthUser {
/// Unique identifier for the user
final String id;
/// User's email address
final String email;
/// Timestamp when the user account was created
final DateTime createdAt;
/// Whether the user's email has been verified
final bool emailVerified;
/// User's display name (optional)
final String? displayName;
/// User's avatar URL (optional)
final String? avatarUrl;
/// Timestamp when the user was last seen
final DateTime? lastSignInAt;
/// Creates a new AuthUser instance
const AuthUser({
required this.id,
required this.email,
required this.createdAt,
required this.emailVerified,
this.displayName,
this.avatarUrl,
this.lastSignInAt,
});
/// Creates an AuthUser from a Supabase User object
///
/// [user] - The Supabase User object to convert
/// Returns an AuthUser with mapped fields
factory AuthUser.fromSupabase(User user) {
return AuthUser(
id: user.id,
email: user.email ?? '',
createdAt: user.createdAt ?? DateTime.now(),
emailVerified: user.emailConfirmedAt != null,
displayName: user.userMetadata?['display_name'] as String?,
avatarUrl: user.userMetadata?['avatar_url'] as String?,
lastSignInAt: user.lastSignInAt,
);
}
/// Creates a copy of this AuthUser with updated values
///
/// Allows for immutable updates to user data
AuthUser copyWith({
String? id,
String? email,
DateTime? createdAt,
bool? emailVerified,
String? displayName,
String? avatarUrl,
DateTime? lastSignInAt,
}) {
return AuthUser(
id: id ?? this.id,
email: email ?? this.email,
createdAt: createdAt ?? this.createdAt,
emailVerified: emailVerified ?? this.emailVerified,
displayName: displayName ?? this.displayName,
avatarUrl: avatarUrl ?? this.avatarUrl,
lastSignInAt: lastSignInAt ?? this.lastSignInAt,
);
}
/// Returns a string representation of the user for debugging
@override
String toString() {
return 'AuthUser(id: $id, email: $email, emailVerified: $emailVerified, displayName: $displayName)';
}
/// Returns true if the user is considered authenticated
///
/// A user is authenticated if they have a valid ID and email
bool get isAuthenticated => id.isNotEmpty && email.isNotEmpty;
/// Returns true if the user's email is verified
bool get isEmailVerified => emailVerified;
/// Equality operator for comparing AuthUser objects
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is AuthUser &&
other.id == id &&
other.email == email &&
other.emailVerified == emailVerified;
}
/// Hash code for AuthUser objects
@override
int get hashCode {
return id.hashCode ^
email.hashCode ^
emailVerified.hashCode;
}
}