Skip to content

Conversation

@tlgimenes
Copy link
Contributor

@tlgimenes tlgimenes commented Jan 2, 2026

What

  • Add USER_GET management MCP tool to fetch user profile info (name/email/avatar) behind auth and org membership checks.
  • Update collection table to render created_by / updated_by via .
  • Switch UI user lookup from REST to MCP tool calls (no /api/users route).

Why

Show human-friendly user info in collection tables instead of raw user ids, without exposing user data outside authenticated MCP access.

Testing


Summary by cubic

Show user names and avatars in collection tables via a secured USER_GET MCP tool, replacing REST user lookups. Improves readability while enforcing org-scoped access.

  • New Features

    • Added USER_GET tool and UserStorage (Better Auth table) with shared-organization checks.
    • component and useUser hook fetch profile (id/name/email/image); collections render *_by fields.
    • Registered tool in the mesh and query keys; 5-minute cache via React Query.
  • Refactors

    • Wired users storage into context and tests; updated seed with auth fields.
    • Removed reliance on /api/users; refined ViewLayout tabs/actions overflow and spacing.

Written for commit c39ca9c. Summary will update on new commits.

…ponent

- Adjusted the layout of the tabs and actions section for improved responsiveness and visual consistency.
- Modified CSS classes to enhance overflow handling and spacing between elements.
@github-actions
Copy link
Contributor

github-actions bot commented Jan 2, 2026

🧪 Benchmark

Should we run the MCP Gateway benchmark for this PR?

React with 👍 to run the benchmark.

Reaction Action
👍 Run quick benchmark (10 & 128 tools)

Benchmark will run on the next push after you react.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 2, 2026

Release Options

Should a new version be published when this PR is merged?

React with an emoji to vote on the release type:

Reaction Type Next Version
👍 Prerelease 1.0.18-alpha.1
🎉 Patch 1.0.18
❤️ Minor 1.1.0
🚀 Major 2.0.0

Current version: 1.0.17

Deployment

  • Deploy to production (triggers ArgoCD sync after Docker image is published)

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 18 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="apps/mesh/src/storage/user.ts">

<violation number="1" location="apps/mesh/src/storage/user.ts:72">
P2: Type assertion `as User &amp; { image?: string }` has no effect here because the function&#39;s declared return type is `Promise&lt;User | null&gt;`. Callers won&#39;t have type-safe access to the `image` field. Either update the return type to `Promise&lt;(User &amp; { image?: string }) | null&gt;`, or define a separate `UserWithImage` type.</violation>
</file>

<file name="apps/mesh/src/web/hooks/use-user.ts">

<violation number="1" location="apps/mesh/src/web/hooks/use-user.ts:33">
P2: Query runs even when `userId` is empty. Add `enabled: !!userId` to prevent unnecessary API calls with invalid user IDs.</violation>
</file>

<file name="apps/mesh/src/web/components/user/user.tsx">

<violation number="1" location="apps/mesh/src/web/components/user/user.tsx:47">
P2: The `Avatar.Skeleton` should receive the `size` prop to match the actual avatar size and prevent layout shift when loading completes. Currently it defaults to `&quot;base&quot;` (40×40px) while the avatar uses `&quot;xs&quot;` (24×24px).</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

updatedAt: result.updatedAt,
// Include image field from Better Auth
image: result.image ?? undefined,
} as User & { image?: string };
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 2, 2026

Choose a reason for hiding this comment

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

P2: Type assertion as User & { image?: string } has no effect here because the function's declared return type is Promise<User | null>. Callers won't have type-safe access to the image field. Either update the return type to Promise<(User & { image?: string }) | null>, or define a separate UserWithImage type.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/storage/user.ts, line 72:

<comment>Type assertion `as User &amp; { image?: string }` has no effect here because the function&#39;s declared return type is `Promise&lt;User | null&gt;`. Callers won&#39;t have type-safe access to the `image` field. Either update the return type to `Promise&lt;(User &amp; { image?: string }) | null&gt;`, or define a separate `UserWithImage` type.</comment>

<file context>
@@ -0,0 +1,74 @@
+      updatedAt: result.updatedAt,
+      // Include image field from Better Auth
+      image: result.image ?? undefined,
+    } as User &amp; { image?: string };
+  }
+}
</file context>
Fix with Cubic

export function useUser(userId: string) {
const toolCaller = createToolCaller<{ id: string }, UserGetOutput>();

return useQuery({
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 2, 2026

Choose a reason for hiding this comment

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

P2: Query runs even when userId is empty. Add enabled: !!userId to prevent unnecessary API calls with invalid user IDs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/hooks/use-user.ts, line 33:

<comment>Query runs even when `userId` is empty. Add `enabled: !!userId` to prevent unnecessary API calls with invalid user IDs.</comment>

<file context>
@@ -0,0 +1,42 @@
+export function useUser(userId: string) {
+  const toolCaller = createToolCaller&lt;{ id: string }, UserGetOutput&gt;();
+
+  return useQuery({
+    queryKey: KEYS.user(userId),
+    queryFn: async () =&gt; {
</file context>
Fix with Cubic

if (isLoading) {
return (
<div className={`flex items-center gap-2 ${className || ""}`}>
<Avatar.Skeleton />
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 2, 2026

Choose a reason for hiding this comment

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

P2: The Avatar.Skeleton should receive the size prop to match the actual avatar size and prevent layout shift when loading completes. Currently it defaults to "base" (40×40px) while the avatar uses "xs" (24×24px).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/components/user/user.tsx, line 47:

<comment>The `Avatar.Skeleton` should receive the `size` prop to match the actual avatar size and prevent layout shift when loading completes. Currently it defaults to `&quot;base&quot;` (40×40px) while the avatar uses `&quot;xs&quot;` (24×24px).</comment>

<file context>
@@ -0,0 +1,87 @@
+  if (isLoading) {
+    return (
+      &lt;div className={`flex items-center gap-2 ${className || &quot;&quot;}`}&gt;
+        &lt;Avatar.Skeleton /&gt;
+        &lt;div className=&quot;flex flex-col gap-1&quot;&gt;
+          &lt;div className=&quot;h-3 w-24 bg-muted animate-pulse rounded&quot; /&gt;
</file context>
Fix with Cubic

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants