class User { final String id; final String? email; final String? username; final String? nickname; final String? avatar; final String? discriminator; final bool? temporary; final String? type; final bool? emailVerified; final bool? banned; final Map? extra; final DateTime? createdAt; User({ required this.id, this.email, this.username, this.nickname, this.avatar, this.discriminator, this.temporary, this.type, this.emailVerified, this.banned, this.extra, this.createdAt, }); factory User.fromJson(Map json) { return User( id: (json['_id'] ?? json['id'] ?? '').toString(), email: json['email'], username: json['username'], nickname: json['nickname'], avatar: json['avatar'], discriminator: json['discriminator']?.toString(), temporary: json['temporary'], type: json['type'], emailVerified: json['emailVerified'], banned: json['banned'], extra: json['extra'], createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt'].toString()) : null, ); } Map toJson() { return { '_id': id, 'email': email, 'username': username, 'nickname': nickname, 'avatar': avatar, 'discriminator': discriminator, 'temporary': temporary, 'type': type, 'emailVerified': emailVerified, 'banned': banned, 'extra': extra, 'createdAt': createdAt?.toIso8601String(), }; } /// Display name: nickname first, then username, then email prefix String get displayName { if (nickname != null && nickname!.isNotEmpty) return nickname!; if (username != null && username!.isNotEmpty) return username!; if (email != null && email!.isNotEmpty) return email!.split('@').first; return 'User'; } /// Check if user is a guest/temporary user bool get isGuest => temporary == true; /// Role checks - these may come from extra fields or custom logic /// In Tailchat, roles are not built-in; they are managed by the plugin bool get isAdmin { final role = extra?['role']; return role == 'admin' || role == 'super_admin'; } bool get isSuperAdmin { final role = extra?['role']; return role == 'super_admin'; } bool get isSales { final role = extra?['role']; return role == 'sales' || role == null; } } /// Tailchat login/register response wraps the user info with a token. /// The backend returns the user object directly with a `token` field appended. /// The gateway wraps all responses as `{ code, data }`. class AuthResponse { final User user; final String token; AuthResponse({required this.user, required this.token}); /// Parse from the gateway response. /// Gateway returns: { "code": 200, "data": { ...userFields..., "token": "jwt..." } } factory AuthResponse.fromJson(Map json) { // The gateway wraps response in { code, data } final data = json['data'] ?? json; final token = data['token'] ?? ''; final user = User.fromJson(data); return AuthResponse( user: user, token: token, ); } }