From 5e6eb76f5bc591f07119c60374b7d9b90e5c03dc Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Thu, 24 Jul 2025 17:33:37 -0600 Subject: [PATCH] move get asset types around --- apps/server/src/api/v2/title/GET.ts | 11 ++++----- packages/database/src/queries/assets/index.ts | 23 ------------------- .../get-collection-title.ts | 11 ++++++--- .../database/src/queries/collections/index.ts | 5 ++++ .../{assets => dashboards}/dashboards.ts | 0 .../get-dashboard-title.ts | 11 ++++++--- .../database/src/queries/dashboards/index.ts | 11 +++++++++ packages/database/src/queries/index.ts | 3 +++ .../{assets => metrics}/get-metric-title.ts | 11 ++++++--- .../database/src/queries/metrics/index.ts | 5 ++++ packages/server-shared/src/title/requests.ts | 3 ++- 11 files changed, 54 insertions(+), 40 deletions(-) rename packages/database/src/queries/{assets => collections}/get-collection-title.ts (67%) create mode 100644 packages/database/src/queries/collections/index.ts rename packages/database/src/queries/{assets => dashboards}/dashboards.ts (100%) rename packages/database/src/queries/{assets => dashboards}/get-dashboard-title.ts (68%) create mode 100644 packages/database/src/queries/dashboards/index.ts rename packages/database/src/queries/{assets => metrics}/get-metric-title.ts (68%) create mode 100644 packages/database/src/queries/metrics/index.ts diff --git a/apps/server/src/api/v2/title/GET.ts b/apps/server/src/api/v2/title/GET.ts index c5fb7579a..5a18c3127 100644 --- a/apps/server/src/api/v2/title/GET.ts +++ b/apps/server/src/api/v2/title/GET.ts @@ -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; diff --git a/packages/database/src/queries/assets/index.ts b/packages/database/src/queries/assets/index.ts index cbc76ec58..b14d13084 100644 --- a/packages/database/src/queries/assets/index.ts +++ b/packages/database/src/queries/assets/index.ts @@ -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'; diff --git a/packages/database/src/queries/assets/get-collection-title.ts b/packages/database/src/queries/collections/get-collection-title.ts similarity index 67% rename from packages/database/src/queries/assets/get-collection-title.ts rename to packages/database/src/queries/collections/get-collection-title.ts index 1d98c61cc..a4722d300 100644 --- a/packages/database/src/queries/assets/get-collection-title.ts +++ b/packages/database/src/queries/collections/get-collection-title.ts @@ -10,7 +10,8 @@ export const GetCollectionTitleInputSchema = z.object({ export type GetCollectionTitleInput = z.infer; -export async function getCollectionTitle(input: GetCollectionTitleInput): Promise { +// Updated return type to remove null since we now throw an error instead +export async function getCollectionTitle(input: GetCollectionTitleInput): Promise { 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; diff --git a/packages/database/src/queries/collections/index.ts b/packages/database/src/queries/collections/index.ts new file mode 100644 index 000000000..1bc049c9e --- /dev/null +++ b/packages/database/src/queries/collections/index.ts @@ -0,0 +1,5 @@ +export { + getCollectionTitle, + GetCollectionTitleInputSchema, + type GetCollectionTitleInput, +} from './get-collection-title'; diff --git a/packages/database/src/queries/assets/dashboards.ts b/packages/database/src/queries/dashboards/dashboards.ts similarity index 100% rename from packages/database/src/queries/assets/dashboards.ts rename to packages/database/src/queries/dashboards/dashboards.ts diff --git a/packages/database/src/queries/assets/get-dashboard-title.ts b/packages/database/src/queries/dashboards/get-dashboard-title.ts similarity index 68% rename from packages/database/src/queries/assets/get-dashboard-title.ts rename to packages/database/src/queries/dashboards/get-dashboard-title.ts index 63dd9417a..7425c919b 100644 --- a/packages/database/src/queries/assets/get-dashboard-title.ts +++ b/packages/database/src/queries/dashboards/get-dashboard-title.ts @@ -10,7 +10,8 @@ export const GetDashboardTitleInputSchema = z.object({ export type GetDashboardTitleInput = z.infer; -export async function getDashboardTitle(input: GetDashboardTitleInput): Promise { +// Updated return type to remove null since we now throw an error instead +export async function getDashboardTitle(input: GetDashboardTitleInput): Promise { 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; diff --git a/packages/database/src/queries/dashboards/index.ts b/packages/database/src/queries/dashboards/index.ts new file mode 100644 index 000000000..b284f5a8f --- /dev/null +++ b/packages/database/src/queries/dashboards/index.ts @@ -0,0 +1,11 @@ +export { + getChatDashboardFiles, + type DashboardFileContext, + type DashboardFile, +} from './dashboards'; + +export { + getDashboardTitle, + GetDashboardTitleInputSchema, + type GetDashboardTitleInput, +} from './get-dashboard-title'; diff --git a/packages/database/src/queries/index.ts b/packages/database/src/queries/index.ts index 278c06028..bc72287e2 100644 --- a/packages/database/src/queries/index.ts +++ b/packages/database/src/queries/index.ts @@ -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'; diff --git a/packages/database/src/queries/assets/get-metric-title.ts b/packages/database/src/queries/metrics/get-metric-title.ts similarity index 68% rename from packages/database/src/queries/assets/get-metric-title.ts rename to packages/database/src/queries/metrics/get-metric-title.ts index 6da66797b..5fe548ac4 100644 --- a/packages/database/src/queries/assets/get-metric-title.ts +++ b/packages/database/src/queries/metrics/get-metric-title.ts @@ -10,7 +10,8 @@ export const GetMetricTitleInputSchema = z.object({ export type GetMetricTitleInput = z.infer; -export async function getMetricTitle(input: GetMetricTitleInput): Promise { +// Updated return type to remove null since we now throw an error instead +export async function getMetricTitle(input: GetMetricTitleInput): Promise { const validated = GetMetricTitleInputSchema.parse(input); const [metric] = await db @@ -23,12 +24,16 @@ export async function getMetricTitle(input: GetMetricTitleInput): Promise;