Adding simplified user/[id] v2 endpoint

This commit is contained in:
Wells Bunker 2025-09-11 12:18:49 -06:00
parent 9c967b657d
commit 633b66d132
No known key found for this signature in database
GPG Key ID: DB16D6F2679B78FC
3 changed files with 62 additions and 13 deletions

View File

@ -1,22 +1,25 @@
import { getUserInformation } from '@buster/database';
import { GetUserByIdRequestSchema, type GetUserByIdResponse } from '@buster/server-shared/user';
import { zValidator } from '@hono/zod-validator';
import { Hono } from 'hono';
import suggestedPromptsRoutes from './suggested-prompts';
import { HTTPException } from 'hono/http-exception';
import { standardErrorHandler } from '../../../../utils/response';
const app = new Hono()
.get('/', (c) => {
.get('/', zValidator('param', GetUserByIdRequestSchema), async (c) => {
const userId = c.req.param('id');
const authenticatedUser = c.get('busterUser');
// Stub data for individual user
const stubUser = {
id: userId,
name: 'Example User',
email: `user${userId}@example.com`,
role: 'user',
createdAt: '2024-01-01T00:00:00Z',
updatedAt: '2024-01-01T00:00:00Z',
};
if (authenticatedUser.id !== userId) {
throw new HTTPException(403, {
message: 'You are not authorized to access this user',
});
}
return c.json(stubUser);
const userInfo: GetUserByIdResponse = await getUserInformation(userId);
return c.json(userInfo);
})
.route('/suggested-prompts', suggestedPromptsRoutes);
.onError(standardErrorHandler);
export default app;

View File

@ -1,4 +1,5 @@
import { and, eq, isNull } from 'drizzle-orm';
import { z } from 'zod';
import { db } from '../../connection';
import { users, usersToOrganizations } from '../../schema';
import type { User } from './user';
@ -6,6 +7,15 @@ import type { User } from './user';
// Use the full User type from the schema internally
type FullUser = typeof users.$inferSelect;
export const UserInfoByIdResponseSchema = z.object({
id: z.string().uuid(),
name: z.string().nullable(),
email: z.string().email(),
role: z.string(),
status: z.string(),
});
export type UserInfoByIdResponse = z.infer<typeof UserInfoByIdResponseSchema>;
/**
* Converts a full user to the public User type
*/
@ -142,3 +152,31 @@ export async function addUserToOrganization(
throw error;
}
}
/**
* Get comprehensive user information including datasets and permissions
* This function replaces the complex Rust implementation with TypeScript
*/
export async function getUserInformation(userId: string): Promise<UserInfoByIdResponse> {
// Get user basic info and organization relationship
const userInfo = await db
.select({
id: users.id,
email: users.email,
name: users.name,
role: usersToOrganizations.role,
status: usersToOrganizations.status,
organizationId: usersToOrganizations.organizationId,
})
.from(users)
.innerJoin(usersToOrganizations, eq(users.id, usersToOrganizations.userId))
.where(and(eq(users.id, userId), isNull(usersToOrganizations.deletedAt)))
.limit(1);
if (userInfo.length === 0 || !userInfo[0]) {
throw new Error(`User not found: ${userId}`);
}
const user: UserInfoByIdResponse = userInfo[0];
return user;
}

View File

@ -1,3 +1,4 @@
import type { UserInfoByIdResponse } from '@buster/database';
import { z } from 'zod';
import type { UserFavorite } from './favorites.types';
import type { UserOrganizationRole } from './roles.types';
@ -19,3 +20,10 @@ export const UserSchema = z.object({
});
export type User = z.infer<typeof UserSchema>;
export const GetUserByIdRequestSchema = z.object({
id: z.string().uuid(),
});
export type GetUserByIdRequest = z.infer<typeof GetUserByIdRequestSchema>;
export type GetUserByIdResponse = UserInfoByIdResponse;