feat: add selectedK8sContexts to Preference and user prefs API#673
feat: add selectedK8sContexts to Preference and user prefs API#673
Conversation
… endpoints Add selectedK8sContexts array field to the Preference schema to support persisting the user's Kubernetes context selection across sessions. Add GET/POST /api/user/prefs endpoints (meshery-only) so RTK Query hooks are generated for reading and updating user preferences.
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the user experience by enabling the persistence of selected Kubernetes contexts across sessions. It achieves this by extending the user preference schema to include a new field for Kubernetes context IDs and introducing dedicated API endpoints for managing these preferences. The changes involve updates to the backend Go models, OpenAPI specification, and frontend TypeScript types and RTK Query hooks, ensuring a consistent and robust mechanism for user preference management. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a new selectedK8sContexts field to the user's Preference schema to persist Kubernetes context selections. It also adds new internal API endpoints (GET and POST /api/user/prefs) for managing these preferences and cleans up a number of old, unused user-related API definitions and models. The generated Go, TypeScript, and RTK Query client code has been updated accordingly. My review identifies a potential issue with the new POST endpoint's request body schema, which may not correctly reflect the intended partial update behavior.
| description: Merges the provided fields into the current user's preferences. Only the fields present in the request body are updated. | ||
| x-internal: | ||
| - meshery | ||
| requestBody: | ||
| required: true | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: "#/components/schemas/Preference" |
There was a problem hiding this comment.
The description for this POST operation states that it "Merges the provided fields into the current user's preferences. Only the fields present in the request body are updated." This implies a partial update (PATCH) behavior.
However, the requestBody schema references #/components/schemas/Preference, which has several required fields. This forces the client to send all required fields even when they only intend to update a single field, which contradicts the documented behavior.
For a partial update endpoint, the request body schema should not have required fields. Please consider one of the following solutions:
- Create a new schema for the request body (e.g.,
PreferenceUpdatePayload) that is based onPreferencebut without therequiredproperties. - Inline the schema for the request body and remove the
requiredconstraint.
This will make the API more intuitive and align the schema with the endpoint's described functionality.
There was a problem hiding this comment.
Pull request overview
Adds persistence support for a user’s selected Kubernetes contexts by extending the Preference schema and introducing new Meshery-internal user preferences endpoints, with regenerated Go + TypeScript clients/types reflecting the updated OpenAPI.
Changes:
- Add
selectedK8sContexts: string[]to thePreferenceschema/model. - Add
GET /api/user/prefsandPOST /api/user/prefs(x-internal: meshery) to the v1beta1 user OpenAPI spec. - Regenerate RTK Query endpoints/hooks and v1beta1 user TypeScript/Go models.
Reviewed changes
Copilot reviewed 3 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
schemas/constructs/v1beta1/user/api.yml |
Adds /api/user/prefs endpoints and selectedK8sContexts in Preference. |
models/v1beta1/user/user.go |
Updates generated Go Preference model to include SelectedK8sContexts. |
typescript/rtk/meshery.ts |
Regenerates RTK Query endpoints/types to include getUserPrefs + updateUserPrefs and new preference field. |
typescript/generated/v1beta1/user/User.ts |
Regenerates OpenAPI TypeScript types to include /api/user/prefs and selectedK8sContexts. |
typescript/generated/v1beta1/user/UserSchema.ts |
Regenerates bundled schema output reflecting new endpoints and preference field. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /api/user/prefs: | ||
| get: | ||
| tags: | ||
| - users | ||
| operationId: getUserPrefs | ||
| summary: Get user preferences | ||
| description: Returns the current user's preferences including selected K8s contexts, load test settings, and other UI preferences. | ||
| x-internal: | ||
| - meshery | ||
| responses: |
There was a problem hiding this comment.
/api/user/prefs operations don’t declare any security requirements (and the spec has no top-level security either), which makes these endpoints effectively unauthenticated in the OpenAPI contract despite defining 401 responses. Add a top-level security: [{ jwt: [] }] for this spec or add per-operation security blocks for the new prefs endpoints.
| description: Merges the provided fields into the current user's preferences. Only the fields present in the request body are updated. | ||
| x-internal: | ||
| - meshery | ||
| requestBody: | ||
| required: true | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: "#/components/schemas/Preference" |
There was a problem hiding this comment.
updateUserPrefs is documented as a partial merge (only provided fields are updated), but the requestBody schema $refs Preference, which has many required fields (e.g., updated_at, anonymousUsageStats, etc.). This makes partial updates invalid per the schema and forces generated clients to send server-managed fields. Define a separate update/patch schema with all-optional properties (and mark server-managed fields like updated_at as readOnly) and use that schema for the request body (or change the endpoint semantics/docs to require a full replacement).
| query: () => ({ url: `/api/identity/users/profile` }), | ||
| providesTags: ["User_users"], | ||
| }), | ||
| updateUserPreference: build.mutation<UpdateUserPreferenceApiResponse, UpdateUserPreferenceApiArg>({ | ||
| query: (queryArg) => ({ url: `/api/identity/users/preferences`, method: "PUT", body: queryArg.body }), | ||
| invalidatesTags: ["User_users"], | ||
| }), | ||
| deleteOwnAccount: build.mutation<DeleteOwnAccountApiResponse, DeleteOwnAccountApiArg>({ | ||
| query: () => ({ url: `/api/identity/users/self`, method: "DELETE" }), | ||
| invalidatesTags: ["User_users"], | ||
| }), | ||
| bulkDeleteUsers: build.mutation<BulkDeleteUsersApiResponse, BulkDeleteUsersApiArg>({ | ||
| query: (queryArg) => ({ | ||
| url: `/api/identity/orgs/${queryArg.orgId}/users/bulk`, | ||
| method: "POST", | ||
| body: queryArg.body, | ||
| }), | ||
| invalidatesTags: ["User_users"], | ||
| }), | ||
| getProfileOverview: build.query<GetProfileOverviewApiResponse, GetProfileOverviewApiArg>({ | ||
| query: () => ({ url: `/api/identity/users/profile/details` }), | ||
| providesTags: ["User_users"], | ||
| }), | ||
| getUserActivity: build.query<GetUserActivityApiResponse, GetUserActivityApiArg>({ | ||
| query: (queryArg) => ({ | ||
| url: `/api/identity/users/${queryArg.userId}/profile/activity`, | ||
| params: { | ||
| page: queryArg.page, | ||
| pagesize: queryArg.pagesize, | ||
| order: queryArg.order, | ||
| filter: queryArg.filter, | ||
| }, | ||
| }), | ||
| getUserPrefs: build.query<GetUserPrefsApiResponse, GetUserPrefsApiArg>({ | ||
| query: () => ({ url: `/api/user/prefs` }), | ||
| providesTags: ["User_users"], | ||
| }), | ||
| handleFeedbackFormSubmission: build.mutation< | ||
| HandleFeedbackFormSubmissionApiResponse, | ||
| HandleFeedbackFormSubmissionApiArg | ||
| >({ | ||
| query: (queryArg) => ({ url: `/api/identity/users/notify/feedback`, method: "POST", body: queryArg.body }), | ||
| updateUserPrefs: build.mutation<UpdateUserPrefsApiResponse, UpdateUserPrefsApiArg>({ | ||
| query: (queryArg) => ({ url: `/api/user/prefs`, method: "POST", body: queryArg.body }), | ||
| invalidatesTags: ["User_users"], | ||
| }), |
There was a problem hiding this comment.
This regeneration removes previously exported RTK Query endpoints/hooks (e.g., updateUserPreference, deleteOwnAccount, bulkDeleteUsers, notification prefs, etc.). This is a breaking change for any consumer relying on those hooks; if intentional, it should be called out in the PR description and coordinated with downstream usage.
|
Hold. Pending determination of local definitions versus meshery/schemas. |
Summary
selectedK8sContexts(string array) to thePreferenceschema, enabling persistence of the user's Kubernetes context selection across sessionsGET /api/user/prefsandPOST /api/user/prefsendpoints (meshery-only viax-internal) so RTK Query hooks (useGetUserPrefsQuery,useUpdateUserPrefsMutation) are auto-generatedTest plan
SelectedK8sContexts *[]stringfielduseGetUserPrefsQueryanduseUpdateUserPrefsMutationare exported frommesheryApi