move get asset types around

This commit is contained in:
Nate Kelley 2025-07-24 17:33:37 -06:00
parent b2cf1725fc
commit 5e6eb76f5b
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
11 changed files with 54 additions and 40 deletions

View File

@ -20,24 +20,21 @@ const app = new Hono()
const user = c.get('busterUser');
const userOrg = await getUserOrganizationId(user.id);
if (!userOrg) {
throw new HTTPException(403, { message: 'User is not associated with an organization' });
}
let title: string | null = null;
switch (assetType) {
case 'chat':
title = await getChatTitle({ assetId, organizationId: userOrg.organizationId });
title = await getChatTitle({ assetId, organizationId: userOrg?.organizationId });
break;
case 'metric':
title = await getMetricTitle({ assetId, organizationId: userOrg.organizationId });
title = await getMetricTitle({ assetId, organizationId: userOrg?.organizationId });
break;
case 'collection':
title = await getCollectionTitle({ assetId, organizationId: userOrg.organizationId });
title = await getCollectionTitle({ assetId, organizationId: userOrg?.organizationId });
break;
case 'dashboard':
title = await getDashboardTitle({ assetId, organizationId: userOrg.organizationId });
title = await getDashboardTitle({ assetId, organizationId: userOrg?.organizationId });
break;
default: {
const _exhaustive: never = assetType;

View File

@ -6,27 +6,4 @@ export {
type GenerateAssetMessagesInput,
} from './assets';
export {
getChatDashboardFiles,
type DashboardFileContext,
type DashboardFile,
} from './dashboards';
export {
getMetricTitle,
GetMetricTitleInputSchema,
type GetMetricTitleInput,
} from './get-metric-title';
export {
getCollectionTitle,
GetCollectionTitleInputSchema,
type GetCollectionTitleInput,
} from './get-collection-title';
export {
getDashboardTitle,
GetDashboardTitleInputSchema,
type GetDashboardTitleInput,
} from './get-dashboard-title';
export type { DatabaseAssetType } from './assets';

View File

@ -10,7 +10,8 @@ export const GetCollectionTitleInputSchema = z.object({
export type GetCollectionTitleInput = z.infer<typeof GetCollectionTitleInputSchema>;
export async function getCollectionTitle(input: GetCollectionTitleInput): Promise<string | null> {
// Updated return type to remove null since we now throw an error instead
export async function getCollectionTitle(input: GetCollectionTitleInput): Promise<string> {
const validated = GetCollectionTitleInputSchema.parse(input);
const [collection] = await db
@ -22,12 +23,16 @@ export async function getCollectionTitle(input: GetCollectionTitleInput): Promis
.where(and(eq(collections.id, validated.assetId), isNull(collections.deletedAt)))
.limit(1);
// Throw error instead of returning null
if (!collection) {
return null;
throw new Error(`Collection with ID ${validated.assetId} not found`);
}
// Throw error for permission failure instead of returning null
if (collection.organizationId !== validated.organizationId) {
return null;
throw new Error(
`Access denied: Collection with ID ${validated.assetId} does not belong to the specified organization`
);
}
return collection.name;

View File

@ -0,0 +1,5 @@
export {
getCollectionTitle,
GetCollectionTitleInputSchema,
type GetCollectionTitleInput,
} from './get-collection-title';

View File

@ -10,7 +10,8 @@ export const GetDashboardTitleInputSchema = z.object({
export type GetDashboardTitleInput = z.infer<typeof GetDashboardTitleInputSchema>;
export async function getDashboardTitle(input: GetDashboardTitleInput): Promise<string | null> {
// Updated return type to remove null since we now throw an error instead
export async function getDashboardTitle(input: GetDashboardTitleInput): Promise<string> {
const validated = GetDashboardTitleInputSchema.parse(input);
const [dashboard] = await db
@ -23,12 +24,16 @@ export async function getDashboardTitle(input: GetDashboardTitleInput): Promise<
.where(and(eq(dashboardFiles.id, validated.assetId), isNull(dashboardFiles.deletedAt)))
.limit(1);
// Throw error instead of returning null
if (!dashboard) {
return null;
throw new Error(`Dashboard with ID ${validated.assetId} not found`);
}
// Throw error for permission failure instead of returning null
if (!dashboard.publiclyAccessible && dashboard.organizationId !== validated.organizationId) {
return null;
throw new Error(
`Access denied: Dashboard with ID ${validated.assetId} is not publicly accessible and does not belong to the specified organization`
);
}
return dashboard.name;

View File

@ -0,0 +1,11 @@
export {
getChatDashboardFiles,
type DashboardFileContext,
type DashboardFile,
} from './dashboards';
export {
getDashboardTitle,
GetDashboardTitleInputSchema,
type GetDashboardTitleInput,
} from './get-dashboard-title';

View File

@ -5,3 +5,6 @@ export * from './assets';
export * from './metadata';
export * from './chats';
export * from './organizations';
export * from './dashboards';
export * from './metrics';
export * from './collections';

View File

@ -10,7 +10,8 @@ export const GetMetricTitleInputSchema = z.object({
export type GetMetricTitleInput = z.infer<typeof GetMetricTitleInputSchema>;
export async function getMetricTitle(input: GetMetricTitleInput): Promise<string | null> {
// Updated return type to remove null since we now throw an error instead
export async function getMetricTitle(input: GetMetricTitleInput): Promise<string> {
const validated = GetMetricTitleInputSchema.parse(input);
const [metric] = await db
@ -23,12 +24,16 @@ export async function getMetricTitle(input: GetMetricTitleInput): Promise<string
.where(and(eq(metricFiles.id, validated.assetId), isNull(metricFiles.deletedAt)))
.limit(1);
// Throw error instead of returning null
if (!metric) {
return null;
throw new Error(`Metric with ID ${validated.assetId} not found`);
}
// Throw error for permission failure instead of returning null
if (!metric.publiclyAccessible && metric.organizationId !== validated.organizationId) {
return null;
throw new Error(
`Access denied: Metric with ID ${validated.assetId} is not publicly accessible and does not belong to the specified organization`
);
}
return metric.name;

View File

@ -0,0 +1,5 @@
export {
getMetricTitle,
GetMetricTitleInputSchema,
type GetMetricTitleInput,
} from './get-metric-title';

View File

@ -1,8 +1,9 @@
import { z } from 'zod';
import { AssetTypeSchema } from '../assets/asset-types.types';
export const GetTitleRequestSchema = z.object({
assetId: z.string().uuid(),
assetType: z.enum(['chat', 'metric', 'collection', 'dashboard']),
assetType: AssetTypeSchema,
});
export type GetTitleRequest = z.infer<typeof GetTitleRequestSchema>;