Files
sure/mobile/lib/models/user.dart
Juan José Mata bf0be85859 Expose ui_layout and ai_enabled to mobile clients and add enable_ai endpoint (#983)
* Wire ui layout and AI flags into mobile auth

Include ui_layout and ai_enabled in mobile login/signup/SSO payloads,
add an authenticated endpoint to enable AI from Flutter, and gate
mobile navigation based on intro layout and AI consent flow.

* Linter

* Ensure write scope on enable_ai

* Make sure AI is available before enabling it

* Test improvements

* PR comment

* Fix review issues: test assertion bug, missing coverage, and Dart defaults (#985)

- Fix login test to use ai_enabled? (method) instead of ai_enabled (column)
  to match what mobile_user_payload actually serializes
- Add test for enable_ai when ai_available? returns false (403 path)
- Default aiEnabled to false when user is null in AuthProvider to avoid
  showing AI as available before authentication completes
- Remove extra blank lines in auth_provider.dart and auth_service.dart

https://claude.ai/code/session_01LEYYmtsDBoqizyihFtkye4

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-14 00:39:03 +01:00

74 lines
1.7 KiB
Dart

class User {
final String id;
final String email;
final String? firstName;
final String? lastName;
final String uiLayout;
final bool aiEnabled;
User({
required this.id,
required this.email,
this.firstName,
this.lastName,
required this.uiLayout,
required this.aiEnabled,
});
bool get isIntroLayout => uiLayout == 'intro';
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'].toString(),
email: json['email'] as String,
firstName: json['first_name'] as String?,
lastName: json['last_name'] as String?,
uiLayout: (json['ui_layout'] as String?) ?? 'dashboard',
// Default to true when key is absent (legacy payloads from older app versions).
// Avoids regressing existing users who would otherwise be incorrectly gated.
aiEnabled: json.containsKey('ai_enabled')
? (json['ai_enabled'] == true)
: true,
);
}
User copyWith({
String? id,
String? email,
String? firstName,
String? lastName,
String? uiLayout,
bool? aiEnabled,
}) {
return User(
id: id ?? this.id,
email: email ?? this.email,
firstName: firstName ?? this.firstName,
lastName: lastName ?? this.lastName,
uiLayout: uiLayout ?? this.uiLayout,
aiEnabled: aiEnabled ?? this.aiEnabled,
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'email': email,
'first_name': firstName,
'last_name': lastName,
'ui_layout': uiLayout,
'ai_enabled': aiEnabled,
};
}
String get displayName {
if (firstName != null && lastName != null) {
return '$firstName $lastName';
}
if (firstName != null) {
return firstName!;
}
return email;
}
}