mirror of
https://github.com/we-promise/sure.git
synced 2026-04-08 14:54:49 +00:00
* 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>
74 lines
1.7 KiB
Dart
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;
|
|
}
|
|
}
|