Skip to content

feat: add selectedK8sContexts to Preference and user prefs API#673

Open
hortison wants to merge 1 commit intomasterfrom
feat/persist-k8s-context-selection
Open

feat: add selectedK8sContexts to Preference and user prefs API#673
hortison wants to merge 1 commit intomasterfrom
feat/persist-k8s-context-selection

Conversation

@hortison
Copy link
Copy Markdown
Contributor

Summary

  • Adds selectedK8sContexts (string array) to the Preference schema, enabling persistence of the user's Kubernetes context selection across sessions
  • Adds GET /api/user/prefs and POST /api/user/prefs endpoints (meshery-only via x-internal) so RTK Query hooks (useGetUserPrefsQuery, useUpdateUserPrefsMutation) are auto-generated
  • Regenerates Go models, RTK Query clients, and TypeScript types

Test plan

  • Verify generated Go model includes SelectedK8sContexts *[]string field
  • Verify useGetUserPrefsQuery and useUpdateUserPrefsMutation are exported from mesheryApi
  • Integration tested in companion meshery PR for persisting K8s context selection

… 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.
Copilot AI review requested due to automatic review settings March 24, 2026 03:16
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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

  • User Preferences Extension: The Preference schema now includes selectedK8sContexts, an array of strings to store active Kubernetes context IDs, enabling persistence across sessions.
  • New User Preferences API: Introduced GET /api/user/prefs and POST /api/user/prefs endpoints, exclusively for internal Meshery use (x-internal), to retrieve and update user preferences.
  • Code Regeneration: Go models, RTK Query clients, and TypeScript types have been regenerated to reflect the schema and API changes.
  • API Cleanup: Several unused or deprecated API endpoints and related types have been removed from the TypeScript client and Go models, streamlining the user API.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +133 to +141
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"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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:

  1. Create a new schema for the request body (e.g., PreferenceUpdatePayload) that is based on Preference but without the required properties.
  2. Inline the schema for the request body and remove the required constraint.

This will make the API more intuitive and align the schema with the endpoint's described functionality.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 the Preference schema/model.
  • Add GET /api/user/prefs and POST /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.

Comment on lines +108 to +117
/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:
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/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.

Copilot uses AI. Check for mistakes.
Comment on lines +133 to +141
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"
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
Comment on lines 352 to 362
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"],
}),
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
@marblom007 marblom007 added the pr/on hold PR/Issue on hold label Mar 24, 2026
@marblom007
Copy link
Copy Markdown
Member

Hold. Pending determination of local definitions versus meshery/schemas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr/on hold PR/Issue on hold

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants