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>
This commit is contained in:
Juan José Mata
2026-02-14 00:39:03 +01:00
committed by GitHub
parent e99e38a91c
commit bf0be85859
10 changed files with 774 additions and 104 deletions

View File

@@ -51,7 +51,9 @@ RSpec.describe 'API V1 Auth', type: :request do
id: { type: :string, format: :uuid },
email: { type: :string },
first_name: { type: :string },
last_name: { type: :string }
last_name: { type: :string },
ui_layout: { type: :string, enum: %w[dashboard intro] },
ai_enabled: { type: :boolean }
}
}
}
@@ -110,7 +112,9 @@ RSpec.describe 'API V1 Auth', type: :request do
id: { type: :string, format: :uuid },
email: { type: :string },
first_name: { type: :string },
last_name: { type: :string }
last_name: { type: :string },
ui_layout: { type: :string, enum: %w[dashboard intro] },
ai_enabled: { type: :boolean }
}
}
}
@@ -152,7 +156,9 @@ RSpec.describe 'API V1 Auth', type: :request do
id: { type: :string, format: :uuid },
email: { type: :string },
first_name: { type: :string },
last_name: { type: :string }
last_name: { type: :string },
ui_layout: { type: :string, enum: %w[dashboard intro] },
ai_enabled: { type: :boolean }
}
}
}
@@ -209,4 +215,41 @@ RSpec.describe 'API V1 Auth', type: :request do
end
end
end
path '/api/v1/auth/enable_ai' do
patch 'Enable AI features for the authenticated user' do
tags 'Auth'
consumes 'application/json'
produces 'application/json'
security [ { apiKeyAuth: [] } ]
response '200', 'ai enabled' do
schema type: :object,
properties: {
user: {
type: :object,
properties: {
id: { type: :string, format: :uuid },
email: { type: :string },
first_name: { type: :string, nullable: true },
last_name: { type: :string, nullable: true },
ui_layout: { type: :string, enum: %w[dashboard intro] },
ai_enabled: { type: :boolean }
}
}
}
run_test!
end
response '401', 'unauthorized' do
schema '$ref' => '#/components/schemas/ErrorResponse'
run_test!
end
response '403', 'insufficient scope' do
schema '$ref' => '#/components/schemas/ErrorResponse'
run_test!
end
end
end
end