fix type sharing in server-shared

This commit is contained in:
Wells Bunker 2025-09-11 10:04:17 -06:00
parent 01f3f2dde3
commit 4dc7ec62bf
No known key found for this signature in database
GPG Key ID: DB16D6F2679B78FC
8 changed files with 67 additions and 62 deletions

View File

@ -2,7 +2,7 @@ import { generateSuggestedMessages } from '@buster/ai';
import {
DEFAULT_USER_SUGGESTED_PROMPTS,
type User,
type UserSuggestedPromptsField,
type UserSuggestedPromptsType,
getPermissionedDatasets,
getUserRecentMessages,
getUserSuggestedPrompts,
@ -28,7 +28,7 @@ describe('GET /api/v2/users/:id/suggested-prompts', () => {
// Use actual DEFAULT_USER_SUGGESTED_PROMPTS instead of mock
const mockTodayPrompts: UserSuggestedPromptsField = {
const mockTodayPrompts: UserSuggestedPromptsType = {
suggestedPrompts: {
report: ['Generate Q4 sales report'],
dashboard: ['Create revenue dashboard'],
@ -38,7 +38,7 @@ describe('GET /api/v2/users/:id/suggested-prompts', () => {
updatedAt: new Date().toISOString(), // Today's date
};
const mockOldPrompts: UserSuggestedPromptsField = {
const mockOldPrompts: UserSuggestedPromptsType = {
suggestedPrompts: {
report: ['Old report prompt'],
dashboard: ['Old dashboard prompt'],
@ -55,7 +55,7 @@ describe('GET /api/v2/users/:id/suggested-prompts', () => {
help: ['New AI generated help'],
};
const mockUpdatedPrompts: UserSuggestedPromptsField = {
const mockUpdatedPrompts: UserSuggestedPromptsType = {
suggestedPrompts: mockGeneratedPrompts,
updatedAt: new Date().toISOString(),
};

View File

@ -1,42 +1,38 @@
import { generateSuggestedMessages } from '@buster/ai';
import {
DEFAULT_USER_SUGGESTED_PROMPTS,
type UserSuggestedPromptsField,
type UserSuggestedPromptsType,
getPermissionedDatasets,
getUserRecentMessages,
getUserSuggestedPrompts,
updateUserSuggestedPrompts,
} from '@buster/database';
import { GetSuggestedPromptsRequestSchema, type GetSuggestedPromptsResponse } from '@buster/server-shared/user';
import { zValidator } from '@hono/zod-validator';
import { Hono } from 'hono';
import { HTTPException } from 'hono/http-exception';
import { z } from 'zod';
const GetSuggestedPromptsRequestParams = z.object({
id: z.string().uuid(),
});
import { standardErrorHandler } from '../../../../../utils/response';
const app = new Hono().get(
'/',
zValidator('param', GetSuggestedPromptsRequestParams),
zValidator('param', GetSuggestedPromptsRequestSchema),
async (c) => {
try {
const userId = c.req.param('id');
const authenticatedUser = c.get('busterUser');
const userId = c.req.param('id');
const authenticatedUser = c.get('busterUser');
// Authorization check: Users can only access their own suggested prompts
if (authenticatedUser.id !== userId) {
throw new HTTPException(403, {
message: 'Forbidden: You can only access your own suggested prompts',
});
}
// Authorization check: Users can only access their own suggested prompts
if (authenticatedUser.id !== userId) {
throw new HTTPException(403, {
message: 'Forbidden: You can only access your own suggested prompts',
});
}
const currentSuggestedPrompts = await getUserSuggestedPrompts({ userId });
const currentSuggestedPrompts: GetSuggestedPromptsResponse = await getUserSuggestedPrompts({ userId });
if (currentSuggestedPrompts) {
// Check if the updatedAt date is from today
const today = new Date();
const updatedDate = new Date(currentSuggestedPrompts.updatedAt);
if (currentSuggestedPrompts) {
// Check if the updatedAt date is from today
const today = new Date();
const updatedDate = new Date(currentSuggestedPrompts.updatedAt);
const isToday =
today.getFullYear() === updatedDate.getFullYear() &&
@ -58,33 +54,25 @@ const app = new Hono().get(
}, timeoutMs);
});
try {
const newPrompts = await Promise.race([buildNewSuggestedPrompts(userId), timeoutPromise]);
return c.json(newPrompts);
} catch {
if (currentSuggestedPrompts) {
return c.json(currentSuggestedPrompts);
}
return c.json(DEFAULT_USER_SUGGESTED_PROMPTS);
try {
const newPrompts: GetSuggestedPromptsResponse = await Promise.race([buildNewSuggestedPrompts(userId), timeoutPromise]);
return c.json(newPrompts);
} catch {
if (currentSuggestedPrompts) {
return c.json(currentSuggestedPrompts);
}
} catch (error) {
if (error instanceof HTTPException) {
throw error;
}
console.error('[GetSuggestedPrompts] Error:', error);
throw new HTTPException(500, {
message: 'Error fetching suggested prompts',
});
const defaultPrompts: GetSuggestedPromptsResponse = DEFAULT_USER_SUGGESTED_PROMPTS;
return c.json(defaultPrompts);
}
}
);
)
.onError(standardErrorHandler);
/**
* Generate new suggested prompts for a user and update the database with the new prompts
* Returns the updated prompts
*/
async function buildNewSuggestedPrompts(userId: string): Promise<UserSuggestedPromptsField> {
async function buildNewSuggestedPrompts(userId: string): Promise<UserSuggestedPromptsType> {
try {
const [databaseContext, chatHistoryText] = await Promise.all([
getDatabaseContext(userId),

View File

@ -2,7 +2,7 @@ import { eq } from 'drizzle-orm';
import { z } from 'zod';
import { db } from '../../connection';
import { users } from '../../schema';
import type { UserSuggestedPromptsField } from '../../schema-types';
import type { UserSuggestedPromptsType } from '../../schema-types';
// Input validation schemas
const UpdateSuggestedPromptsInputSchema = z.object({
@ -27,11 +27,11 @@ type GetSuggestedPromptsInput = z.infer<typeof GetSuggestedPromptsInputSchema>;
*/
export async function updateUserSuggestedPrompts(
params: UpdateSuggestedPromptsInput
): Promise<UserSuggestedPromptsField> {
): Promise<UserSuggestedPromptsType> {
try {
const { userId, suggestedPrompts } = UpdateSuggestedPromptsInputSchema.parse(params);
const updatedPrompts: UserSuggestedPromptsField = {
const updatedPrompts: UserSuggestedPromptsType = {
suggestedPrompts: suggestedPrompts,
updatedAt: new Date().toISOString(),
};
@ -65,7 +65,7 @@ export async function updateUserSuggestedPrompts(
*/
export async function getUserSuggestedPrompts(
params: GetSuggestedPromptsInput
): Promise<UserSuggestedPromptsField> {
): Promise<UserSuggestedPromptsType> {
try {
const { userId } = GetSuggestedPromptsInputSchema.parse(params);

View File

@ -1,15 +1,19 @@
// User Suggested Prompts Types
export type UserSuggestedPromptsField = {
suggestedPrompts: {
report: string[];
dashboard: string[];
visualization: string[];
help: string[];
};
updatedAt: string;
};
import { z } from 'zod';
export const DEFAULT_USER_SUGGESTED_PROMPTS: UserSuggestedPromptsField = {
export const UserSuggestedPromptsSchema = z.object({
suggestedPrompts: z.object({
report: z.array(z.string()),
dashboard: z.array(z.string()),
visualization: z.array(z.string()),
help: z.array(z.string()),
}),
updatedAt: z.string(),
});
// User Suggested Prompts Types
export type UserSuggestedPromptsType = z.infer<typeof UserSuggestedPromptsSchema>;
export const DEFAULT_USER_SUGGESTED_PROMPTS: UserSuggestedPromptsType = {
suggestedPrompts: {
report: [
'provide a trend analysis of quarterly profits',

View File

@ -19,7 +19,7 @@ import {
uuid,
varchar,
} from 'drizzle-orm/pg-core';
import type { OrganizationColorPalettes, UserSuggestedPromptsField } from './schema-types';
import type { OrganizationColorPalettes, UserSuggestedPromptsType } from './schema-types';
import { DEFAULT_USER_SUGGESTED_PROMPTS } from './schema-types/user';
export const assetPermissionRoleEnum = pgEnum('asset_permission_role_enum', [
@ -867,7 +867,7 @@ export const users = pgTable(
attributes: jsonb().default({}).notNull(),
avatarUrl: text('avatar_url'),
suggestedPrompts: jsonb('suggested_prompts')
.$type<UserSuggestedPromptsField>()
.$type<UserSuggestedPromptsType>()
.default(DEFAULT_USER_SUGGESTED_PROMPTS)
.notNull(),
},

View File

@ -23,7 +23,7 @@ export type {
} from './schemas/message-schemas';
// Export schema-types to use across the codebase
export type { UserSuggestedPromptsField } from './schema-types';
export type { UserSuggestedPromptsType } from './schema-types';
// Export default user suggested prompts
export { DEFAULT_USER_SUGGESTED_PROMPTS } from './schema-types/user';

View File

@ -5,3 +5,4 @@ export * from './roles.types';
export * from '../teams/teams.types';
export * from './sharing-setting.types';
export * from './favorites.types';
export * from './suggested-prompts.types';

View File

@ -0,0 +1,12 @@
import type { UserSuggestedPromptsType } from '@buster/database';
import { UserSuggestedPromptsSchema } from '@buster/database';
import { z } from 'zod';
export const GetSuggestedPromptsRequestSchema = z.object({
id: z.string().uuid(),
});
export const GetSuggestedPromptsResponseSchema = UserSuggestedPromptsSchema;
export type GetSuggestedPromptsRequest = z.infer<typeof GetSuggestedPromptsRequestSchema>;
export type GetSuggestedPromptsResponse = UserSuggestedPromptsType;