diff --git a/apps/admin/src/app/organizations/[orgId]/org-metrics.tsx b/apps/admin/src/app/organizations/[orgId]/org-metrics.tsx index dc070c94ef..46044d9633 100644 --- a/apps/admin/src/app/organizations/[orgId]/org-metrics.tsx +++ b/apps/admin/src/app/organizations/[orgId]/org-metrics.tsx @@ -7,7 +7,7 @@ import { Loader2, Server, } from "lucide-react"; -import { useCallback, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { Button } from "@/components/ui/button"; import { @@ -90,7 +90,7 @@ function MetricCard({ export function OrgMetricsSection({ orgId }: { orgId: string }) { const [metrics, setMetrics] = useState(null); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); const [window, setWindow] = useState("1d"); const loadMetrics = useCallback( @@ -103,35 +103,14 @@ export function OrgMetricsSection({ orgId }: { orgId: string }) { [orgId], ); - const handleWindowChange = useCallback( - (w: TokenWindow) => { - setWindow(w); - loadMetrics(w); - }, - [loadMetrics], - ); + // Load metrics automatically on mount + useEffect(() => { + loadMetrics(window); + }, [loadMetrics, window]); - if (!metrics && !loading) { - return ( -
-
-

Usage Metrics

- -
-
- Click "Load Usage Data" to fetch usage metrics. This queries - the logs table which may be slow for orgs with lots of data. -
-
- ); - } + const handleWindowChange = useCallback((w: TokenWindow) => { + setWindow(w); + }, []); if (loading) { return ( @@ -146,7 +125,14 @@ export function OrgMetricsSection({ orgId }: { orgId: string }) { } if (!metrics) { - return null; + return ( +
+

Usage Metrics

+
+ No usage data available. +
+
+ ); } const windowLabel = window === "7d" ? "Last 7 days" : "Last 24 hours"; diff --git a/apps/admin/src/lib/api/v1.d.ts b/apps/admin/src/lib/api/v1.d.ts index 0468f37d52..5d9581086b 100644 --- a/apps/admin/src/lib/api/v1.d.ts +++ b/apps/admin/src/lib/api/v1.d.ts @@ -981,6 +981,14 @@ export interface paths { cacheCount: number; cacheRate: number; discountSavings: number; + creditsRequestCount: number; + apiKeysRequestCount: number; + creditsCost: number; + apiKeysCost: number; + creditsServiceFee: number; + apiKeysServiceFee: number; + creditsDataStorageCost: number; + apiKeysDataStorageCost: number; modelBreakdown: { id: string; provider: string; diff --git a/apps/api/src/routes/activity.spec.ts b/apps/api/src/routes/activity.spec.ts index b1a78a1854..9e2a9a1453 100644 --- a/apps/api/src/routes/activity.spec.ts +++ b/apps/api/src/routes/activity.spec.ts @@ -1,7 +1,11 @@ import { afterEach, beforeEach, describe, expect, test } from "vitest"; import { app } from "@/index.js"; -import { createTestUser, deleteAll } from "@/testing.js"; +import { + createTestUser, + deleteAll, + aggregateLogsForTesting, +} from "@/testing.js"; import { db, tables } from "@llmgateway/db"; @@ -173,6 +177,9 @@ describe("activity endpoint", () => { usedMode: "api-keys", }, ]); + + // Aggregate logs into the hourly stats tables for the activity endpoint + await aggregateLogsForTesting(); }); afterEach(async () => { @@ -335,6 +342,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, @@ -513,6 +522,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, @@ -628,6 +639,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, @@ -727,6 +740,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, @@ -830,6 +845,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, @@ -855,6 +872,7 @@ describe("activity endpoint", () => { test("GET /activity should return zero error rate and cache rate when no requests", async () => { await db.delete(tables.log); + await aggregateLogsForTesting(); const res = await app.request("/activity?days=7", { headers: { @@ -944,6 +962,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, @@ -1037,6 +1057,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, @@ -1129,6 +1151,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, @@ -1202,6 +1226,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, @@ -1275,6 +1301,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, @@ -1453,6 +1481,8 @@ describe("activity endpoint", () => { }, ]); + await aggregateLogsForTesting(); + const res = await app.request("/activity?days=7", { headers: { Cookie: token, diff --git a/apps/api/src/routes/activity.ts b/apps/api/src/routes/activity.ts index 76f5eaf538..c3746a909f 100644 --- a/apps/api/src/routes/activity.ts +++ b/apps/api/src/routes/activity.ts @@ -4,7 +4,19 @@ import { z } from "zod"; import { getUserOrganizationIds } from "@/utils/authorization.js"; -import { db, sql, tables, inArray, and, gte, lte, eq } from "@llmgateway/db"; +import { + db, + sql, + inArray, + and, + gte, + lte, + eq, + projectHourlyStats, + projectHourlyModelStats, + apiKeyHourlyStats, + apiKeyHourlyModelStats, +} from "@llmgateway/db"; import type { ServerTypes } from "@/vars.js"; @@ -42,6 +54,14 @@ const dailyActivitySchema = z.object({ cacheCount: z.number(), cacheRate: z.number(), discountSavings: z.number(), + creditsRequestCount: z.number(), + apiKeysRequestCount: z.number(), + creditsCost: z.number(), + apiKeysCost: z.number(), + creditsServiceFee: z.number(), + apiKeysServiceFee: z.number(), + creditsDataStorageCost: z.number(), + apiKeysDataStorageCost: z.number(), modelBreakdown: z.array(modelUsageSchema), }); @@ -126,119 +146,406 @@ activity.openapi(getActivity, async (c) => { }); } - // Query daily aggregated data using database-level aggregation - const dailyAggregates = await db + // If filtering by apiKeyId, use the apiKeyHourlyStats aggregation table + if (apiKeyId) { + // Query daily aggregated data from apiKeyHourlyStats table + const hourlyAggregates = await db + .select({ + date: sql`DATE(${apiKeyHourlyStats.hourTimestamp})`.as("date"), + requestCount: + sql`COALESCE(SUM(${apiKeyHourlyStats.requestCount}), 0)`.as( + "requestCount", + ), + inputTokens: + sql`COALESCE(SUM(CAST(${apiKeyHourlyStats.inputTokens} AS NUMERIC)), 0)`.as( + "inputTokens", + ), + outputTokens: + sql`COALESCE(SUM(CAST(${apiKeyHourlyStats.outputTokens} AS NUMERIC)), 0)`.as( + "outputTokens", + ), + totalTokens: + sql`COALESCE(SUM(CAST(${apiKeyHourlyStats.totalTokens} AS NUMERIC)), 0)`.as( + "totalTokens", + ), + cost: sql`COALESCE(SUM(${apiKeyHourlyStats.cost}), 0)`.as( + "cost", + ), + inputCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.inputCost}), 0)`.as( + "inputCost", + ), + outputCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.outputCost}), 0)`.as( + "outputCost", + ), + requestCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.requestCost}), 0)`.as( + "requestCost", + ), + dataStorageCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.dataStorageCost}), 0)`.as( + "dataStorageCost", + ), + errorCount: + sql`COALESCE(SUM(${apiKeyHourlyStats.errorCount}), 0)`.as( + "errorCount", + ), + cacheCount: + sql`COALESCE(SUM(${apiKeyHourlyStats.cacheCount}), 0)`.as( + "cacheCount", + ), + discountSavings: + sql`COALESCE(SUM(${apiKeyHourlyStats.discountSavings}), 0)`.as( + "discountSavings", + ), + imageInputCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.imageInputCost}), 0)`.as( + "imageInputCost", + ), + imageOutputCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.imageOutputCost}), 0)`.as( + "imageOutputCost", + ), + cachedTokens: + sql`COALESCE(SUM(CAST(${apiKeyHourlyStats.cachedTokens} AS NUMERIC)), 0)`.as( + "cachedTokens", + ), + cachedInputCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.cachedInputCost}), 0)`.as( + "cachedInputCost", + ), + creditsRequestCount: + sql`COALESCE(SUM(${apiKeyHourlyStats.creditsRequestCount}), 0)`.as( + "creditsRequestCount", + ), + apiKeysRequestCount: + sql`COALESCE(SUM(${apiKeyHourlyStats.apiKeysRequestCount}), 0)`.as( + "apiKeysRequestCount", + ), + creditsCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.creditsCost}), 0)`.as( + "creditsCost", + ), + apiKeysCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.apiKeysCost}), 0)`.as( + "apiKeysCost", + ), + creditsServiceFee: + sql`COALESCE(SUM(${apiKeyHourlyStats.creditsServiceFee}), 0)`.as( + "creditsServiceFee", + ), + apiKeysServiceFee: + sql`COALESCE(SUM(${apiKeyHourlyStats.apiKeysServiceFee}), 0)`.as( + "apiKeysServiceFee", + ), + creditsDataStorageCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.creditsDataStorageCost}), 0)`.as( + "creditsDataStorageCost", + ), + apiKeysDataStorageCost: + sql`COALESCE(SUM(${apiKeyHourlyStats.apiKeysDataStorageCost}), 0)`.as( + "apiKeysDataStorageCost", + ), + }) + .from(apiKeyHourlyStats) + .where( + and( + eq(apiKeyHourlyStats.apiKeyId, apiKeyId), + inArray(apiKeyHourlyStats.projectId, projectIds), + gte(apiKeyHourlyStats.hourTimestamp, startDate), + lte(apiKeyHourlyStats.hourTimestamp, endDate), + ), + ) + .groupBy(sql`DATE(${apiKeyHourlyStats.hourTimestamp})`) + .orderBy(sql`DATE(${apiKeyHourlyStats.hourTimestamp}) ASC`); + + // Query model breakdown from apiKeyHourlyModelStats table + const modelBreakdowns = await db + .select({ + date: sql`DATE(${apiKeyHourlyModelStats.hourTimestamp})`.as( + "date", + ), + usedModel: apiKeyHourlyModelStats.usedModel, + usedProvider: apiKeyHourlyModelStats.usedProvider, + requestCount: + sql`COALESCE(SUM(${apiKeyHourlyModelStats.requestCount}), 0)`.as( + "requestCount", + ), + inputTokens: + sql`COALESCE(SUM(CAST(${apiKeyHourlyModelStats.inputTokens} AS NUMERIC)), 0)`.as( + "inputTokens", + ), + outputTokens: + sql`COALESCE(SUM(CAST(${apiKeyHourlyModelStats.outputTokens} AS NUMERIC)), 0)`.as( + "outputTokens", + ), + totalTokens: + sql`COALESCE(SUM(CAST(${apiKeyHourlyModelStats.totalTokens} AS NUMERIC)), 0)`.as( + "totalTokens", + ), + cost: sql`COALESCE(SUM(${apiKeyHourlyModelStats.cost}), 0)`.as( + "cost", + ), + }) + .from(apiKeyHourlyModelStats) + .where( + and( + eq(apiKeyHourlyModelStats.apiKeyId, apiKeyId), + inArray(apiKeyHourlyModelStats.projectId, projectIds), + gte(apiKeyHourlyModelStats.hourTimestamp, startDate), + lte(apiKeyHourlyModelStats.hourTimestamp, endDate), + ), + ) + .groupBy( + sql`DATE(${apiKeyHourlyModelStats.hourTimestamp}), ${apiKeyHourlyModelStats.usedModel}, ${apiKeyHourlyModelStats.usedProvider}`, + ) + .orderBy( + sql`DATE(${apiKeyHourlyModelStats.hourTimestamp}) ASC, ${apiKeyHourlyModelStats.usedModel} ASC`, + ); + + const modelBreakdownByDate = new Map< + string, + z.infer[] + >(); + for (const breakdown of modelBreakdowns) { + if (!modelBreakdownByDate.has(breakdown.date)) { + modelBreakdownByDate.set(breakdown.date, []); + } + modelBreakdownByDate.get(breakdown.date)!.push({ + id: breakdown.usedModel || "unknown", + provider: breakdown.usedProvider || "unknown", + requestCount: Number(breakdown.requestCount), + inputTokens: Number(breakdown.inputTokens), + outputTokens: Number(breakdown.outputTokens), + totalTokens: Number(breakdown.totalTokens), + cost: Number(breakdown.cost), + }); + } + + // Process daily aggregates and add calculated fields + const activityData = hourlyAggregates.map((day) => { + const requestCount = Number(day.requestCount); + const inputTokens = Number(day.inputTokens); + const outputTokens = Number(day.outputTokens); + const cachedTokens = Number(day.cachedTokens); + const totalTokens = Number(day.totalTokens); + const cost = Number(day.cost); + const inputCost = Number(day.inputCost); + const outputCost = Number(day.outputCost); + const requestCost = Number(day.requestCost); + const dataStorageCost = Number(day.dataStorageCost); + const errorCount = Number(day.errorCount); + const cacheCount = Number(day.cacheCount); + const discountSavings = Number(day.discountSavings); + const imageInputCost = Number(day.imageInputCost); + const imageOutputCost = Number(day.imageOutputCost); + const cachedInputCost = Number(day.cachedInputCost); + + const creditsRequestCount = Number(day.creditsRequestCount); + const apiKeysRequestCount = Number(day.apiKeysRequestCount); + const creditsCost = Number(day.creditsCost); + const apiKeysCost = Number(day.apiKeysCost); + const creditsServiceFee = Number(day.creditsServiceFee); + const apiKeysServiceFee = Number(day.apiKeysServiceFee); + const creditsDataStorageCost = Number(day.creditsDataStorageCost); + const apiKeysDataStorageCost = Number(day.apiKeysDataStorageCost); + + const errorRate = + requestCount > 0 ? (errorCount / requestCount) * 100 : 0; + const cacheRate = + requestCount > 0 ? (cacheCount / requestCount) * 100 : 0; + + return { + date: day.date, + requestCount, + inputTokens, + outputTokens, + cachedTokens, + totalTokens, + cost, + inputCost, + outputCost, + requestCost, + dataStorageCost, + imageInputCost, + imageOutputCost, + cachedInputCost, + errorCount, + errorRate, + cacheCount, + cacheRate, + discountSavings, + creditsRequestCount, + apiKeysRequestCount, + creditsCost, + apiKeysCost, + creditsServiceFee, + apiKeysServiceFee, + creditsDataStorageCost, + apiKeysDataStorageCost, + modelBreakdown: modelBreakdownByDate.get(day.date) || [], + }; + }); + + return c.json({ + activity: activityData, + }); + } + + // Use aggregation tables for fast queries (when not filtering by apiKeyId) + // Query hourly aggregated data from projectHourlyStats table + const hourlyAggregates = await db .select({ - date: sql`DATE(${tables.log.createdAt})`.as("date"), - requestCount: sql`COUNT(*)`.as("requestCount"), + date: sql`DATE(${projectHourlyStats.hourTimestamp})`.as("date"), + requestCount: + sql`COALESCE(SUM(${projectHourlyStats.requestCount}), 0)`.as( + "requestCount", + ), inputTokens: - sql`COALESCE(SUM(CAST(${tables.log.promptTokens} AS NUMERIC)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyStats.inputTokens} AS NUMERIC)), 0)`.as( "inputTokens", ), outputTokens: - sql`COALESCE(SUM(CAST(${tables.log.completionTokens} AS NUMERIC)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyStats.outputTokens} AS NUMERIC)), 0)`.as( "outputTokens", ), cachedTokens: - sql`COALESCE(SUM(CAST(${tables.log.cachedTokens} AS NUMERIC)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyStats.cachedTokens} AS NUMERIC)), 0)`.as( "cachedTokens", ), totalTokens: - sql`COALESCE(SUM(CAST(${tables.log.totalTokens} AS NUMERIC)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyStats.totalTokens} AS NUMERIC)), 0)`.as( "totalTokens", ), - cost: sql`COALESCE(SUM(${tables.log.cost}), 0)`.as("cost"), - inputCost: sql`COALESCE(SUM(${tables.log.inputCost}), 0)`.as( - "inputCost", - ), - outputCost: sql`COALESCE(SUM(${tables.log.outputCost}), 0)`.as( - "outputCost", - ), - requestCost: sql`COALESCE(SUM(${tables.log.requestCost}), 0)`.as( - "requestCost", + cost: sql`COALESCE(SUM(${projectHourlyStats.cost}), 0)`.as( + "cost", ), + inputCost: + sql`COALESCE(SUM(${projectHourlyStats.inputCost}), 0)`.as( + "inputCost", + ), + outputCost: + sql`COALESCE(SUM(${projectHourlyStats.outputCost}), 0)`.as( + "outputCost", + ), + requestCost: + sql`COALESCE(SUM(${projectHourlyStats.requestCost}), 0)`.as( + "requestCost", + ), dataStorageCost: - sql`COALESCE(SUM(${tables.log.dataStorageCost}), 0)`.as( + sql`COALESCE(SUM(${projectHourlyStats.dataStorageCost}), 0)`.as( "dataStorageCost", ), imageInputCost: - sql`COALESCE(SUM(${tables.log.imageInputCost}), 0)`.as( + sql`COALESCE(SUM(${projectHourlyStats.imageInputCost}), 0)`.as( "imageInputCost", ), imageOutputCost: - sql`COALESCE(SUM(${tables.log.imageOutputCost}), 0)`.as( + sql`COALESCE(SUM(${projectHourlyStats.imageOutputCost}), 0)`.as( "imageOutputCost", ), cachedInputCost: - sql`COALESCE(SUM(${tables.log.cachedInputCost}), 0)`.as( + sql`COALESCE(SUM(${projectHourlyStats.cachedInputCost}), 0)`.as( "cachedInputCost", ), errorCount: - sql`SUM(CASE WHEN ${tables.log.hasError} = true THEN 1 ELSE 0 END)`.as( + sql`COALESCE(SUM(${projectHourlyStats.errorCount}), 0)`.as( "errorCount", ), cacheCount: - sql`SUM(CASE WHEN ${tables.log.cached} = true THEN 1 ELSE 0 END)`.as( + sql`COALESCE(SUM(${projectHourlyStats.cacheCount}), 0)`.as( "cacheCount", ), - discountSavings: sql`COALESCE( - SUM( - CASE - WHEN ${tables.log.discount} > 0 AND ${tables.log.discount} < 1 - THEN ${tables.log.cost} * ${tables.log.discount} / (1 - ${tables.log.discount}) - ELSE 0 - END + discountSavings: + sql`COALESCE(SUM(${projectHourlyStats.discountSavings}), 0)`.as( + "discountSavings", + ), + creditsRequestCount: + sql`COALESCE(SUM(${projectHourlyStats.creditsRequestCount}), 0)`.as( + "creditsRequestCount", + ), + apiKeysRequestCount: + sql`COALESCE(SUM(${projectHourlyStats.apiKeysRequestCount}), 0)`.as( + "apiKeysRequestCount", + ), + creditsCost: + sql`COALESCE(SUM(${projectHourlyStats.creditsCost}), 0)`.as( + "creditsCost", + ), + apiKeysCost: + sql`COALESCE(SUM(${projectHourlyStats.apiKeysCost}), 0)`.as( + "apiKeysCost", + ), + creditsServiceFee: + sql`COALESCE(SUM(${projectHourlyStats.creditsServiceFee}), 0)`.as( + "creditsServiceFee", + ), + apiKeysServiceFee: + sql`COALESCE(SUM(${projectHourlyStats.apiKeysServiceFee}), 0)`.as( + "apiKeysServiceFee", + ), + creditsDataStorageCost: + sql`COALESCE(SUM(${projectHourlyStats.creditsDataStorageCost}), 0)`.as( + "creditsDataStorageCost", + ), + apiKeysDataStorageCost: + sql`COALESCE(SUM(${projectHourlyStats.apiKeysDataStorageCost}), 0)`.as( + "apiKeysDataStorageCost", ), - 0 - )`.as("discountSavings"), }) - .from(tables.log) + .from(projectHourlyStats) .where( and( - inArray(tables.log.projectId, projectIds), - gte(tables.log.createdAt, startDate), - lte(tables.log.createdAt, endDate), - ...(apiKeyId ? [eq(tables.log.apiKeyId, apiKeyId)] : []), + inArray(projectHourlyStats.projectId, projectIds), + gte(projectHourlyStats.hourTimestamp, startDate), + lte(projectHourlyStats.hourTimestamp, endDate), ), ) - .groupBy(sql`DATE(${tables.log.createdAt})`) - .orderBy(sql`DATE(${tables.log.createdAt}) ASC`); + .groupBy(sql`DATE(${projectHourlyStats.hourTimestamp})`) + .orderBy(sql`DATE(${projectHourlyStats.hourTimestamp}) ASC`); - // Query model breakdown data using database-level aggregation + // Query model breakdown from projectHourlyModelStats table const modelBreakdowns = await db .select({ - date: sql`DATE(${tables.log.createdAt})`.as("date"), - usedModel: tables.log.usedModel, - usedProvider: tables.log.usedProvider, - requestCount: sql`COUNT(*)`.as("requestCount"), + date: sql`DATE(${projectHourlyModelStats.hourTimestamp})`.as( + "date", + ), + usedModel: projectHourlyModelStats.usedModel, + usedProvider: projectHourlyModelStats.usedProvider, + requestCount: + sql`COALESCE(SUM(${projectHourlyModelStats.requestCount}), 0)`.as( + "requestCount", + ), inputTokens: - sql`COALESCE(SUM(CAST(${tables.log.promptTokens} AS NUMERIC)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyModelStats.inputTokens} AS NUMERIC)), 0)`.as( "inputTokens", ), outputTokens: - sql`COALESCE(SUM(CAST(${tables.log.completionTokens} AS NUMERIC)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyModelStats.outputTokens} AS NUMERIC)), 0)`.as( "outputTokens", ), totalTokens: - sql`COALESCE(SUM(CAST(${tables.log.totalTokens} AS NUMERIC)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyModelStats.totalTokens} AS NUMERIC)), 0)`.as( "totalTokens", ), - cost: sql`COALESCE(SUM(${tables.log.cost}), 0)`.as("cost"), + cost: sql`COALESCE(SUM(${projectHourlyModelStats.cost}), 0)`.as( + "cost", + ), }) - .from(tables.log) + .from(projectHourlyModelStats) .where( and( - inArray(tables.log.projectId, projectIds), - gte(tables.log.createdAt, startDate), - lte(tables.log.createdAt, endDate), - ...(apiKeyId ? [eq(tables.log.apiKeyId, apiKeyId)] : []), + inArray(projectHourlyModelStats.projectId, projectIds), + gte(projectHourlyModelStats.hourTimestamp, startDate), + lte(projectHourlyModelStats.hourTimestamp, endDate), ), ) .groupBy( - sql`DATE(${tables.log.createdAt}), ${tables.log.usedModel}, ${tables.log.usedProvider}`, + sql`DATE(${projectHourlyModelStats.hourTimestamp}), ${projectHourlyModelStats.usedModel}, ${projectHourlyModelStats.usedProvider}`, ) .orderBy( - sql`DATE(${tables.log.createdAt}) ASC, ${tables.log.usedModel} ASC`, + sql`DATE(${projectHourlyModelStats.hourTimestamp}) ASC, ${projectHourlyModelStats.usedModel} ASC`, ); // Create a map to organize model breakdowns by date @@ -261,8 +568,8 @@ activity.openapi(getActivity, async (c) => { }); } - // Process daily aggregates and add calculated fields - const activityData = dailyAggregates.map((day) => { + // Process hourly aggregates (summed to daily) and add calculated fields + const activityData = hourlyAggregates.map((day) => { // Convert database strings to numbers const requestCount = Number(day.requestCount); const inputTokens = Number(day.inputTokens); @@ -281,6 +588,15 @@ activity.openapi(getActivity, async (c) => { const cacheCount = Number(day.cacheCount); const discountSavings = Number(day.discountSavings); + const creditsRequestCount = Number(day.creditsRequestCount); + const apiKeysRequestCount = Number(day.apiKeysRequestCount); + const creditsCost = Number(day.creditsCost); + const apiKeysCost = Number(day.apiKeysCost); + const creditsServiceFee = Number(day.creditsServiceFee); + const apiKeysServiceFee = Number(day.apiKeysServiceFee); + const creditsDataStorageCost = Number(day.creditsDataStorageCost); + const apiKeysDataStorageCost = Number(day.apiKeysDataStorageCost); + const errorRate = requestCount > 0 ? (errorCount / requestCount) * 100 : 0; const cacheRate = requestCount > 0 ? (cacheCount / requestCount) * 100 : 0; @@ -304,6 +620,14 @@ activity.openapi(getActivity, async (c) => { cacheCount, cacheRate, discountSavings, + creditsRequestCount, + apiKeysRequestCount, + creditsCost, + apiKeysCost, + creditsServiceFee, + apiKeysServiceFee, + creditsDataStorageCost, + apiKeysDataStorageCost, modelBreakdown: modelBreakdownByDate.get(day.date) || [], }; }); diff --git a/apps/api/src/routes/admin.ts b/apps/api/src/routes/admin.ts index 2987899168..2125e7deb0 100644 --- a/apps/api/src/routes/admin.ts +++ b/apps/api/src/routes/admin.ts @@ -17,6 +17,8 @@ import { or, sql, tables, + projectHourlyStats, + projectHourlyModelStats, } from "@llmgateway/db"; import { models, providers } from "@llmgateway/models"; @@ -469,62 +471,87 @@ admin.openapi(getOrganizationMetrics, async (c) => { let mostUsedModelCost = 0; if (projectIds.length > 0) { - const rows = await db + // Query aggregated project stats for totals + const [totals] = await db .select({ - usedModel: tables.log.usedModel, - usedProvider: tables.log.usedProvider, - requestsCount: sql`COUNT(*)`.as("requestsCount"), + totalRequests: + sql`COALESCE(SUM(${projectHourlyStats.requestCount}), 0)`.as( + "totalRequests", + ), inputTokens: - sql`COALESCE(SUM(CAST(${tables.log.promptTokens} AS INTEGER)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyStats.inputTokens} AS INTEGER)), 0)`.as( "inputTokens", ), outputTokens: - sql`COALESCE(SUM(CAST(${tables.log.completionTokens} AS INTEGER)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyStats.outputTokens} AS INTEGER)), 0)`.as( "outputTokens", ), cachedTokens: - sql`COALESCE(SUM(CAST(${tables.log.cachedTokens} AS INTEGER)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyStats.cachedTokens} AS INTEGER)), 0)`.as( "cachedTokens", ), totalTokens: - sql`COALESCE(SUM(CAST(${tables.log.totalTokens} AS INTEGER)), 0)`.as( + sql`COALESCE(SUM(CAST(${projectHourlyStats.totalTokens} AS INTEGER)), 0)`.as( "totalTokens", ), - totalCost: sql`COALESCE(SUM(${tables.log.cost}), 0)`.as( + totalCost: sql`COALESCE(SUM(${projectHourlyStats.cost}), 0)`.as( "totalCost", ), - inputCost: sql`COALESCE(SUM(${tables.log.inputCost}), 0)`.as( - "inputCost", - ), - outputCost: sql`COALESCE(SUM(${tables.log.outputCost}), 0)`.as( - "outputCost", + inputCost: + sql`COALESCE(SUM(${projectHourlyStats.inputCost}), 0)`.as( + "inputCost", + ), + outputCost: + sql`COALESCE(SUM(${projectHourlyStats.outputCost}), 0)`.as( + "outputCost", + ), + }) + .from(projectHourlyStats) + .where( + and( + inArray(projectHourlyStats.projectId, projectIds), + gte(projectHourlyStats.hourTimestamp, startDate), + lt(projectHourlyStats.hourTimestamp, now), ), - cachedCost: - sql`COALESCE(SUM(${tables.log.cachedInputCost}), 0)`.as( - "cachedCost", + ); + + if (totals) { + totalRequests = Number(totals.totalRequests) || 0; + totalTokens = Number(totals.totalTokens) || 0; + totalCost = Number(totals.totalCost) || 0; + inputTokens = Number(totals.inputTokens) || 0; + inputCost = Number(totals.inputCost) || 0; + outputTokens = Number(totals.outputTokens) || 0; + outputCost = Number(totals.outputCost) || 0; + cachedTokens = Number(totals.cachedTokens) || 0; + // cachedCost is not stored in aggregation tables, estimate from cachedTokens + cachedCost = 0; + } + + // Query model stats for most used model (by cost) + const modelRows = await db + .select({ + usedModel: projectHourlyModelStats.usedModel, + usedProvider: projectHourlyModelStats.usedProvider, + totalCost: + sql`COALESCE(SUM(${projectHourlyModelStats.cost}), 0)`.as( + "totalCost", ), }) - .from(tables.log) + .from(projectHourlyModelStats) .where( and( - inArray(tables.log.projectId, projectIds), - gte(tables.log.createdAt, startDate), - lt(tables.log.createdAt, now), + inArray(projectHourlyModelStats.projectId, projectIds), + gte(projectHourlyModelStats.hourTimestamp, startDate), + lt(projectHourlyModelStats.hourTimestamp, now), ), ) - .groupBy(tables.log.usedModel, tables.log.usedProvider); - - for (const row of rows) { - totalRequests += Number(row.requestsCount) || 0; - totalTokens += Number(row.totalTokens) || 0; - totalCost += Number(row.totalCost) || 0; - inputTokens += Number(row.inputTokens) || 0; - inputCost += Number(row.inputCost) || 0; - outputTokens += Number(row.outputTokens) || 0; - outputCost += Number(row.outputCost) || 0; - cachedTokens += Number(row.cachedTokens) || 0; - cachedCost += Number(row.cachedCost) || 0; + .groupBy( + projectHourlyModelStats.usedModel, + projectHourlyModelStats.usedProvider, + ); + for (const row of modelRows) { const rowCost = Number(row.totalCost) || 0; if (rowCost > mostUsedModelCost) { mostUsedModelCost = rowCost; diff --git a/apps/api/src/testing.ts b/apps/api/src/testing.ts index a7b2080d8a..3fcf052aae 100644 --- a/apps/api/src/testing.ts +++ b/apps/api/src/testing.ts @@ -1,4 +1,12 @@ -import { db, tables } from "@llmgateway/db"; +import { + db, + tables, + sql, + projectHourlyStats, + projectHourlyModelStats, + apiKeyHourlyStats, + apiKeyHourlyModelStats, +} from "@llmgateway/db"; import { app } from "./index.js"; @@ -16,6 +24,10 @@ export async function deleteAll() { db.delete(tables.log), db.delete(tables.apiKey), db.delete(tables.providerKey), + db.delete(projectHourlyStats), + db.delete(projectHourlyModelStats), + db.delete(apiKeyHourlyStats), + db.delete(apiKeyHourlyModelStats), ]); await Promise.all([ @@ -32,6 +44,350 @@ export async function deleteAll() { ]); } +/** + * Common aggregation fields for stats tables + */ +function getCommonAggregationFields() { + return { + requestCount: sql`count(*)::int`.as("requestCount"), + errorCount: + sql`sum(case when ${tables.log.hasError} = true then 1 else 0 end)::int`.as( + "errorCount", + ), + cacheCount: + sql`sum(case when ${tables.log.cached} = true then 1 else 0 end)::int`.as( + "cacheCount", + ), + streamedCount: + sql`sum(case when ${tables.log.streamed} = true then 1 else 0 end)::int`.as( + "streamedCount", + ), + nonStreamedCount: + sql`sum(case when ${tables.log.streamed} = false or ${tables.log.streamed} is null then 1 else 0 end)::int`.as( + "nonStreamedCount", + ), + completedCount: + sql`sum(case when ${tables.log.unifiedFinishReason} = 'completed' then 1 else 0 end)::int`.as( + "completedCount", + ), + lengthLimitCount: + sql`sum(case when ${tables.log.unifiedFinishReason} = 'length_limit' then 1 else 0 end)::int`.as( + "lengthLimitCount", + ), + contentFilterCount: + sql`sum(case when ${tables.log.unifiedFinishReason} = 'content_filter' then 1 else 0 end)::int`.as( + "contentFilterCount", + ), + toolCallsCount: + sql`sum(case when ${tables.log.unifiedFinishReason} = 'tool_calls' then 1 else 0 end)::int`.as( + "toolCallsCount", + ), + canceledCount: + sql`sum(case when ${tables.log.unifiedFinishReason} = 'canceled' then 1 else 0 end)::int`.as( + "canceledCount", + ), + unknownFinishCount: + sql`sum(case when ${tables.log.unifiedFinishReason} = 'unknown' or ${tables.log.unifiedFinishReason} is null then 1 else 0 end)::int`.as( + "unknownFinishCount", + ), + clientErrorCount: + sql`sum(case when ${tables.log.unifiedFinishReason} = 'client_error' then 1 else 0 end)::int`.as( + "clientErrorCount", + ), + gatewayErrorCount: + sql`sum(case when ${tables.log.unifiedFinishReason} = 'gateway_error' then 1 else 0 end)::int`.as( + "gatewayErrorCount", + ), + upstreamErrorCount: + sql`sum(case when ${tables.log.unifiedFinishReason} = 'upstream_error' then 1 else 0 end)::int`.as( + "upstreamErrorCount", + ), + inputTokens: + sql`coalesce(sum(cast(${tables.log.promptTokens} as numeric)), 0)`.as( + "inputTokens", + ), + outputTokens: + sql`coalesce(sum(cast(${tables.log.completionTokens} as numeric)), 0)`.as( + "outputTokens", + ), + totalTokens: + sql`coalesce(sum(cast(${tables.log.totalTokens} as numeric)), 0)`.as( + "totalTokens", + ), + reasoningTokens: + sql`coalesce(sum(cast(${tables.log.reasoningTokens} as numeric)), 0)`.as( + "reasoningTokens", + ), + cachedTokens: + sql`coalesce(sum(cast(${tables.log.cachedTokens} as numeric)), 0)`.as( + "cachedTokens", + ), + cost: sql`coalesce(sum(${tables.log.cost}), 0)`.as("cost"), + inputCost: sql`coalesce(sum(${tables.log.inputCost}), 0)`.as( + "inputCost", + ), + outputCost: sql`coalesce(sum(${tables.log.outputCost}), 0)`.as( + "outputCost", + ), + requestCost: sql`coalesce(sum(${tables.log.requestCost}), 0)`.as( + "requestCost", + ), + dataStorageCost: + sql`coalesce(sum(cast(${tables.log.dataStorageCost} as real)), 0)`.as( + "dataStorageCost", + ), + serviceFee: sql`coalesce(sum(${tables.log.serviceFee}), 0)`.as( + "serviceFee", + ), + discountSavings: sql`coalesce( + sum( + case + when ${tables.log.discount} > 0 and ${tables.log.discount} < 1 + then ${tables.log.cost} * ${tables.log.discount} / (1 - ${tables.log.discount}) + else 0 + end + ), + 0 + )`.as("discountSavings"), + imageInputCost: + sql`coalesce(sum(${tables.log.imageInputCost}), 0)`.as( + "imageInputCost", + ), + imageOutputCost: + sql`coalesce(sum(${tables.log.imageOutputCost}), 0)`.as( + "imageOutputCost", + ), + cachedInputCost: + sql`coalesce(sum(${tables.log.cachedInputCost}), 0)`.as( + "cachedInputCost", + ), + // Per-mode breakdowns + creditsRequestCount: + sql`sum(case when ${tables.log.usedMode} = 'credits' then 1 else 0 end)::int`.as( + "creditsRequestCount", + ), + apiKeysRequestCount: + sql`sum(case when ${tables.log.usedMode} = 'api-keys' then 1 else 0 end)::int`.as( + "apiKeysRequestCount", + ), + creditsCost: + sql`coalesce(sum(case when ${tables.log.usedMode} = 'credits' then ${tables.log.cost} else 0 end), 0)`.as( + "creditsCost", + ), + apiKeysCost: + sql`coalesce(sum(case when ${tables.log.usedMode} = 'api-keys' then ${tables.log.cost} else 0 end), 0)`.as( + "apiKeysCost", + ), + creditsServiceFee: + sql`coalesce(sum(case when ${tables.log.usedMode} = 'credits' then ${tables.log.serviceFee} else 0 end), 0)`.as( + "creditsServiceFee", + ), + apiKeysServiceFee: + sql`coalesce(sum(case when ${tables.log.usedMode} = 'api-keys' then ${tables.log.serviceFee} else 0 end), 0)`.as( + "apiKeysServiceFee", + ), + creditsDataStorageCost: + sql`coalesce(sum(case when ${tables.log.usedMode} = 'credits' then cast(${tables.log.dataStorageCost} as real) else 0 end), 0)`.as( + "creditsDataStorageCost", + ), + apiKeysDataStorageCost: + sql`coalesce(sum(case when ${tables.log.usedMode} = 'api-keys' then cast(${tables.log.dataStorageCost} as real) else 0 end), 0)`.as( + "apiKeysDataStorageCost", + ), + }; +} + +/** + * Aggregates logs into the hourly stats tables for testing purposes. + * This mimics what the worker does in production. + * + * Uses single-query aggregation (grouping by project+hour in one SELECT) + * to avoid timezone issues when round-tripping timestamps through JS Date objects. + * The hourTimestamp is returned as a string and passed back via sql`` to avoid + * the pg driver's local-timezone interpretation of `timestamp without timezone`. + */ +export async function aggregateLogsForTesting() { + // Clear existing aggregation data to ensure a clean state + await Promise.all([ + db.delete(projectHourlyStats), + db.delete(projectHourlyModelStats), + db.delete(apiKeyHourlyStats), + db.delete(apiKeyHourlyModelStats), + ]); + + const hourTrunc = sql`date_trunc('hour', ${tables.log.createdAt})`; + + // Project hourly stats - aggregate in a single query + const projectStats = await db + .select({ + projectId: tables.log.projectId, + hourTimestamp: + sql`to_char(${hourTrunc}, 'YYYY-MM-DD HH24:MI:SS')`.as( + "hourTimestamp", + ), + ...getCommonAggregationFields(), + }) + .from(tables.log) + .groupBy(tables.log.projectId, hourTrunc); + + for (const stats of projectStats) { + const { projectId, hourTimestamp, ...fields } = stats; + if (fields.requestCount > 0) { + await db + .insert(projectHourlyStats) + .values({ + projectId, + hourTimestamp: sql`${hourTimestamp}::timestamp`, + ...fields, + }) + .onConflictDoUpdate({ + target: [ + projectHourlyStats.projectId, + projectHourlyStats.hourTimestamp, + ], + set: { + ...fields, + updatedAt: new Date(), + }, + }); + } + } + + // Project hourly model stats + const modelStats = await db + .select({ + projectId: tables.log.projectId, + hourTimestamp: + sql`to_char(${hourTrunc}, 'YYYY-MM-DD HH24:MI:SS')`.as( + "hourTimestamp", + ), + usedModel: tables.log.usedModel, + usedProvider: tables.log.usedProvider, + ...getCommonAggregationFields(), + }) + .from(tables.log) + .groupBy( + tables.log.projectId, + hourTrunc, + tables.log.usedModel, + tables.log.usedProvider, + ); + + for (const stat of modelStats) { + const { projectId, hourTimestamp, usedModel, usedProvider, ...fields } = + stat; + await db + .insert(projectHourlyModelStats) + .values({ + projectId, + hourTimestamp: sql`${hourTimestamp}::timestamp`, + usedModel, + usedProvider, + ...fields, + }) + .onConflictDoUpdate({ + target: [ + projectHourlyModelStats.projectId, + projectHourlyModelStats.hourTimestamp, + projectHourlyModelStats.usedModel, + projectHourlyModelStats.usedProvider, + ], + set: { + ...fields, + updatedAt: new Date(), + }, + }); + } + + // API key hourly stats + const apiKeyStats = await db + .select({ + apiKeyId: tables.log.apiKeyId, + projectId: tables.log.projectId, + hourTimestamp: + sql`to_char(${hourTrunc}, 'YYYY-MM-DD HH24:MI:SS')`.as( + "hourTimestamp", + ), + ...getCommonAggregationFields(), + }) + .from(tables.log) + .groupBy(tables.log.apiKeyId, tables.log.projectId, hourTrunc); + + for (const stat of apiKeyStats) { + const { apiKeyId, projectId, hourTimestamp, ...fields } = stat; + await db + .insert(apiKeyHourlyStats) + .values({ + apiKeyId, + projectId, + hourTimestamp: sql`${hourTimestamp}::timestamp`, + ...fields, + }) + .onConflictDoUpdate({ + target: [apiKeyHourlyStats.apiKeyId, apiKeyHourlyStats.hourTimestamp], + set: { + ...fields, + updatedAt: new Date(), + }, + }); + } + + // API key hourly model stats + const apiKeyModelStats = await db + .select({ + apiKeyId: tables.log.apiKeyId, + projectId: tables.log.projectId, + hourTimestamp: + sql`to_char(${hourTrunc}, 'YYYY-MM-DD HH24:MI:SS')`.as( + "hourTimestamp", + ), + usedModel: tables.log.usedModel, + usedProvider: tables.log.usedProvider, + ...getCommonAggregationFields(), + }) + .from(tables.log) + .groupBy( + tables.log.apiKeyId, + tables.log.projectId, + hourTrunc, + tables.log.usedModel, + tables.log.usedProvider, + ); + + for (const stat of apiKeyModelStats) { + const { + apiKeyId, + projectId, + hourTimestamp, + usedModel, + usedProvider, + ...fields + } = stat; + await db + .insert(apiKeyHourlyModelStats) + .values({ + apiKeyId, + projectId, + hourTimestamp: sql`${hourTimestamp}::timestamp`, + usedModel, + usedProvider, + ...fields, + }) + .onConflictDoUpdate({ + target: [ + apiKeyHourlyModelStats.apiKeyId, + apiKeyHourlyModelStats.hourTimestamp, + apiKeyHourlyModelStats.usedModel, + apiKeyHourlyModelStats.usedProvider, + ], + set: { + ...fields, + updatedAt: new Date(), + }, + }); + } +} + export async function createTestUser() { await deleteAll(); diff --git a/apps/code/src/lib/api/v1.d.ts b/apps/code/src/lib/api/v1.d.ts index 0468f37d52..5d9581086b 100644 --- a/apps/code/src/lib/api/v1.d.ts +++ b/apps/code/src/lib/api/v1.d.ts @@ -981,6 +981,14 @@ export interface paths { cacheCount: number; cacheRate: number; discountSavings: number; + creditsRequestCount: number; + apiKeysRequestCount: number; + creditsCost: number; + apiKeysCost: number; + creditsServiceFee: number; + apiKeysServiceFee: number; + creditsDataStorageCost: number; + apiKeysDataStorageCost: number; modelBreakdown: { id: string; provider: string; diff --git a/apps/playground/src/lib/api/v1.d.ts b/apps/playground/src/lib/api/v1.d.ts index 0468f37d52..5d9581086b 100644 --- a/apps/playground/src/lib/api/v1.d.ts +++ b/apps/playground/src/lib/api/v1.d.ts @@ -981,6 +981,14 @@ export interface paths { cacheCount: number; cacheRate: number; discountSavings: number; + creditsRequestCount: number; + apiKeysRequestCount: number; + creditsCost: number; + apiKeysCost: number; + creditsServiceFee: number; + apiKeysServiceFee: number; + creditsDataStorageCost: number; + apiKeysDataStorageCost: number; modelBreakdown: { id: string; provider: string; diff --git a/apps/ui/src/components/dashboard/overview.tsx b/apps/ui/src/components/dashboard/overview.tsx index af5fa6edfc..b80913c3cb 100644 --- a/apps/ui/src/components/dashboard/overview.tsx +++ b/apps/ui/src/components/dashboard/overview.tsx @@ -184,7 +184,7 @@ export function Overview({ {metric === "costs" ? ( <> ) : ( `count(*)::int`.as("requestCount"), + errorCount: + sql`sum(case when ${log.hasError} = true then 1 else 0 end)::int`.as( + "errorCount", + ), + cacheCount: + sql`sum(case when ${log.cached} = true then 1 else 0 end)::int`.as( + "cacheCount", + ), + streamedCount: + sql`sum(case when ${log.streamed} = true then 1 else 0 end)::int`.as( + "streamedCount", + ), + nonStreamedCount: + sql`sum(case when ${log.streamed} = false or ${log.streamed} is null then 1 else 0 end)::int`.as( + "nonStreamedCount", + ), + // Unified finish reason counts + completedCount: + sql`sum(case when ${log.unifiedFinishReason} = 'completed' then 1 else 0 end)::int`.as( + "completedCount", + ), + lengthLimitCount: + sql`sum(case when ${log.unifiedFinishReason} = 'length_limit' then 1 else 0 end)::int`.as( + "lengthLimitCount", + ), + contentFilterCount: + sql`sum(case when ${log.unifiedFinishReason} = 'content_filter' then 1 else 0 end)::int`.as( + "contentFilterCount", + ), + toolCallsCount: + sql`sum(case when ${log.unifiedFinishReason} = 'tool_calls' then 1 else 0 end)::int`.as( + "toolCallsCount", + ), + canceledCount: + sql`sum(case when ${log.unifiedFinishReason} = 'canceled' then 1 else 0 end)::int`.as( + "canceledCount", + ), + unknownFinishCount: + sql`sum(case when ${log.unifiedFinishReason} = 'unknown' or ${log.unifiedFinishReason} is null then 1 else 0 end)::int`.as( + "unknownFinishCount", + ), + // Error type counts + clientErrorCount: + sql`sum(case when ${log.unifiedFinishReason} = 'client_error' then 1 else 0 end)::int`.as( + "clientErrorCount", + ), + gatewayErrorCount: + sql`sum(case when ${log.unifiedFinishReason} = 'gateway_error' then 1 else 0 end)::int`.as( + "gatewayErrorCount", + ), + upstreamErrorCount: + sql`sum(case when ${log.unifiedFinishReason} = 'upstream_error' then 1 else 0 end)::int`.as( + "upstreamErrorCount", + ), + // Token counts + inputTokens: + sql`coalesce(sum(cast(${log.promptTokens} as numeric)), 0)`.as( + "inputTokens", + ), + outputTokens: + sql`coalesce(sum(cast(${log.completionTokens} as numeric)), 0)`.as( + "outputTokens", + ), + totalTokens: + sql`coalesce(sum(cast(${log.totalTokens} as numeric)), 0)`.as( + "totalTokens", + ), + reasoningTokens: + sql`coalesce(sum(cast(${log.reasoningTokens} as numeric)), 0)`.as( + "reasoningTokens", + ), + cachedTokens: + sql`coalesce(sum(cast(${log.cachedTokens} as numeric)), 0)`.as( + "cachedTokens", + ), + // Costs + cost: sql`coalesce(sum(${log.cost}), 0)`.as("cost"), + inputCost: sql`coalesce(sum(${log.inputCost}), 0)`.as("inputCost"), + outputCost: sql`coalesce(sum(${log.outputCost}), 0)`.as( + "outputCost", + ), + requestCost: sql`coalesce(sum(${log.requestCost}), 0)`.as( + "requestCost", + ), + dataStorageCost: + sql`coalesce(sum(cast(${log.dataStorageCost} as real)), 0)`.as( + "dataStorageCost", + ), + serviceFee: sql`coalesce(sum(${log.serviceFee}), 0)`.as( + "serviceFee", + ), + discountSavings: sql`coalesce( + sum( + case + when ${log.discount} > 0 and ${log.discount} < 1 + then ${log.cost} * ${log.discount} / (1 - ${log.discount}) + else 0 + end + ), + 0 + )`.as("discountSavings"), + imageInputCost: sql`coalesce(sum(${log.imageInputCost}), 0)`.as( + "imageInputCost", + ), + imageOutputCost: sql`coalesce(sum(${log.imageOutputCost}), 0)`.as( + "imageOutputCost", + ), + cachedInputCost: sql`coalesce(sum(${log.cachedInputCost}), 0)`.as( + "cachedInputCost", + ), + // Per-mode breakdowns + creditsRequestCount: + sql`sum(case when ${log.usedMode} = 'credits' then 1 else 0 end)::int`.as( + "creditsRequestCount", + ), + apiKeysRequestCount: + sql`sum(case when ${log.usedMode} = 'api-keys' then 1 else 0 end)::int`.as( + "apiKeysRequestCount", + ), + creditsCost: + sql`coalesce(sum(case when ${log.usedMode} = 'credits' then ${log.cost} else 0 end), 0)`.as( + "creditsCost", + ), + apiKeysCost: + sql`coalesce(sum(case when ${log.usedMode} = 'api-keys' then ${log.cost} else 0 end), 0)`.as( + "apiKeysCost", + ), + creditsServiceFee: + sql`coalesce(sum(case when ${log.usedMode} = 'credits' then ${log.serviceFee} else 0 end), 0)`.as( + "creditsServiceFee", + ), + apiKeysServiceFee: + sql`coalesce(sum(case when ${log.usedMode} = 'api-keys' then ${log.serviceFee} else 0 end), 0)`.as( + "apiKeysServiceFee", + ), + creditsDataStorageCost: + sql`coalesce(sum(case when ${log.usedMode} = 'credits' then cast(${log.dataStorageCost} as real) else 0 end), 0)`.as( + "creditsDataStorageCost", + ), + apiKeysDataStorageCost: + sql`coalesce(sum(case when ${log.usedMode} = 'api-keys' then cast(${log.dataStorageCost} as real) else 0 end), 0)`.as( + "apiKeysDataStorageCost", + ), + }; +} + +/** + * Calculate and store hourly statistics for a specific project and hour. + * hourTimestamp is a UTC string (YYYY-MM-DD HH:MM:SS) to avoid JS Date timezone issues. + */ +async function recalculateProjectHourlyStats( + projectId: string, + hourTimestamp: string, +) { + const database = db; + + const [stats] = await database + .select(getCommonAggregationFields()) + .from(log) + .where( + and( + sql`${log.projectId} = ${projectId}`, + sql`${log.createdAt} >= ${hourTimestamp}::timestamp`, + sql`${log.createdAt} < ${hourTimestamp}::timestamp + interval '1 hour'`, + ), + ); + + if (!stats || stats.requestCount === 0) { + return; + } + + await database + .insert(projectHourlyStats) + .values({ + projectId, + hourTimestamp: sql`${hourTimestamp}::timestamp`, + ...stats, + }) + .onConflictDoUpdate({ + target: [projectHourlyStats.projectId, projectHourlyStats.hourTimestamp], + set: { + ...stats, + updatedAt: new Date(), + }, + }); +} + +/** + * Calculate and store hourly model statistics for a specific project and hour + */ +async function recalculateProjectHourlyModelStats( + projectId: string, + hourTimestamp: string, +) { + const database = db; + + const modelStats = await database + .select({ + usedModel: log.usedModel, + usedProvider: log.usedProvider, + ...getCommonAggregationFields(), + }) + .from(log) + .where( + and( + sql`${log.projectId} = ${projectId}`, + sql`${log.createdAt} >= ${hourTimestamp}::timestamp`, + sql`${log.createdAt} < ${hourTimestamp}::timestamp + interval '1 hour'`, + ), + ) + .groupBy(log.usedModel, log.usedProvider); + + for (const stat of modelStats) { + const { usedModel, usedProvider, ...statsFields } = stat; + await database + .insert(projectHourlyModelStats) + .values({ + projectId, + hourTimestamp: sql`${hourTimestamp}::timestamp`, + usedModel, + usedProvider, + ...statsFields, + }) + .onConflictDoUpdate({ + target: [ + projectHourlyModelStats.projectId, + projectHourlyModelStats.hourTimestamp, + projectHourlyModelStats.usedModel, + projectHourlyModelStats.usedProvider, + ], + set: { + ...statsFields, + updatedAt: new Date(), + }, + }); + } +} + +/** + * Calculate and store hourly API key statistics for a specific project and hour + */ +async function recalculateApiKeyHourlyStats( + projectId: string, + hourTimestamp: string, +) { + const database = db; + + const apiKeyStats = await database + .select({ + apiKeyId: log.apiKeyId, + ...getCommonAggregationFields(), + }) + .from(log) + .where( + and( + sql`${log.projectId} = ${projectId}`, + sql`${log.createdAt} >= ${hourTimestamp}::timestamp`, + sql`${log.createdAt} < ${hourTimestamp}::timestamp + interval '1 hour'`, + ), + ) + .groupBy(log.apiKeyId); + + for (const stat of apiKeyStats) { + const { apiKeyId, ...statsFields } = stat; + await database + .insert(apiKeyHourlyStats) + .values({ + apiKeyId, + projectId, + hourTimestamp: sql`${hourTimestamp}::timestamp`, + ...statsFields, + }) + .onConflictDoUpdate({ + target: [apiKeyHourlyStats.apiKeyId, apiKeyHourlyStats.hourTimestamp], + set: { + ...statsFields, + updatedAt: new Date(), + }, + }); + } +} + +/** + * Calculate and store hourly API key model statistics for a specific project and hour + */ +async function recalculateApiKeyHourlyModelStats( + projectId: string, + hourTimestamp: string, +) { + const database = db; + + const apiKeyModelStats = await database + .select({ + apiKeyId: log.apiKeyId, + usedModel: log.usedModel, + usedProvider: log.usedProvider, + ...getCommonAggregationFields(), + }) + .from(log) + .where( + and( + sql`${log.projectId} = ${projectId}`, + sql`${log.createdAt} >= ${hourTimestamp}::timestamp`, + sql`${log.createdAt} < ${hourTimestamp}::timestamp + interval '1 hour'`, + ), + ) + .groupBy(log.apiKeyId, log.usedModel, log.usedProvider); + + for (const stat of apiKeyModelStats) { + const { apiKeyId, usedModel, usedProvider, ...statsFields } = stat; + await database + .insert(apiKeyHourlyModelStats) + .values({ + apiKeyId, + projectId, + hourTimestamp: sql`${hourTimestamp}::timestamp`, + usedModel, + usedProvider, + ...statsFields, + }) + .onConflictDoUpdate({ + target: [ + apiKeyHourlyModelStats.apiKeyId, + apiKeyHourlyModelStats.hourTimestamp, + apiKeyHourlyModelStats.usedModel, + apiKeyHourlyModelStats.usedProvider, + ], + set: { + ...statsFields, + updatedAt: new Date(), + }, + }); + } +} + +// Batch size per run (shared by both phases) +const STATS_BATCH_SIZE = Number(process.env.STATS_BATCH_SIZE) || 100; + +// Phase 1: Backfill — process hours with no stats rows yet +// STATS_BACKFILL_ENABLED: "true" (default) or "false" +// STATS_BACKFILL_DAYS: how far back to look (default: 30, 0 = unlimited) +const STATS_BACKFILL_ENABLED = process.env.STATS_BACKFILL_ENABLED !== "false"; +const STATS_BACKFILL_DAYS = Number(process.env.STATS_BACKFILL_DAYS) || 30; + +// Phase 2: Stale detection — re-process hours where new logs arrived after aggregation +// STATS_STALE_ENABLED: "true" (default) or "false" +// STATS_STALE_DAYS: how far back to check for stale buckets (default: 7, 0 = unlimited) +const STATS_STALE_ENABLED = process.env.STATS_STALE_ENABLED !== "false"; +const STATS_STALE_DAYS = Number(process.env.STATS_STALE_DAYS) || 7; + +/** + * Process all logs that haven't been aggregated yet (backfill) and re-process + * stale buckets where new logs arrived after the last aggregation. + */ +export async function processRecentLogs() { + const database = db; + const currentHourStart = getCurrentHourStart(); + let totalBucketsProcessed = 0; + + try { + // Phase 1: Backfill - find project-hour buckets that have NO stats rows yet + if (STATS_BACKFILL_ENABLED) { + const backfillStart = + STATS_BACKFILL_DAYS > 0 + ? formatUTCTimestamp( + new Date(Date.now() - STATS_BACKFILL_DAYS * 24 * 60 * 60 * 1000), + ) + : undefined; + + logger.info( + `[backfill] Scanning for unprocessed buckets (lookback: ${backfillStart ?? "unlimited"})`, + ); + + const backfillBuckets = await database + .select({ + projectId: log.projectId, + hourTimestamp: + sql`to_char(date_trunc('hour', ${log.createdAt}), 'YYYY-MM-DD HH24:MI:SS')`.as( + "hourTimestamp", + ), + }) + .from(log) + .leftJoin( + projectHourlyStats, + and( + sql`${projectHourlyStats.projectId} = ${log.projectId}`, + sql`${projectHourlyStats.hourTimestamp} = date_trunc('hour', ${log.createdAt})`, + ), + ) + .where( + and( + sql`${log.createdAt} < ${currentHourStart}::timestamp`, + isNull(projectHourlyStats.projectId), + backfillStart + ? sql`${log.createdAt} >= ${backfillStart}::timestamp` + : undefined, + ), + ) + .groupBy(log.projectId, sql`date_trunc('hour', ${log.createdAt})`) + .orderBy(sql`date_trunc('hour', ${log.createdAt}) ASC`) + .limit(STATS_BATCH_SIZE); + + if (backfillBuckets.length > 0) { + logger.info( + `[backfill] Found ${backfillBuckets.length} unprocessed project-hour buckets (oldest: ${backfillBuckets[0].hourTimestamp}, newest: ${backfillBuckets[backfillBuckets.length - 1].hourTimestamp})`, + ); + + for (let i = 0; i < backfillBuckets.length; i++) { + const bucket = backfillBuckets[i]; + + await recalculateProjectHourlyStats( + bucket.projectId, + bucket.hourTimestamp, + ); + await recalculateProjectHourlyModelStats( + bucket.projectId, + bucket.hourTimestamp, + ); + await recalculateApiKeyHourlyStats( + bucket.projectId, + bucket.hourTimestamp, + ); + await recalculateApiKeyHourlyModelStats( + bucket.projectId, + bucket.hourTimestamp, + ); + + logger.info( + `[backfill] Processed bucket ${i + 1}/${backfillBuckets.length}: project=${bucket.projectId} hour=${bucket.hourTimestamp}`, + ); + } + + totalBucketsProcessed += backfillBuckets.length; + + if (backfillBuckets.length === STATS_BATCH_SIZE) { + logger.info( + `[backfill] Batch limit reached (${STATS_BATCH_SIZE}), more unprocessed buckets may remain — will continue in next run`, + ); + } else { + logger.info( + `[backfill] Complete: ${backfillBuckets.length} buckets processed`, + ); + } + } else { + logger.debug("[backfill] No unprocessed buckets found"); + } + } + + // Phase 2: Re-process stale buckets where new logs arrived after the last aggregation. + // Iterates over the small project_hourly_stats table and uses a correlated + // subquery to check if any log in that bucket is newer than updatedAt. + // This leverages the (project_id, created_at) index for fast lookups. + if (STATS_STALE_ENABLED) { + const staleStart = + STATS_STALE_DAYS > 0 + ? formatUTCTimestamp( + new Date(Date.now() - STATS_STALE_DAYS * 24 * 60 * 60 * 1000), + ) + : undefined; + + logger.info( + `[stale] Scanning for stale buckets (lookback: ${staleStart ?? "unlimited"})`, + ); + + const staleBuckets = await database + .select({ + projectId: projectHourlyStats.projectId, + hourTimestamp: + sql`to_char(${projectHourlyStats.hourTimestamp}, 'YYYY-MM-DD HH24:MI:SS')`.as( + "hourTimestamp", + ), + }) + .from(projectHourlyStats) + .where( + and( + staleStart + ? sql`${projectHourlyStats.hourTimestamp} >= ${staleStart}::timestamp` + : undefined, + sql`EXISTS ( + SELECT 1 FROM ${log} + WHERE ${log.projectId} = ${projectHourlyStats.projectId} + AND ${log.createdAt} >= ${projectHourlyStats.hourTimestamp} + AND ${log.createdAt} < ${projectHourlyStats.hourTimestamp} + interval '1 hour' + AND ${log.createdAt} > ${projectHourlyStats.updatedAt} + LIMIT 1 + )`, + ), + ) + .orderBy(projectHourlyStats.hourTimestamp) + .limit(STATS_BATCH_SIZE); + + if (staleBuckets.length > 0) { + logger.info( + `[stale] Found ${staleBuckets.length} stale project-hour buckets with new logs (oldest: ${staleBuckets[0].hourTimestamp}, newest: ${staleBuckets[staleBuckets.length - 1].hourTimestamp})`, + ); + + for (let i = 0; i < staleBuckets.length; i++) { + const bucket = staleBuckets[i]; + + await recalculateProjectHourlyStats( + bucket.projectId, + bucket.hourTimestamp, + ); + await recalculateProjectHourlyModelStats( + bucket.projectId, + bucket.hourTimestamp, + ); + await recalculateApiKeyHourlyStats( + bucket.projectId, + bucket.hourTimestamp, + ); + await recalculateApiKeyHourlyModelStats( + bucket.projectId, + bucket.hourTimestamp, + ); + + logger.info( + `[stale] Processed bucket ${i + 1}/${staleBuckets.length}: project=${bucket.projectId} hour=${bucket.hourTimestamp}`, + ); + } + + totalBucketsProcessed += staleBuckets.length; + + if (staleBuckets.length === STATS_BATCH_SIZE) { + logger.info( + `[stale] Batch limit reached (${STATS_BATCH_SIZE}), more stale buckets may remain — will continue in next run`, + ); + } + } else { + logger.debug("[stale] No stale buckets found"); + } + } + + logger.info( + `Stats aggregation complete: ${totalBucketsProcessed} total buckets processed`, + ); + + return { + bucketsProcessed: totalBucketsProcessed, + }; + } catch (error) { + logger.error( + "Error processing logs for stats aggregation", + error instanceof Error ? error : new Error(String(error)), + ); + throw error; + } +} + +/** + * Refresh the current hour's stats (for real-time dashboard data) + */ +export async function refreshCurrentHourStats() { + const database = db; + const currentHourStart = getCurrentHourStart(); + + logger.info(`Refreshing current hour stats for ${currentHourStart}`); + + try { + const projectsWithCurrentHourLogs = await database + .select({ + projectId: log.projectId, + }) + .from(log) + .where(sql`${log.createdAt} >= ${currentHourStart}::timestamp`) + .groupBy(log.projectId); + + for (const { projectId } of projectsWithCurrentHourLogs) { + await recalculateProjectHourlyStats(projectId, currentHourStart); + await recalculateProjectHourlyModelStats(projectId, currentHourStart); + await recalculateApiKeyHourlyStats(projectId, currentHourStart); + await recalculateApiKeyHourlyModelStats(projectId, currentHourStart); + } + + logger.info( + `Refreshed current hour stats (${currentHourStart}) for ${projectsWithCurrentHourLogs.length} projects`, + ); + } catch (error) { + logger.error( + "Error refreshing current hour stats", + error instanceof Error ? error : new Error(String(error)), + ); + throw error; + } +} + +/** + * Main refresh function called by the worker interval + */ +export async function refreshProjectHourlyStats() { + logger.debug("Starting project hourly stats refresh..."); + + try { + await processRecentLogs(); + await refreshCurrentHourStats(); + logger.debug("Project hourly stats refresh complete"); + } catch (error) { + logger.error( + "Error refreshing project hourly stats", + error instanceof Error ? error : new Error(String(error)), + ); + throw error; + } +} diff --git a/apps/worker/src/worker.ts b/apps/worker/src/worker.ts index dda6dacf4b..40f95f7b5c 100644 --- a/apps/worker/src/worker.ts +++ b/apps/worker/src/worker.ts @@ -26,6 +26,10 @@ import { logger } from "@llmgateway/logger"; import { hasErrorCode } from "@llmgateway/models"; import { BYOK_FEE_PERCENTAGE, calculateFees } from "@llmgateway/shared"; +import { + PROJECT_STATS_REFRESH_INTERVAL_SECONDS, + refreshProjectHourlyStats, +} from "./services/project-stats-aggregator.js"; import { backfillHistoryIfNeeded, calculateAggregatedStatistics, @@ -519,7 +523,7 @@ export async function batchProcessLogs(): Promise { const row = schema.parse(raw); // Log each processed log with JSON format - logger.info("Processing log", { + logger.trace("Processing log", { kind: "log-process", status: row.hasError ? "error" : row.cached ? "cached" : "success", logId: row.id, @@ -857,6 +861,7 @@ let shouldStop = false; let minutelyIntervalId: NodeJS.Timeout | null = null; let currentMinuteIntervalId: NodeJS.Timeout | null = null; let aggregatedIntervalId: NodeJS.Timeout | null = null; +let projectStatsIntervalId: NodeJS.Timeout | null = null; let activeLoops = 0; let stopFailed = false; @@ -1175,6 +1180,27 @@ export async function startWorker() { scheduleAggregatedStats(); + // Start project hourly stats refresh (for dashboard aggregations) + logger.info( + `- Project hourly stats: runs every ${PROJECT_STATS_REFRESH_INTERVAL_SECONDS} seconds for dashboard aggregations`, + ); + + refreshProjectHourlyStats().catch((error) => { + logger.error( + "Error in initial project hourly stats refresh", + error instanceof Error ? error : new Error(String(error)), + ); + }); + + projectStatsIntervalId = setInterval(() => { + refreshProjectHourlyStats().catch((error) => { + logger.error( + "Error in interval project hourly stats refresh", + error instanceof Error ? error : new Error(String(error)), + ); + }); + }, PROJECT_STATS_REFRESH_INTERVAL_SECONDS * 1000); + // Start all parallel worker loops void runLogQueueLoop(); void runAutoTopUpLoop(); @@ -1210,6 +1236,12 @@ export async function stopWorker(): Promise { logger.info("Aggregated statistics calculator stopped"); } + if (projectStatsIntervalId) { + clearInterval(projectStatsIntervalId); + projectStatsIntervalId = null; + logger.info("Project hourly stats refresh stopped"); + } + // Wait for all loops to finish by polling activeLoops counter const maxWaitTime = 15000; // 15 seconds timeout const pollInterval = 100; // 100ms per iteration diff --git a/package.json b/package.json index fa39575d15..d625f2d16a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "migrate": "pnpm --filter db migrate", "migrations": "pnpm --filter db migrations", "prepare-codex": "mv ~/.nvm ~/.nvm-bak && export PATH=\"${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH\" && . ~/.bashrc && sudo service postgresql start && sudo service redis-server start && sleep 20 && pnpm sync", + "push": "pnpm push-dev && pnpm push-test", "push-dev": "pnpm --filter db push", "push-test": "cross-env-shell \"DATABASE_URL=${DATABASE_URL:-postgres://postgres:pw@localhost:5432/test}\" pnpm --filter db push", "seed": "pnpm --filter db seed", diff --git a/packages/db/migrations/1770740952_same_lake.sql b/packages/db/migrations/1770740952_same_lake.sql new file mode 100644 index 0000000000..1087053794 --- /dev/null +++ b/packages/db/migrations/1770740952_same_lake.sql @@ -0,0 +1,199 @@ +CREATE TABLE "api_key_hourly_model_stats" ( + "id" text PRIMARY KEY, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "api_key_id" text NOT NULL, + "project_id" text NOT NULL, + "hour_timestamp" timestamp NOT NULL, + "used_model" text NOT NULL, + "used_provider" text NOT NULL, + "request_count" integer DEFAULT 0 NOT NULL, + "error_count" integer DEFAULT 0 NOT NULL, + "cache_count" integer DEFAULT 0 NOT NULL, + "streamed_count" integer DEFAULT 0 NOT NULL, + "non_streamed_count" integer DEFAULT 0 NOT NULL, + "completed_count" integer DEFAULT 0 NOT NULL, + "length_limit_count" integer DEFAULT 0 NOT NULL, + "content_filter_count" integer DEFAULT 0 NOT NULL, + "tool_calls_count" integer DEFAULT 0 NOT NULL, + "canceled_count" integer DEFAULT 0 NOT NULL, + "unknown_finish_count" integer DEFAULT 0 NOT NULL, + "client_error_count" integer DEFAULT 0 NOT NULL, + "gateway_error_count" integer DEFAULT 0 NOT NULL, + "upstream_error_count" integer DEFAULT 0 NOT NULL, + "input_tokens" numeric DEFAULT '0' NOT NULL, + "output_tokens" numeric DEFAULT '0' NOT NULL, + "total_tokens" numeric DEFAULT '0' NOT NULL, + "reasoning_tokens" numeric DEFAULT '0' NOT NULL, + "cached_tokens" numeric DEFAULT '0' NOT NULL, + "cost" real DEFAULT 0 NOT NULL, + "input_cost" real DEFAULT 0 NOT NULL, + "output_cost" real DEFAULT 0 NOT NULL, + "request_cost" real DEFAULT 0 NOT NULL, + "data_storage_cost" real DEFAULT 0 NOT NULL, + "service_fee" real DEFAULT 0 NOT NULL, + "discount_savings" real DEFAULT 0 NOT NULL, + "image_input_cost" real DEFAULT 0 NOT NULL, + "image_output_cost" real DEFAULT 0 NOT NULL, + "cached_input_cost" real DEFAULT 0 NOT NULL, + "credits_request_count" integer DEFAULT 0 NOT NULL, + "api_keys_request_count" integer DEFAULT 0 NOT NULL, + "credits_cost" real DEFAULT 0 NOT NULL, + "api_keys_cost" real DEFAULT 0 NOT NULL, + "credits_service_fee" real DEFAULT 0 NOT NULL, + "api_keys_service_fee" real DEFAULT 0 NOT NULL, + "credits_data_storage_cost" real DEFAULT 0 NOT NULL, + "api_keys_data_storage_cost" real DEFAULT 0 NOT NULL, + CONSTRAINT "api_key_hourly_model_stats_api_key_id_hour_timestamp_used_model_used_provider_unique" UNIQUE("api_key_id","hour_timestamp","used_model","used_provider") +); +--> statement-breakpoint +CREATE TABLE "api_key_hourly_stats" ( + "id" text PRIMARY KEY, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "api_key_id" text NOT NULL, + "project_id" text NOT NULL, + "hour_timestamp" timestamp NOT NULL, + "request_count" integer DEFAULT 0 NOT NULL, + "error_count" integer DEFAULT 0 NOT NULL, + "cache_count" integer DEFAULT 0 NOT NULL, + "streamed_count" integer DEFAULT 0 NOT NULL, + "non_streamed_count" integer DEFAULT 0 NOT NULL, + "completed_count" integer DEFAULT 0 NOT NULL, + "length_limit_count" integer DEFAULT 0 NOT NULL, + "content_filter_count" integer DEFAULT 0 NOT NULL, + "tool_calls_count" integer DEFAULT 0 NOT NULL, + "canceled_count" integer DEFAULT 0 NOT NULL, + "unknown_finish_count" integer DEFAULT 0 NOT NULL, + "client_error_count" integer DEFAULT 0 NOT NULL, + "gateway_error_count" integer DEFAULT 0 NOT NULL, + "upstream_error_count" integer DEFAULT 0 NOT NULL, + "input_tokens" numeric DEFAULT '0' NOT NULL, + "output_tokens" numeric DEFAULT '0' NOT NULL, + "total_tokens" numeric DEFAULT '0' NOT NULL, + "reasoning_tokens" numeric DEFAULT '0' NOT NULL, + "cached_tokens" numeric DEFAULT '0' NOT NULL, + "cost" real DEFAULT 0 NOT NULL, + "input_cost" real DEFAULT 0 NOT NULL, + "output_cost" real DEFAULT 0 NOT NULL, + "request_cost" real DEFAULT 0 NOT NULL, + "data_storage_cost" real DEFAULT 0 NOT NULL, + "service_fee" real DEFAULT 0 NOT NULL, + "discount_savings" real DEFAULT 0 NOT NULL, + "image_input_cost" real DEFAULT 0 NOT NULL, + "image_output_cost" real DEFAULT 0 NOT NULL, + "cached_input_cost" real DEFAULT 0 NOT NULL, + "credits_request_count" integer DEFAULT 0 NOT NULL, + "api_keys_request_count" integer DEFAULT 0 NOT NULL, + "credits_cost" real DEFAULT 0 NOT NULL, + "api_keys_cost" real DEFAULT 0 NOT NULL, + "credits_service_fee" real DEFAULT 0 NOT NULL, + "api_keys_service_fee" real DEFAULT 0 NOT NULL, + "credits_data_storage_cost" real DEFAULT 0 NOT NULL, + "api_keys_data_storage_cost" real DEFAULT 0 NOT NULL, + CONSTRAINT "api_key_hourly_stats_api_key_id_hour_timestamp_unique" UNIQUE("api_key_id","hour_timestamp") +); +--> statement-breakpoint +CREATE TABLE "project_hourly_model_stats" ( + "id" text PRIMARY KEY, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "project_id" text NOT NULL, + "hour_timestamp" timestamp NOT NULL, + "used_model" text NOT NULL, + "used_provider" text NOT NULL, + "request_count" integer DEFAULT 0 NOT NULL, + "error_count" integer DEFAULT 0 NOT NULL, + "cache_count" integer DEFAULT 0 NOT NULL, + "streamed_count" integer DEFAULT 0 NOT NULL, + "non_streamed_count" integer DEFAULT 0 NOT NULL, + "completed_count" integer DEFAULT 0 NOT NULL, + "length_limit_count" integer DEFAULT 0 NOT NULL, + "content_filter_count" integer DEFAULT 0 NOT NULL, + "tool_calls_count" integer DEFAULT 0 NOT NULL, + "canceled_count" integer DEFAULT 0 NOT NULL, + "unknown_finish_count" integer DEFAULT 0 NOT NULL, + "client_error_count" integer DEFAULT 0 NOT NULL, + "gateway_error_count" integer DEFAULT 0 NOT NULL, + "upstream_error_count" integer DEFAULT 0 NOT NULL, + "input_tokens" numeric DEFAULT '0' NOT NULL, + "output_tokens" numeric DEFAULT '0' NOT NULL, + "total_tokens" numeric DEFAULT '0' NOT NULL, + "reasoning_tokens" numeric DEFAULT '0' NOT NULL, + "cached_tokens" numeric DEFAULT '0' NOT NULL, + "cost" real DEFAULT 0 NOT NULL, + "input_cost" real DEFAULT 0 NOT NULL, + "output_cost" real DEFAULT 0 NOT NULL, + "request_cost" real DEFAULT 0 NOT NULL, + "data_storage_cost" real DEFAULT 0 NOT NULL, + "service_fee" real DEFAULT 0 NOT NULL, + "discount_savings" real DEFAULT 0 NOT NULL, + "image_input_cost" real DEFAULT 0 NOT NULL, + "image_output_cost" real DEFAULT 0 NOT NULL, + "cached_input_cost" real DEFAULT 0 NOT NULL, + "credits_request_count" integer DEFAULT 0 NOT NULL, + "api_keys_request_count" integer DEFAULT 0 NOT NULL, + "credits_cost" real DEFAULT 0 NOT NULL, + "api_keys_cost" real DEFAULT 0 NOT NULL, + "credits_service_fee" real DEFAULT 0 NOT NULL, + "api_keys_service_fee" real DEFAULT 0 NOT NULL, + "credits_data_storage_cost" real DEFAULT 0 NOT NULL, + "api_keys_data_storage_cost" real DEFAULT 0 NOT NULL, + CONSTRAINT "project_hourly_model_stats_project_id_hour_timestamp_used_model_used_provider_unique" UNIQUE("project_id","hour_timestamp","used_model","used_provider") +); +--> statement-breakpoint +CREATE TABLE "project_hourly_stats" ( + "id" text PRIMARY KEY, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "project_id" text NOT NULL, + "hour_timestamp" timestamp NOT NULL, + "request_count" integer DEFAULT 0 NOT NULL, + "error_count" integer DEFAULT 0 NOT NULL, + "cache_count" integer DEFAULT 0 NOT NULL, + "streamed_count" integer DEFAULT 0 NOT NULL, + "non_streamed_count" integer DEFAULT 0 NOT NULL, + "completed_count" integer DEFAULT 0 NOT NULL, + "length_limit_count" integer DEFAULT 0 NOT NULL, + "content_filter_count" integer DEFAULT 0 NOT NULL, + "tool_calls_count" integer DEFAULT 0 NOT NULL, + "canceled_count" integer DEFAULT 0 NOT NULL, + "unknown_finish_count" integer DEFAULT 0 NOT NULL, + "client_error_count" integer DEFAULT 0 NOT NULL, + "gateway_error_count" integer DEFAULT 0 NOT NULL, + "upstream_error_count" integer DEFAULT 0 NOT NULL, + "input_tokens" numeric DEFAULT '0' NOT NULL, + "output_tokens" numeric DEFAULT '0' NOT NULL, + "total_tokens" numeric DEFAULT '0' NOT NULL, + "reasoning_tokens" numeric DEFAULT '0' NOT NULL, + "cached_tokens" numeric DEFAULT '0' NOT NULL, + "cost" real DEFAULT 0 NOT NULL, + "input_cost" real DEFAULT 0 NOT NULL, + "output_cost" real DEFAULT 0 NOT NULL, + "request_cost" real DEFAULT 0 NOT NULL, + "data_storage_cost" real DEFAULT 0 NOT NULL, + "service_fee" real DEFAULT 0 NOT NULL, + "discount_savings" real DEFAULT 0 NOT NULL, + "image_input_cost" real DEFAULT 0 NOT NULL, + "image_output_cost" real DEFAULT 0 NOT NULL, + "cached_input_cost" real DEFAULT 0 NOT NULL, + "credits_request_count" integer DEFAULT 0 NOT NULL, + "api_keys_request_count" integer DEFAULT 0 NOT NULL, + "credits_cost" real DEFAULT 0 NOT NULL, + "api_keys_cost" real DEFAULT 0 NOT NULL, + "credits_service_fee" real DEFAULT 0 NOT NULL, + "api_keys_service_fee" real DEFAULT 0 NOT NULL, + "credits_data_storage_cost" real DEFAULT 0 NOT NULL, + "api_keys_data_storage_cost" real DEFAULT 0 NOT NULL, + CONSTRAINT "project_hourly_stats_project_id_hour_timestamp_unique" UNIQUE("project_id","hour_timestamp") +); +--> statement-breakpoint +CREATE INDEX "api_key_hourly_model_stats_api_key_id_hour_timestamp_idx" ON "api_key_hourly_model_stats" ("api_key_id","hour_timestamp");--> statement-breakpoint +CREATE INDEX "api_key_hourly_model_stats_project_id_hour_timestamp_idx" ON "api_key_hourly_model_stats" ("project_id","hour_timestamp");--> statement-breakpoint +CREATE INDEX "api_key_hourly_model_stats_hour_timestamp_idx" ON "api_key_hourly_model_stats" ("hour_timestamp");--> statement-breakpoint +CREATE INDEX "api_key_hourly_stats_api_key_id_hour_timestamp_idx" ON "api_key_hourly_stats" ("api_key_id","hour_timestamp");--> statement-breakpoint +CREATE INDEX "api_key_hourly_stats_project_id_hour_timestamp_idx" ON "api_key_hourly_stats" ("project_id","hour_timestamp");--> statement-breakpoint +CREATE INDEX "api_key_hourly_stats_hour_timestamp_idx" ON "api_key_hourly_stats" ("hour_timestamp");--> statement-breakpoint +CREATE INDEX "project_hourly_model_stats_project_id_hour_timestamp_idx" ON "project_hourly_model_stats" ("project_id","hour_timestamp");--> statement-breakpoint +CREATE INDEX "project_hourly_model_stats_hour_timestamp_idx" ON "project_hourly_model_stats" ("hour_timestamp");--> statement-breakpoint +CREATE INDEX "project_hourly_stats_hour_timestamp_idx" ON "project_hourly_stats" ("hour_timestamp"); \ No newline at end of file diff --git a/packages/db/migrations/meta/1770740952_snapshot.json b/packages/db/migrations/meta/1770740952_snapshot.json new file mode 100644 index 0000000000..dfd2cac051 --- /dev/null +++ b/packages/db/migrations/meta/1770740952_snapshot.json @@ -0,0 +1,11151 @@ +{ + "version": "8", + "dialect": "postgres", + "id": "0cc932b3-1121-42eb-8399-2d8ac4000313", + "prevId": "e5fcbbc1-a429-4cb2-9b9d-329dc6387ffc", + "ddl": [ + { + "isRlsEnabled": false, + "name": "account", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "api_key", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "api_key_hourly_model_stats", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "api_key_hourly_stats", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "api_key_iam_rule", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "audit_log", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "chat", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "discount", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "guardrail_config", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "guardrail_rule", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "guardrail_violation", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "installation", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "lock", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "log", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "message", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "model", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "model_history", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "model_provider_mapping", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "model_provider_mapping_history", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "organization", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "organization_action", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "passkey", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "payment_method", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "project", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "project_hourly_model_stats", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "project_hourly_stats", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "provider", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "provider_key", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "referral", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "session", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "transaction", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "user", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "user_organization", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "verification", + "entityType": "tables", + "schema": "public" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "account_id", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "provider_id", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "access_token", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "refresh_token", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id_token", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "access_token_expires_at", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "refresh_token_expires_at", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "scope", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "password", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "api_key" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "api_key" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "api_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "token", + "entityType": "columns", + "schema": "public", + "table": "api_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "description", + "entityType": "columns", + "schema": "public", + "table": "api_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "'active'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "api_key" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "usage_limit", + "entityType": "columns", + "schema": "public", + "table": "api_key" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "usage", + "entityType": "columns", + "schema": "public", + "table": "api_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "project_id", + "entityType": "columns", + "schema": "public", + "table": "api_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "created_by", + "entityType": "columns", + "schema": "public", + "table": "api_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "api_key_id", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "project_id", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "hour_timestamp", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "used_model", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "used_provider", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "request_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "error_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cache_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "streamed_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "non_streamed_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "completed_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "length_limit_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "content_filter_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "tool_calls_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "canceled_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "unknown_finish_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "client_error_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "gateway_error_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "upstream_error_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "input_tokens", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "output_tokens", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_tokens", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "reasoning_tokens", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_tokens", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "input_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "output_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "request_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "service_fee", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "discount_savings", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "image_input_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "image_output_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_input_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_request_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_request_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_service_fee", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_service_fee", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "api_key_id", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "project_id", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "hour_timestamp", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "request_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "error_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cache_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "streamed_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "non_streamed_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "completed_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "length_limit_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "content_filter_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "tool_calls_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "canceled_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "unknown_finish_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "client_error_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "gateway_error_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "upstream_error_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "input_tokens", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "output_tokens", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_tokens", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "reasoning_tokens", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_tokens", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "input_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "output_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "request_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "service_fee", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "discount_savings", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "image_input_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "image_output_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_input_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_request_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_request_count", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_service_fee", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_service_fee", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "api_key_id", + "entityType": "columns", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "rule_type", + "entityType": "columns", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "type": "json", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "rule_value", + "entityType": "columns", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'active'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "audit_log" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "audit_log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "audit_log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "audit_log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "action", + "entityType": "columns", + "schema": "public", + "table": "audit_log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resource_type", + "entityType": "columns", + "schema": "public", + "table": "audit_log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resource_id", + "entityType": "columns", + "schema": "public", + "table": "audit_log" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "metadata", + "entityType": "columns", + "schema": "public", + "table": "audit_log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "chat" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "chat" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "chat" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "title", + "entityType": "columns", + "schema": "public", + "table": "chat" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "chat" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "model", + "entityType": "columns", + "schema": "public", + "table": "chat" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "'active'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "chat" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "web_search", + "entityType": "columns", + "schema": "public", + "table": "chat" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "discount" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "discount" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "discount" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "discount" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "provider", + "entityType": "columns", + "schema": "public", + "table": "discount" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "model", + "entityType": "columns", + "schema": "public", + "table": "discount" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "discount_percent", + "entityType": "columns", + "schema": "public", + "table": "discount" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reason", + "entityType": "columns", + "schema": "public", + "table": "discount" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "discount" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "guardrail_config" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "guardrail_config" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "true", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "enabled", + "entityType": "columns", + "schema": "public", + "table": "guardrail_config" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "type": "unknown", + "value": "'{\"prompt_injection\":{\"enabled\":true,\"action\":\"block\"},\"jailbreak\":{\"enabled\":true,\"action\":\"block\"},\"pii_detection\":{\"enabled\":true,\"action\":\"redact\"},\"secrets\":{\"enabled\":true,\"action\":\"block\"},\"file_types\":{\"enabled\":true,\"action\":\"block\"},\"document_leakage\":{\"enabled\":false,\"action\":\"warn\"}}'" + }, + "generated": null, + "identity": null, + "name": "system_rules", + "entityType": "columns", + "schema": "public", + "table": "guardrail_config" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "10", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "max_file_size_mb", + "entityType": "columns", + "schema": "public", + "table": "guardrail_config" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 1, + "default": { + "value": "'{image/jpeg,image/png,image/gif,image/webp}'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "allowed_file_types", + "entityType": "columns", + "schema": "public", + "table": "guardrail_config" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "'redact'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "pii_action", + "entityType": "columns", + "schema": "public", + "table": "guardrail_config" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "guardrail_config" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "guardrail_config" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "guardrail_rule" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "guardrail_rule" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "guardrail_rule" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "type", + "entityType": "columns", + "schema": "public", + "table": "guardrail_rule" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "config", + "entityType": "columns", + "schema": "public", + "table": "guardrail_rule" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "100", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "priority", + "entityType": "columns", + "schema": "public", + "table": "guardrail_rule" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "true", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "enabled", + "entityType": "columns", + "schema": "public", + "table": "guardrail_rule" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'block'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "action", + "entityType": "columns", + "schema": "public", + "table": "guardrail_rule" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "guardrail_rule" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "guardrail_rule" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "log_id", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "rule_id", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "rule_name", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "category", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "action_taken", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "matched_pattern", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "matched_content", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "content_hash", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "api_key_id", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "model", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "guardrail_violation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "installation" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "installation" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "installation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "uuid", + "entityType": "columns", + "schema": "public", + "table": "installation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "type", + "entityType": "columns", + "schema": "public", + "table": "installation" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "lock" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "lock" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "lock" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "key", + "entityType": "columns", + "schema": "public", + "table": "lock" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "request_id", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "project_id", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "api_key_id", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "duration", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "time_to_first_token", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "time_to_first_reasoning_token", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "requested_model", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "requested_provider", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "used_model", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "used_model_mapping", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "used_provider", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "response_size", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "content", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reasoning_content", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "tools", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "tool_choice", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "tool_results", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "finish_reason", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "unified_finish_reason", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "prompt_tokens", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "completion_tokens", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "total_tokens", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reasoning_tokens", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "cached_tokens", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "messages", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "temperature", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "max_tokens", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "top_p", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "frequency_penalty", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "presence_penalty", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reasoning_effort", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "effort", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "response_format", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "has_error", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "error_details", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "cost", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "input_cost", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "output_cost", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "cached_input_cost", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "request_cost", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "web_search_cost", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "image_input_tokens", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "image_output_tokens", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "image_input_cost", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "image_output_cost", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "estimated_cost", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "discount", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "service_fee", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "pricing_tier", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "canceled", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "streamed", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "mode", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "used_mode", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "source", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "custom_headers", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "routing_metadata", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "processed_at", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "raw_request", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "raw_response", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "upstream_request", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "upstream_response", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "trace_id", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "data_retention_cleaned_up", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "params", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_agent", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "plugins", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "plugin_results", + "entityType": "columns", + "schema": "public", + "table": "log" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "message" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "message" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "message" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "chat_id", + "entityType": "columns", + "schema": "public", + "table": "message" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "role", + "entityType": "columns", + "schema": "public", + "table": "message" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "content", + "entityType": "columns", + "schema": "public", + "table": "message" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "images", + "entityType": "columns", + "schema": "public", + "table": "message" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reasoning", + "entityType": "columns", + "schema": "public", + "table": "message" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "tools", + "entityType": "columns", + "schema": "public", + "table": "message" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "sequence", + "entityType": "columns", + "schema": "public", + "table": "message" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "released_at", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'(empty)'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "json", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "type": "unknown", + "value": "'[]'" + }, + "generated": null, + "identity": null, + "name": "aliases", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'(empty)'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "description", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "family", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "free", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "json", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "type": "unknown", + "value": "'[\"text\"]'" + }, + "generated": null, + "identity": null, + "name": "output", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'stable'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "stability", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'active'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "logs_count", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "errors_count", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "client_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "gateway_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "upstream_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_count", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "avg_time_to_first_token", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "avg_time_to_first_reasoning_token", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "stats_updated_at", + "entityType": "columns", + "schema": "public", + "table": "model" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "model_id", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "minute_timestamp", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "logs_count", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "client_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "gateway_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "upstream_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_count", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_input_tokens", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_output_tokens", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_tokens", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_reasoning_tokens", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_cached_tokens", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_duration", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_time_to_first_token", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_time_to_first_reasoning_token", + "entityType": "columns", + "schema": "public", + "table": "model_history" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "model_id", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "provider_id", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "model_name", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "input_price", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "output_price", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "cached_input_price", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "image_input_price", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "request_price", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "context_size", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "max_output", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "streaming", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "vision", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reasoning", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reasoning_output", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "tools", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "json_output", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "json_output_schema", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "web_search", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "web_search_price", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "discount", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'stable'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "stability", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "json", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "supported_parameters", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "test", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "deprecated_at", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "deactivated_at", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'active'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "logs_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "client_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "gateway_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "upstream_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "avg_time_to_first_token", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "avg_time_to_first_reasoning_token", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "stats_updated_at", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "model_id", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "provider_id", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "model_provider_mapping_id", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "minute_timestamp", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "logs_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "client_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "gateway_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "upstream_errors_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_count", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_input_tokens", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_output_tokens", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_tokens", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_reasoning_tokens", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_cached_tokens", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_duration", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_time_to_first_token", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_time_to_first_reasoning_token", + "entityType": "columns", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "billing_email", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "billing_company", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "billing_address", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "billing_tax_id", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "billing_notes", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "stripe_customer_id", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "stripe_subscription_id", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "auto_top_up_enabled", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "'10'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "auto_top_up_threshold", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "'10'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "auto_top_up_amount", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'free'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "plan", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "plan_expires_at", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "subscription_cancelled", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "trial_start_date", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "trial_end_date", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "is_trial_active", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'none'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "retention_level", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "'active'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "referral_earnings", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "payment_failure_count", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "last_payment_failure_at", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "is_personal", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'none'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "dev_plan", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "dev_plan_credits_used", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "dev_plan_credits_limit", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "dev_plan_billing_cycle_start", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "dev_plan_stripe_subscription_id", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "dev_plan_cancelled", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "dev_plan_expires_at", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "dev_plan_allow_all_models", + "entityType": "columns", + "schema": "public", + "table": "organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "organization_action" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "organization_action" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "organization_action" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "organization_action" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "type", + "entityType": "columns", + "schema": "public", + "table": "organization_action" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "amount", + "entityType": "columns", + "schema": "public", + "table": "organization_action" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "description", + "entityType": "columns", + "schema": "public", + "table": "organization_action" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "public_key", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "credential_id", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "counter", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "device_type", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "backed_up", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "transports", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "payment_method" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "payment_method" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "payment_method" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "stripe_payment_method_id", + "entityType": "columns", + "schema": "public", + "table": "payment_method" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "payment_method" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "type", + "entityType": "columns", + "schema": "public", + "table": "payment_method" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "is_default", + "entityType": "columns", + "schema": "public", + "table": "payment_method" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "project" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "project" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "project" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "project" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "project" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "caching_enabled", + "entityType": "columns", + "schema": "public", + "table": "project" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "60", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cache_duration_seconds", + "entityType": "columns", + "schema": "public", + "table": "project" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'hybrid'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "mode", + "entityType": "columns", + "schema": "public", + "table": "project" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "'active'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "project" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "project_id", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "hour_timestamp", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "used_model", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "used_provider", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "request_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "error_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cache_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "streamed_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "non_streamed_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "completed_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "length_limit_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "content_filter_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "tool_calls_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "canceled_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "unknown_finish_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "client_error_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "gateway_error_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "upstream_error_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "input_tokens", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "output_tokens", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_tokens", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "reasoning_tokens", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_tokens", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "input_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "output_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "request_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "service_fee", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "discount_savings", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "image_input_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "image_output_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_input_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_request_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_request_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_service_fee", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_service_fee", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "project_id", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "hour_timestamp", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "request_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "error_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cache_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "streamed_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "non_streamed_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "completed_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "length_limit_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "content_filter_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "tool_calls_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "canceled_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "unknown_finish_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "client_error_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "gateway_error_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "upstream_error_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "input_tokens", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "output_tokens", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "total_tokens", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "reasoning_tokens", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'0'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_tokens", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "input_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "output_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "request_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "service_fee", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "discount_savings", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "image_input_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "image_output_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_input_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_request_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_request_count", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_service_fee", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_service_fee", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "credits_data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "real", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "api_keys_data_storage_cost", + "entityType": "columns", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "description", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "streaming", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "cancellation", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "color", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "website", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "announcement", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'active'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "logs_count", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "errors_count", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "client_errors_count", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "gateway_errors_count", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "upstream_errors_count", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "0", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "cached_count", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "avg_time_to_first_token", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "real", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "avg_time_to_first_reasoning_token", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "stats_updated_at", + "entityType": "columns", + "schema": "public", + "table": "provider" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "provider_key" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "provider_key" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "provider_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "token", + "entityType": "columns", + "schema": "public", + "table": "provider_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "provider", + "entityType": "columns", + "schema": "public", + "table": "provider_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "provider_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "base_url", + "entityType": "columns", + "schema": "public", + "table": "provider_key" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "options", + "entityType": "columns", + "schema": "public", + "table": "provider_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": { + "value": "'active'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "provider_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "provider_key" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "referral" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "referral" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "referral" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "referrer_organization_id", + "entityType": "columns", + "schema": "public", + "table": "referral" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "referred_organization_id", + "entityType": "columns", + "schema": "public", + "table": "referral" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "token", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "ip_address", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_agent", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "type", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "amount", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "numeric", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "credit_amount", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'USD'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "currency", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'completed'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "stripe_payment_intent_id", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "stripe_invoice_id", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "description", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "related_transaction_id", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "refund_reason", + "entityType": "columns", + "schema": "public", + "table": "transaction" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "email", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "email_verified", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "image", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "false", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "onboarding_completed", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "user_organization" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "user_organization" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "user_organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "user_organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "organization_id", + "entityType": "columns", + "schema": "public", + "table": "user_organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "'owner'", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "role", + "entityType": "columns", + "schema": "public", + "table": "user_organization" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "identifier", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "value", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": { + "value": "now()", + "type": "unknown" + }, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "timestamp", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "account_user_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "account" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "project_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_project_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "created_by", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_created_by_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "api_key_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "hour_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_hourly_model_stats_api_key_id_hour_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "project_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "hour_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_hourly_model_stats_project_id_hour_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "hour_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_hourly_model_stats_hour_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "api_key_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "hour_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_hourly_stats_api_key_id_hour_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "project_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "hour_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_hourly_stats_project_id_hour_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "hour_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_hourly_stats_hour_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "api_key_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_iam_rule_api_key_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "rule_type", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_iam_rule_rule_type_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "api_key_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "status", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "api_key_iam_rule_api_key_id_status_idx", + "entityType": "indexes", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "created_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "audit_log_organization_id_created_at_idx", + "entityType": "indexes", + "schema": "public", + "table": "audit_log" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "audit_log_user_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "audit_log" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "action", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "audit_log_action_idx", + "entityType": "indexes", + "schema": "public", + "table": "audit_log" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "resource_type", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "audit_log_resource_type_idx", + "entityType": "indexes", + "schema": "public", + "table": "audit_log" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "chat_user_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "chat" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "discount_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "discount" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "provider", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "discount_provider_idx", + "entityType": "indexes", + "schema": "public", + "table": "discount" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "model", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "discount_model_idx", + "entityType": "indexes", + "schema": "public", + "table": "discount" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "guardrail_config_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "guardrail_config" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "guardrail_rule_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "guardrail_rule" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "priority", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "guardrail_rule_priority_idx", + "entityType": "indexes", + "schema": "public", + "table": "guardrail_rule" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "created_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "guardrail_violation_org_created_idx", + "entityType": "indexes", + "schema": "public", + "table": "guardrail_violation" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "rule_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "created_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "guardrail_violation_rule_created_idx", + "entityType": "indexes", + "schema": "public", + "table": "guardrail_violation" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "project_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "created_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "log_project_id_created_at_idx", + "entityType": "indexes", + "schema": "public", + "table": "log" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "created_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "used_model", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "used_provider", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "log_created_at_used_model_used_provider_idx", + "entityType": "indexes", + "schema": "public", + "table": "log" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "project_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "created_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": "data_retention_cleaned_up = false", + "with": "", + "method": "btree", + "concurrently": false, + "name": "log_data_retention_pending_idx", + "entityType": "indexes", + "schema": "public", + "table": "log" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "project_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "used_model", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "log_project_id_used_model_idx", + "entityType": "indexes", + "schema": "public", + "table": "log" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "created_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": "processed_at IS NULL", + "with": "", + "method": "btree", + "concurrently": false, + "name": "log_processed_at_null_idx", + "entityType": "indexes", + "schema": "public", + "table": "log" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "chat_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "message_chat_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "message" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "status", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "model_status_idx", + "entityType": "indexes", + "schema": "public", + "table": "model" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "minute_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "model_history_minute_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "model_history" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "status", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "model_provider_mapping_status_idx", + "entityType": "indexes", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "minute_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "model_provider_mapping_history_minute_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "minute_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "provider_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "model_provider_mapping_history_minute_timestamp_provider_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "minute_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "model_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "model_provider_mapping_history_minute_timestamp_model_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "organization_action_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "organization_action" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "passkey_user_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "passkey" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "payment_method_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "payment_method" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "project_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "project" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "project_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "hour_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "project_hourly_model_stats_project_id_hour_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "hour_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "project_hourly_model_stats_hour_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "hour_timestamp", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "project_hourly_stats_hour_timestamp_idx", + "entityType": "indexes", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "status", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "provider_status_idx", + "entityType": "indexes", + "schema": "public", + "table": "provider" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "provider_key_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "provider_key" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "referrer_organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "referral_referrer_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "referral" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "referred_organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "referral_referred_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "referral" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "session_user_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "session" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "transaction_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "transaction" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "user_organization_user_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "user_organization" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "organization_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "user_organization_organization_id_idx", + "entityType": "indexes", + "schema": "public", + "table": "user_organization" + }, + { + "nameExplicit": false, + "columns": [ + "user_id" + ], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "account_user_id_user_id_fk", + "entityType": "fks", + "schema": "public", + "table": "account" + }, + { + "nameExplicit": false, + "columns": [ + "project_id" + ], + "schemaTo": "public", + "tableTo": "project", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "api_key_project_id_project_id_fk", + "entityType": "fks", + "schema": "public", + "table": "api_key" + }, + { + "nameExplicit": false, + "columns": [ + "created_by" + ], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "api_key_created_by_user_id_fk", + "entityType": "fks", + "schema": "public", + "table": "api_key" + }, + { + "nameExplicit": false, + "columns": [ + "api_key_id" + ], + "schemaTo": "public", + "tableTo": "api_key", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "api_key_iam_rule_api_key_id_api_key_id_fk", + "entityType": "fks", + "schema": "public", + "table": "api_key_iam_rule" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "audit_log_organization_id_organization_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "audit_log" + }, + { + "nameExplicit": false, + "columns": [ + "user_id" + ], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "audit_log_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "audit_log" + }, + { + "nameExplicit": false, + "columns": [ + "user_id" + ], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "chat_user_id_user_id_fk", + "entityType": "fks", + "schema": "public", + "table": "chat" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "discount_organization_id_organization_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "discount" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "guardrail_config_organization_id_organization_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "guardrail_config" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "guardrail_rule_organization_id_organization_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "guardrail_rule" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "guardrail_violation_organization_id_organization_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "guardrail_violation" + }, + { + "nameExplicit": false, + "columns": [ + "chat_id" + ], + "schemaTo": "public", + "tableTo": "chat", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "message_chat_id_chat_id_fk", + "entityType": "fks", + "schema": "public", + "table": "message" + }, + { + "nameExplicit": false, + "columns": [ + "model_id" + ], + "schemaTo": "public", + "tableTo": "model", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "model_provider_mapping_model_id_model_id_fk", + "entityType": "fks", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "nameExplicit": false, + "columns": [ + "provider_id" + ], + "schemaTo": "public", + "tableTo": "provider", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "model_provider_mapping_provider_id_provider_id_fk", + "entityType": "fks", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "organization_action_organization_id_organization_id_fk", + "entityType": "fks", + "schema": "public", + "table": "organization_action" + }, + { + "nameExplicit": false, + "columns": [ + "user_id" + ], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "passkey_user_id_user_id_fk", + "entityType": "fks", + "schema": "public", + "table": "passkey" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "payment_method_organization_id_organization_id_fk", + "entityType": "fks", + "schema": "public", + "table": "payment_method" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "project_organization_id_organization_id_fk", + "entityType": "fks", + "schema": "public", + "table": "project" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "provider_key_organization_id_organization_id_fk", + "entityType": "fks", + "schema": "public", + "table": "provider_key" + }, + { + "nameExplicit": false, + "columns": [ + "referrer_organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "referral_referrer_organization_id_organization_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "referral" + }, + { + "nameExplicit": false, + "columns": [ + "referred_organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "referral_referred_organization_id_organization_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "referral" + }, + { + "nameExplicit": false, + "columns": [ + "user_id" + ], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "session_user_id_user_id_fk", + "entityType": "fks", + "schema": "public", + "table": "session" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "transaction_organization_id_organization_id_fk", + "entityType": "fks", + "schema": "public", + "table": "transaction" + }, + { + "nameExplicit": false, + "columns": [ + "user_id" + ], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "user_organization_user_id_user_id_fk", + "entityType": "fks", + "schema": "public", + "table": "user_organization" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "schemaTo": "public", + "tableTo": "organization", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "user_organization_organization_id_organization_id_fk", + "entityType": "fks", + "schema": "public", + "table": "user_organization" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "account_pkey", + "schema": "public", + "table": "account", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "api_key_pkey", + "schema": "public", + "table": "api_key", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "api_key_hourly_model_stats_pkey", + "schema": "public", + "table": "api_key_hourly_model_stats", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "api_key_hourly_stats_pkey", + "schema": "public", + "table": "api_key_hourly_stats", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "api_key_iam_rule_pkey", + "schema": "public", + "table": "api_key_iam_rule", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "audit_log_pkey", + "schema": "public", + "table": "audit_log", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "chat_pkey", + "schema": "public", + "table": "chat", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "discount_pkey", + "schema": "public", + "table": "discount", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "guardrail_config_pkey", + "schema": "public", + "table": "guardrail_config", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "guardrail_rule_pkey", + "schema": "public", + "table": "guardrail_rule", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "guardrail_violation_pkey", + "schema": "public", + "table": "guardrail_violation", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "installation_pkey", + "schema": "public", + "table": "installation", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "lock_pkey", + "schema": "public", + "table": "lock", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "log_pkey", + "schema": "public", + "table": "log", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "message_pkey", + "schema": "public", + "table": "message", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "model_pkey", + "schema": "public", + "table": "model", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "model_history_pkey", + "schema": "public", + "table": "model_history", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "model_provider_mapping_pkey", + "schema": "public", + "table": "model_provider_mapping", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "model_provider_mapping_history_pkey", + "schema": "public", + "table": "model_provider_mapping_history", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "organization_pkey", + "schema": "public", + "table": "organization", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "organization_action_pkey", + "schema": "public", + "table": "organization_action", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "passkey_pkey", + "schema": "public", + "table": "passkey", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "payment_method_pkey", + "schema": "public", + "table": "payment_method", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "project_pkey", + "schema": "public", + "table": "project", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "project_hourly_model_stats_pkey", + "schema": "public", + "table": "project_hourly_model_stats", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "project_hourly_stats_pkey", + "schema": "public", + "table": "project_hourly_stats", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "provider_pkey", + "schema": "public", + "table": "provider", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "provider_key_pkey", + "schema": "public", + "table": "provider_key", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "referral_pkey", + "schema": "public", + "table": "referral", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "session_pkey", + "schema": "public", + "table": "session", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "transaction_pkey", + "schema": "public", + "table": "transaction", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "user_pkey", + "schema": "public", + "table": "user", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "user_organization_pkey", + "schema": "public", + "table": "user_organization", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "verification_pkey", + "schema": "public", + "table": "verification", + "entityType": "pks" + }, + { + "nameExplicit": false, + "columns": [ + "api_key_id", + "hour_timestamp", + "used_model", + "used_provider" + ], + "nullsNotDistinct": false, + "name": "api_key_hourly_model_stats_api_key_id_hour_timestamp_used_model_used_provider_unique", + "entityType": "uniques", + "schema": "public", + "table": "api_key_hourly_model_stats" + }, + { + "nameExplicit": false, + "columns": [ + "api_key_id", + "hour_timestamp" + ], + "nullsNotDistinct": false, + "name": "api_key_hourly_stats_api_key_id_hour_timestamp_unique", + "entityType": "uniques", + "schema": "public", + "table": "api_key_hourly_stats" + }, + { + "nameExplicit": true, + "columns": [ + "organization_id", + "provider", + "model" + ], + "nullsNotDistinct": false, + "name": "discount_org_provider_model_unique", + "entityType": "uniques", + "schema": "public", + "table": "discount" + }, + { + "nameExplicit": false, + "columns": [ + "model_id", + "minute_timestamp" + ], + "nullsNotDistinct": false, + "name": "model_history_model_id_minute_timestamp_unique", + "entityType": "uniques", + "schema": "public", + "table": "model_history" + }, + { + "nameExplicit": false, + "columns": [ + "model_id", + "provider_id" + ], + "nullsNotDistinct": false, + "name": "model_provider_mapping_model_id_provider_id_unique", + "entityType": "uniques", + "schema": "public", + "table": "model_provider_mapping" + }, + { + "nameExplicit": false, + "columns": [ + "model_provider_mapping_id", + "minute_timestamp" + ], + "nullsNotDistinct": false, + "name": "model_provider_mapping_history_model_provider_mapping_id_minute_timestamp_unique", + "entityType": "uniques", + "schema": "public", + "table": "model_provider_mapping_history" + }, + { + "nameExplicit": false, + "columns": [ + "project_id", + "hour_timestamp", + "used_model", + "used_provider" + ], + "nullsNotDistinct": false, + "name": "project_hourly_model_stats_project_id_hour_timestamp_used_model_used_provider_unique", + "entityType": "uniques", + "schema": "public", + "table": "project_hourly_model_stats" + }, + { + "nameExplicit": false, + "columns": [ + "project_id", + "hour_timestamp" + ], + "nullsNotDistinct": false, + "name": "project_hourly_stats_project_id_hour_timestamp_unique", + "entityType": "uniques", + "schema": "public", + "table": "project_hourly_stats" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id", + "name" + ], + "nullsNotDistinct": false, + "name": "provider_key_organization_id_name_unique", + "entityType": "uniques", + "schema": "public", + "table": "provider_key" + }, + { + "nameExplicit": false, + "columns": [ + "token" + ], + "nullsNotDistinct": false, + "name": "api_key_token_unique", + "schema": "public", + "table": "api_key", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": [ + "organization_id" + ], + "nullsNotDistinct": false, + "name": "guardrail_config_organization_id_key", + "schema": "public", + "table": "guardrail_config", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": [ + "uuid" + ], + "nullsNotDistinct": false, + "name": "installation_uuid_unique", + "schema": "public", + "table": "installation", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": [ + "key" + ], + "nullsNotDistinct": false, + "name": "lock_key_unique", + "schema": "public", + "table": "lock", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": [ + "stripe_customer_id" + ], + "nullsNotDistinct": false, + "name": "organization_stripe_customer_id_key", + "schema": "public", + "table": "organization", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": [ + "stripe_subscription_id" + ], + "nullsNotDistinct": false, + "name": "organization_stripe_subscription_id_key", + "schema": "public", + "table": "organization", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": [ + "dev_plan_stripe_subscription_id" + ], + "nullsNotDistinct": false, + "name": "organization_dev_plan_stripe_subscription_id_key", + "schema": "public", + "table": "organization", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": [ + "referred_organization_id" + ], + "nullsNotDistinct": false, + "name": "referral_referred_organization_id_key", + "schema": "public", + "table": "referral", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": [ + "token" + ], + "nullsNotDistinct": false, + "name": "session_token_unique", + "schema": "public", + "table": "session", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": [ + "email" + ], + "nullsNotDistinct": false, + "name": "user_email_unique", + "schema": "public", + "table": "user", + "entityType": "uniques" + } + ], + "renames": [] +} \ No newline at end of file diff --git a/packages/db/migrations/meta/_journal.json b/packages/db/migrations/meta/_journal.json index 8403aa194e..25fd79e226 100644 --- a/packages/db/migrations/meta/_journal.json +++ b/packages/db/migrations/meta/_journal.json @@ -624,6 +624,13 @@ "when": 1770632238756, "tag": "1770632238_lean_sharon_carter", "breakpoints": true + }, + { + "idx": 89, + "version": "8", + "when": 1770740952200, + "tag": "1770740952_same_lake", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/src/schema.ts b/packages/db/src/schema.ts index 3c7b879650..1d4811a575 100644 --- a/packages/db/src/schema.ts +++ b/packages/db/src/schema.ts @@ -1173,3 +1173,304 @@ export const discount = pgTable( index("discount_model_idx").on(table.model), ], ); + +// Project hourly statistics aggregation - used for fast dashboard queries +export const projectHourlyStats = pgTable( + "project_hourly_stats", + { + id: text().primaryKey().notNull().$defaultFn(shortid), + createdAt: timestamp().notNull().defaultNow(), + updatedAt: timestamp() + .notNull() + .defaultNow() + .$onUpdate(() => new Date()), + projectId: text().notNull(), + hourTimestamp: timestamp().notNull(), // Start of the hour bucket + // Request counts + requestCount: integer().notNull().default(0), + errorCount: integer().notNull().default(0), + cacheCount: integer().notNull().default(0), + streamedCount: integer().notNull().default(0), + nonStreamedCount: integer().notNull().default(0), + // Unified finish reason counts + completedCount: integer().notNull().default(0), + lengthLimitCount: integer().notNull().default(0), + contentFilterCount: integer().notNull().default(0), + toolCallsCount: integer().notNull().default(0), + canceledCount: integer().notNull().default(0), + unknownFinishCount: integer().notNull().default(0), + // Error type counts (subset of errorCount) + clientErrorCount: integer().notNull().default(0), + gatewayErrorCount: integer().notNull().default(0), + upstreamErrorCount: integer().notNull().default(0), + // Token counts + inputTokens: decimal().notNull().default("0"), + outputTokens: decimal().notNull().default("0"), + totalTokens: decimal().notNull().default("0"), + reasoningTokens: decimal().notNull().default("0"), + cachedTokens: decimal().notNull().default("0"), + // Costs + cost: real().notNull().default(0), + inputCost: real().notNull().default(0), + outputCost: real().notNull().default(0), + requestCost: real().notNull().default(0), + dataStorageCost: real().notNull().default(0), + serviceFee: real().notNull().default(0), + discountSavings: real().notNull().default(0), + imageInputCost: real().notNull().default(0), + imageOutputCost: real().notNull().default(0), + cachedInputCost: real().notNull().default(0), + // Per-mode breakdowns + creditsRequestCount: integer().notNull().default(0), + apiKeysRequestCount: integer().notNull().default(0), + creditsCost: real().notNull().default(0), + apiKeysCost: real().notNull().default(0), + creditsServiceFee: real().notNull().default(0), + apiKeysServiceFee: real().notNull().default(0), + creditsDataStorageCost: real().notNull().default(0), + apiKeysDataStorageCost: real().notNull().default(0), + }, + (table) => [ + // Unique constraint for one record per project-hour (also creates implicit index) + unique().on(table.projectId, table.hourTimestamp), + // Index for worker refresh queries (find hours to update) + index("project_hourly_stats_hour_timestamp_idx").on(table.hourTimestamp), + ], +); + +// Project hourly model statistics aggregation - model breakdown per hour +export const projectHourlyModelStats = pgTable( + "project_hourly_model_stats", + { + id: text().primaryKey().notNull().$defaultFn(shortid), + createdAt: timestamp().notNull().defaultNow(), + updatedAt: timestamp() + .notNull() + .defaultNow() + .$onUpdate(() => new Date()), + projectId: text().notNull(), + hourTimestamp: timestamp().notNull(), // Start of the hour bucket + usedModel: text().notNull(), + usedProvider: text().notNull(), + // Request counts + requestCount: integer().notNull().default(0), + errorCount: integer().notNull().default(0), + cacheCount: integer().notNull().default(0), + streamedCount: integer().notNull().default(0), + nonStreamedCount: integer().notNull().default(0), + // Unified finish reason counts + completedCount: integer().notNull().default(0), + lengthLimitCount: integer().notNull().default(0), + contentFilterCount: integer().notNull().default(0), + toolCallsCount: integer().notNull().default(0), + canceledCount: integer().notNull().default(0), + unknownFinishCount: integer().notNull().default(0), + // Error type counts (subset of errorCount) + clientErrorCount: integer().notNull().default(0), + gatewayErrorCount: integer().notNull().default(0), + upstreamErrorCount: integer().notNull().default(0), + // Token counts + inputTokens: decimal().notNull().default("0"), + outputTokens: decimal().notNull().default("0"), + totalTokens: decimal().notNull().default("0"), + reasoningTokens: decimal().notNull().default("0"), + cachedTokens: decimal().notNull().default("0"), + // Costs + cost: real().notNull().default(0), + inputCost: real().notNull().default(0), + outputCost: real().notNull().default(0), + requestCost: real().notNull().default(0), + dataStorageCost: real().notNull().default(0), + serviceFee: real().notNull().default(0), + discountSavings: real().notNull().default(0), + imageInputCost: real().notNull().default(0), + imageOutputCost: real().notNull().default(0), + cachedInputCost: real().notNull().default(0), + // Per-mode breakdowns + creditsRequestCount: integer().notNull().default(0), + apiKeysRequestCount: integer().notNull().default(0), + creditsCost: real().notNull().default(0), + apiKeysCost: real().notNull().default(0), + creditsServiceFee: real().notNull().default(0), + apiKeysServiceFee: real().notNull().default(0), + creditsDataStorageCost: real().notNull().default(0), + apiKeysDataStorageCost: real().notNull().default(0), + }, + (table) => [ + // Unique constraint for one record per project-hour-model-provider + unique().on( + table.projectId, + table.hourTimestamp, + table.usedModel, + table.usedProvider, + ), + // Index for dashboard queries (project + time range) + index("project_hourly_model_stats_project_id_hour_timestamp_idx").on( + table.projectId, + table.hourTimestamp, + ), + // Index for worker refresh queries + index("project_hourly_model_stats_hour_timestamp_idx").on( + table.hourTimestamp, + ), + ], +); + +// API key hourly statistics aggregation - for per-key breakdown queries +export const apiKeyHourlyStats = pgTable( + "api_key_hourly_stats", + { + id: text().primaryKey().notNull().$defaultFn(shortid), + createdAt: timestamp().notNull().defaultNow(), + updatedAt: timestamp() + .notNull() + .defaultNow() + .$onUpdate(() => new Date()), + apiKeyId: text().notNull(), + projectId: text().notNull(), // Denormalized for efficient queries + hourTimestamp: timestamp().notNull(), // Start of the hour bucket + // Request counts + requestCount: integer().notNull().default(0), + errorCount: integer().notNull().default(0), + cacheCount: integer().notNull().default(0), + streamedCount: integer().notNull().default(0), + nonStreamedCount: integer().notNull().default(0), + // Unified finish reason counts + completedCount: integer().notNull().default(0), + lengthLimitCount: integer().notNull().default(0), + contentFilterCount: integer().notNull().default(0), + toolCallsCount: integer().notNull().default(0), + canceledCount: integer().notNull().default(0), + unknownFinishCount: integer().notNull().default(0), + // Error type counts (subset of errorCount) + clientErrorCount: integer().notNull().default(0), + gatewayErrorCount: integer().notNull().default(0), + upstreamErrorCount: integer().notNull().default(0), + // Token counts + inputTokens: decimal().notNull().default("0"), + outputTokens: decimal().notNull().default("0"), + totalTokens: decimal().notNull().default("0"), + reasoningTokens: decimal().notNull().default("0"), + cachedTokens: decimal().notNull().default("0"), + // Costs + cost: real().notNull().default(0), + inputCost: real().notNull().default(0), + outputCost: real().notNull().default(0), + requestCost: real().notNull().default(0), + dataStorageCost: real().notNull().default(0), + serviceFee: real().notNull().default(0), + discountSavings: real().notNull().default(0), + imageInputCost: real().notNull().default(0), + imageOutputCost: real().notNull().default(0), + cachedInputCost: real().notNull().default(0), + // Per-mode breakdowns + creditsRequestCount: integer().notNull().default(0), + apiKeysRequestCount: integer().notNull().default(0), + creditsCost: real().notNull().default(0), + apiKeysCost: real().notNull().default(0), + creditsServiceFee: real().notNull().default(0), + apiKeysServiceFee: real().notNull().default(0), + creditsDataStorageCost: real().notNull().default(0), + apiKeysDataStorageCost: real().notNull().default(0), + }, + (table) => [ + // Unique constraint for one record per api-key-hour + unique().on(table.apiKeyId, table.hourTimestamp), + // Index for dashboard queries (api key + time range) + index("api_key_hourly_stats_api_key_id_hour_timestamp_idx").on( + table.apiKeyId, + table.hourTimestamp, + ), + // Index for project-level queries (all keys in a project) + index("api_key_hourly_stats_project_id_hour_timestamp_idx").on( + table.projectId, + table.hourTimestamp, + ), + // Index for worker refresh queries + index("api_key_hourly_stats_hour_timestamp_idx").on(table.hourTimestamp), + ], +); + +// API key hourly model statistics aggregation - model breakdown per API key per hour +export const apiKeyHourlyModelStats = pgTable( + "api_key_hourly_model_stats", + { + id: text().primaryKey().notNull().$defaultFn(shortid), + createdAt: timestamp().notNull().defaultNow(), + updatedAt: timestamp() + .notNull() + .defaultNow() + .$onUpdate(() => new Date()), + apiKeyId: text().notNull(), + projectId: text().notNull(), // Denormalized for efficient queries + hourTimestamp: timestamp().notNull(), // Start of the hour bucket + usedModel: text().notNull(), + usedProvider: text().notNull(), + // Request counts + requestCount: integer().notNull().default(0), + errorCount: integer().notNull().default(0), + cacheCount: integer().notNull().default(0), + streamedCount: integer().notNull().default(0), + nonStreamedCount: integer().notNull().default(0), + // Unified finish reason counts + completedCount: integer().notNull().default(0), + lengthLimitCount: integer().notNull().default(0), + contentFilterCount: integer().notNull().default(0), + toolCallsCount: integer().notNull().default(0), + canceledCount: integer().notNull().default(0), + unknownFinishCount: integer().notNull().default(0), + // Error type counts (subset of errorCount) + clientErrorCount: integer().notNull().default(0), + gatewayErrorCount: integer().notNull().default(0), + upstreamErrorCount: integer().notNull().default(0), + // Token counts + inputTokens: decimal().notNull().default("0"), + outputTokens: decimal().notNull().default("0"), + totalTokens: decimal().notNull().default("0"), + reasoningTokens: decimal().notNull().default("0"), + cachedTokens: decimal().notNull().default("0"), + // Costs + cost: real().notNull().default(0), + inputCost: real().notNull().default(0), + outputCost: real().notNull().default(0), + requestCost: real().notNull().default(0), + dataStorageCost: real().notNull().default(0), + serviceFee: real().notNull().default(0), + discountSavings: real().notNull().default(0), + imageInputCost: real().notNull().default(0), + imageOutputCost: real().notNull().default(0), + cachedInputCost: real().notNull().default(0), + // Per-mode breakdowns + creditsRequestCount: integer().notNull().default(0), + apiKeysRequestCount: integer().notNull().default(0), + creditsCost: real().notNull().default(0), + apiKeysCost: real().notNull().default(0), + creditsServiceFee: real().notNull().default(0), + apiKeysServiceFee: real().notNull().default(0), + creditsDataStorageCost: real().notNull().default(0), + apiKeysDataStorageCost: real().notNull().default(0), + }, + (table) => [ + // Unique constraint for one record per api-key-hour-model-provider + unique().on( + table.apiKeyId, + table.hourTimestamp, + table.usedModel, + table.usedProvider, + ), + // Index for dashboard queries (api key + time range) + index("api_key_hourly_model_stats_api_key_id_hour_timestamp_idx").on( + table.apiKeyId, + table.hourTimestamp, + ), + // Index for project-level queries (all keys in a project) + index("api_key_hourly_model_stats_project_id_hour_timestamp_idx").on( + table.projectId, + table.hourTimestamp, + ), + // Index for worker refresh queries + index("api_key_hourly_model_stats_hour_timestamp_idx").on( + table.hourTimestamp, + ), + ], +); diff --git a/packages/scripts/package.json b/packages/scripts/package.json new file mode 100644 index 0000000000..ea1107374a --- /dev/null +++ b/packages/scripts/package.json @@ -0,0 +1,28 @@ +{ + "name": "@llmgateway/scripts", + "version": "0.0.0", + "private": true, + "license": "SEE LICENSE IN ../../LICENSE", + "type": "module", + "scripts": { + "api-ping": "tsx src/api-ping.ts", + "export-models-dev": "tsx src/export-models-dev.ts", + "generate-test-logs": "tsx src/generate-test-logs.ts", + "model-release-dates": "tsx src/model-release-dates.ts", + "send": "tsx src/send.ts", + "test-gemini-tools-complex": "tsx src/test-gemini-tools-complex.ts", + "test-gemini-tools-simple": "tsx src/test-gemini-tools-simple.ts" + }, + "dependencies": { + "@llmgateway/db": "workspace:*", + "@llmgateway/models": "workspace:*", + "nanoid": "5.1.5", + "openai": "4.104.0", + "resend": "4.5.1", + "sql.js": "1.12.0", + "zod": "3.25.75" + }, + "devDependencies": { + "tsx": "4.20.6" + } +} diff --git a/scripts/api-ping.ts b/packages/scripts/src/api-ping.ts similarity index 98% rename from scripts/api-ping.ts rename to packages/scripts/src/api-ping.ts index 44114748e6..2576fc132c 100644 --- a/scripts/api-ping.ts +++ b/packages/scripts/src/api-ping.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import initSqlJs, { type Database } from "sql.js"; import { readFileSync, writeFileSync, existsSync } from "fs"; diff --git a/scripts/export-models-dev.ts b/packages/scripts/src/export-models-dev.ts similarity index 98% rename from scripts/export-models-dev.ts rename to packages/scripts/src/export-models-dev.ts index 5a46652068..2c82cd3ca9 100644 --- a/scripts/export-models-dev.ts +++ b/packages/scripts/src/export-models-dev.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ /** * Script to export models to models.dev TOML format * @@ -22,14 +23,14 @@ import { mkdirSync, writeFileSync, existsSync, rmSync, copyFileSync } from "fs"; import { join, dirname } from "path"; import { fileURLToPath } from "url"; -import { models, type ModelDefinition } from "../packages/models/src/models.js"; +import { models, type ModelDefinition } from "@llmgateway/models"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const OUTPUT_DIR = "exports/providers/llmgateway"; const MODELS_DIR = join(OUTPUT_DIR, "models"); -const LOGO_SOURCE = join(__dirname, "../apps/ui/public/brand/logo-black.svg"); +const LOGO_SOURCE = join(__dirname, "../../../apps/ui/public/brand/logo-black.svg"); interface ModelsDevModel { name: string; diff --git a/packages/scripts/src/generate-test-logs.ts b/packages/scripts/src/generate-test-logs.ts new file mode 100644 index 0000000000..3ede3844f5 --- /dev/null +++ b/packages/scripts/src/generate-test-logs.ts @@ -0,0 +1,337 @@ +/* eslint-disable no-console */ +/** + * Script to generate random test logs for local development. + * This helps test dashboards and visualizations with realistic data. + * + * Usage: + * pnpm --filter @llmgateway/scripts generate-test-logs 1000 proj_123 key_456 org_789 + * + * Environment: + * DATABASE_URL - PostgreSQL connection string + */ + +import { db, tables } from "@llmgateway/db"; +import { customAlphabet } from "nanoid"; + +const generate = customAlphabet( + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", +); +const shortid = (size = 20) => generate(size); + +// Model configurations with realistic distributions +// discount is applied to smaller/cheaper models (0.3 = 30% discount) +// cachedInputCostPer1k is typically 50% of input cost (or 0 if model doesn't support caching) +const MODELS = [ + { + id: "gpt-4o", + provider: "openai", + weight: 25, + avgInputTokens: 500, + avgOutputTokens: 300, + inputCostPer1k: 0.005, + outputCostPer1k: 0.015, + cachedInputCostPer1k: 0.0025, + cacheChance: 0.35, + discount: 0, + }, + { + id: "gpt-4o-mini", + provider: "openai", + weight: 30, + avgInputTokens: 400, + avgOutputTokens: 250, + inputCostPer1k: 0.00015, + outputCostPer1k: 0.0006, + cachedInputCostPer1k: 0.000075, + cacheChance: 0.4, + discount: 0.3, + }, + { + id: "claude-3-5-sonnet-20241022", + provider: "anthropic", + weight: 20, + avgInputTokens: 600, + avgOutputTokens: 400, + inputCostPer1k: 0.003, + outputCostPer1k: 0.015, + cachedInputCostPer1k: 0.0003, + cacheChance: 0.3, + discount: 0, + }, + { + id: "claude-3-5-haiku-20241022", + provider: "anthropic", + weight: 10, + avgInputTokens: 350, + avgOutputTokens: 200, + inputCostPer1k: 0.0008, + outputCostPer1k: 0.004, + cachedInputCostPer1k: 0.00008, + cacheChance: 0.25, + discount: 0.3, + }, + { + id: "gemini-2.5-pro", + provider: "google-ai-studio", + weight: 8, + avgInputTokens: 550, + avgOutputTokens: 350, + inputCostPer1k: 0.00125, + outputCostPer1k: 0.005, + cachedInputCostPer1k: 0.000315, + cacheChance: 0.3, + discount: 0, + }, + { + id: "gemini-2.5-flash", + provider: "google-ai-studio", + weight: 5, + avgInputTokens: 300, + avgOutputTokens: 200, + inputCostPer1k: 0.000075, + outputCostPer1k: 0.0003, + cachedInputCostPer1k: 0.00001875, + cacheChance: 0.35, + discount: 0.3, + }, + { + id: "deepseek-chat", + provider: "deepseek", + weight: 2, + avgInputTokens: 400, + avgOutputTokens: 300, + inputCostPer1k: 0.00014, + outputCostPer1k: 0.00028, + cachedInputCostPer1k: 0.000014, + cacheChance: 0.2, + discount: 0.3, + }, +]; + +const FINISH_REASONS = [ + { reason: "completed", weight: 85 }, + { reason: "length_limit", weight: 5 }, + { reason: "tool_calls", weight: 5 }, + { reason: "content_filter", weight: 1 }, + { reason: "canceled", weight: 1 }, + { reason: "upstream_error", weight: 2 }, + { reason: "client_error", weight: 1 }, +]; + +function weightedRandom(items: T[]): T { + const totalWeight = items.reduce((sum, item) => sum + item.weight, 0); + let random = Math.random() * totalWeight; + + for (const item of items) { + random -= item.weight; + if (random <= 0) { + return item; + } + } + + return items[items.length - 1]; +} + +function randomInt(min: number, max: number): number { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +function randomFloat(min: number, max: number): number { + return Math.random() * (max - min) + min; +} + +// Log-normal distribution for more realistic heavy-tailed randomness +// Most values cluster near the median, but occasional large outliers occur +function logNormalRandom(median: number, sigma: number): number { + const u1 = Math.random(); + const u2 = Math.random(); + const z = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2); + return median * Math.exp(sigma * z); +} + +function randomDate(daysBack: number): Date { + const now = new Date(); + const msBack = randomInt(0, daysBack * 24 * 60 * 60 * 1000); + return new Date(now.getTime() - msBack); +} + +function generateLog( + projectId: string, + apiKeyId: string, + organizationId: string, + daysBack: number, +) { + const model = weightedRandom(MODELS); + const finishReason = weightedRandom(FINISH_REASONS); + + // Use log-normal distribution for wide, realistic variance + // sigma=0.8 gives roughly 2x-5x spread in either direction from the median + const inputTokens = Math.max( + 1, + Math.round(logNormalRandom(model.avgInputTokens, 0.8)), + ); + const outputTokens = Math.max( + 1, + Math.round(logNormalRandom(model.avgOutputTokens, 0.9)), + ); + + // Determine if this request has cached input tokens + const hasCachedTokens = Math.random() < model.cacheChance; + // Cached tokens are a portion (20-80%) of the input tokens + const cachedTokens = hasCachedTokens + ? Math.round(inputTokens * randomFloat(0.2, 0.8)) + : 0; + + const totalTokens = inputTokens + outputTokens; + + // Calculate costs (before discount) + // For cached tokens, use the cheaper cached input price + const uncachedInputTokens = inputTokens - cachedTokens; + const inputCostBeforeDiscount = + (uncachedInputTokens / 1000) * model.inputCostPer1k; + const cachedInputCostBeforeDiscount = + (cachedTokens / 1000) * model.cachedInputCostPer1k; + const outputCostBeforeDiscount = + (outputTokens / 1000) * model.outputCostPer1k; + const costBeforeDiscount = + inputCostBeforeDiscount + + cachedInputCostBeforeDiscount + + outputCostBeforeDiscount; + + // Apply discount if model has one + const discount = model.discount; + const discountMultiplier = 1 - discount; + const inputCost = inputCostBeforeDiscount * discountMultiplier; + const cachedInputCost = cachedInputCostBeforeDiscount * discountMultiplier; + const outputCost = outputCostBeforeDiscount * discountMultiplier; + const cost = costBeforeDiscount * discountMultiplier; + + // Log-normal duration for wide spread (most fast, some very slow) + const duration = Math.max( + 50, + Math.round(logNormalRandom(800, 1.0)), + ); + + // Error states based on finish reason + const hasError = ["upstream_error", "client_error", "gateway_error"].includes( + finishReason.reason, + ); + + // Random flags + const streamed = Math.random() > 0.3; // 70% are streamed + const cached = Math.random() > 0.9; // 10% are cached + + // Time to first token (only for streamed, log-normal for variability) + const timeToFirstToken = streamed + ? Math.max(20, Math.round(logNormalRandom(150, 0.7))) + : null; + + // Generate date within the specified range + const createdAt = randomDate(daysBack); + + const id = shortid(); + + return { + id, + requestId: id, + createdAt, + updatedAt: createdAt, + organizationId, + projectId, + apiKeyId, + duration, + timeToFirstToken, + requestedModel: model.id, + requestedProvider: model.provider, + usedModel: model.id, + usedProvider: model.provider, + responseSize: outputTokens * randomInt(3, 6), // Variable bytes-per-token estimate + promptTokens: String(inputTokens), + completionTokens: String(outputTokens), + totalTokens: String(totalTokens), + cachedTokens: cachedTokens > 0 ? String(cachedTokens) : null, + cost, + inputCost, + outputCost, + cachedInputCost: cachedTokens > 0 ? cachedInputCost : null, + requestCost: 0, + discount, + hasError, + finishReason: finishReason.reason, + unifiedFinishReason: finishReason.reason, + streamed, + cached, + mode: "credits" as const, + usedMode: "credits" as const, + messages: JSON.stringify([ + { role: "user", content: "Test message for visualization" }, + ]), + temperature: randomFloat(0, 1.5), + maxTokens: Math.round(logNormalRandom(2000, 0.6)), + }; +} + +async function main() { + const args = process.argv.slice(2); + + if (args.length < 4) { + console.log( + "Usage: pnpm --filter @llmgateway/scripts generate-test-logs [daysBack]", + ); + console.log("\nExample:"); + console.log( + " pnpm --filter @llmgateway/scripts generate-test-logs 1000 proj_123 key_456 org_789 30", + ); + console.log("\nArguments:"); + console.log(" count - Number of logs to generate"); + console.log(" projectId - Project ID to associate logs with"); + console.log(" apiKeyId - API Key ID to associate logs with"); + console.log(" organizationId - Organization ID to associate logs with"); + console.log( + " daysBack - How many days back to spread logs (default: 30)", + ); + process.exit(1); + } + + const count = parseInt(args[0], 10); + const projectId = args[1]; + const apiKeyId = args[2]; + const organizationId = args[3]; + const daysBack = parseInt(args[4] || "30", 10); + + if (isNaN(count) || count <= 0) { + console.error("Error: count must be a positive integer"); + process.exit(1); + } + + console.log(`Generating ${count} test logs...`); + console.log(` Project ID: ${projectId}`); + console.log(` API Key ID: ${apiKeyId}`); + console.log(` Organization ID: ${organizationId}`); + console.log(` Days back: ${daysBack}`); + + // Generate logs in batches of 1000 + const batchSize = 1000; + let generated = 0; + + while (generated < count) { + const batchCount = Math.min(batchSize, count - generated); + const logs = Array.from({ length: batchCount }, () => + generateLog(projectId, apiKeyId, organizationId, daysBack), + ); + + await db.insert(tables.log).values(logs); + generated += batchCount; + + const progress = Math.round((generated / count) * 100); + console.log(` Progress: ${generated}/${count} (${progress}%)`); + } + + console.log("\nDone!"); + process.exit(0); +} + +main().catch((err) => { + console.error("Error:", err); + process.exit(1); +}); diff --git a/scripts/model-release-dates.ts b/packages/scripts/src/model-release-dates.ts similarity index 98% rename from scripts/model-release-dates.ts rename to packages/scripts/src/model-release-dates.ts index 47c315714e..be4f46feef 100644 --- a/scripts/model-release-dates.ts +++ b/packages/scripts/src/model-release-dates.ts @@ -1,4 +1,5 @@ -import { models } from "../packages/models/src/models.js"; +/* eslint-disable no-console */ +import { models } from "@llmgateway/models"; import { writeFileSync, appendFileSync, existsSync, unlinkSync } from "fs"; const GATEWAY_URL = "http://localhost:4001/v1/chat/completions"; diff --git a/scripts/send.ts b/packages/scripts/src/send.ts similarity index 98% rename from scripts/send.ts rename to packages/scripts/src/send.ts index 2f182981d3..0b5ce88136 100644 --- a/scripts/send.ts +++ b/packages/scripts/src/send.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ // JSON Schema: // [ // { diff --git a/scripts/test-gemini-tools-complex.ts b/packages/scripts/src/test-gemini-tools-complex.ts similarity index 100% rename from scripts/test-gemini-tools-complex.ts rename to packages/scripts/src/test-gemini-tools-complex.ts diff --git a/scripts/test-gemini-tools-simple.ts b/packages/scripts/src/test-gemini-tools-simple.ts similarity index 100% rename from scripts/test-gemini-tools-simple.ts rename to packages/scripts/src/test-gemini-tools-simple.ts diff --git a/packages/scripts/tsconfig.json b/packages/scripts/tsconfig.json new file mode 100644 index 0000000000..fb9c402137 --- /dev/null +++ b/packages/scripts/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c072bba17a..da607b8382 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -299,7 +299,7 @@ importers: version: 0.7.2(hono@4.11.7)(zod@3.25.75) '@kubiks/otel-better-auth': specifier: 2.0.2 - version: 2.0.2(@opentelemetry/api@1.9.0)(better-auth@1.3.30) + version: 2.0.2(@opentelemetry/api@1.9.0)(better-auth@1.3.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@llmgateway/actions': specifier: workspace:* version: link:../../packages/actions @@ -368,7 +368,7 @@ importers: version: 5.10.4 resend: specifier: 6.8.0 - version: 6.8.0 + version: 6.8.0(@react-email/render@1.0.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) stripe: specifier: 18.1.1 version: 18.1.1(@types/node@25.2.0) @@ -1103,7 +1103,7 @@ importers: version: 3.3.0(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(redux@5.0.1) resend: specifier: 6.8.0 - version: 6.8.0 + version: 6.8.0(@react-email/render@1.0.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) sonner: specifier: ^2.0.7 version: 2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -1299,6 +1299,34 @@ importers: packages/models: {} + packages/scripts: + dependencies: + '@llmgateway/db': + specifier: workspace:* + version: link:../db + '@llmgateway/models': + specifier: workspace:* + version: link:../models + nanoid: + specifier: 5.1.5 + version: 5.1.5 + openai: + specifier: 4.104.0 + version: 4.104.0(zod@3.25.75) + resend: + specifier: 4.5.1 + version: 4.5.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + sql.js: + specifier: 1.12.0 + version: 1.12.0 + zod: + specifier: 3.25.75 + version: 3.25.75 + devDependencies: + tsx: + specifier: 4.20.6 + version: 4.20.6 + packages/shared: dependencies: '@llmgateway/models': @@ -3601,6 +3629,13 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + '@react-email/render@1.0.6': + resolution: {integrity: sha512-zNueW5Wn/4jNC1c5LFgXzbUdv5Lhms+FWjOvWAhal7gx5YVf0q6dPJ0dnR70+ifo59gcMLwCZEaTS9EEuUhKvQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^18.0 || ^19.0 || ^19.0.0-rc + '@redis/bloom@5.9.0': resolution: {integrity: sha512-W9D8yfKTWl4tP8lkC3MRYkMz4OfbuzE/W8iObe0jFgoRmgMfkBV+Vj38gvIqZPImtY0WB34YZkX3amYuQebvRQ==} engines: {node: '>= 18'} @@ -3786,6 +3821,9 @@ packages: '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@selderee/plugin-htmlparser2@0.11.0': + resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==} + '@semantic-release/commit-analyzer@13.0.1': resolution: {integrity: sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ==} engines: {node: '>=20.8.1'} @@ -4295,6 +4333,12 @@ packages: '@types/mysql@2.15.27': resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} + '@types/node-fetch@2.6.13': + resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} + + '@types/node@18.19.130': + resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} + '@types/node@20.19.14': resolution: {integrity: sha512-gqiKWld3YIkmtrrg9zDvg9jfksZCcPywXVN7IauUGhilwGV/yOyeUsvpR796m/Jye0zUzMXPKe8Ct1B79A7N5Q==} @@ -4582,6 +4626,10 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} @@ -4728,6 +4776,9 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} @@ -5036,6 +5087,10 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} @@ -5428,6 +5483,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + default-browser-id@5.0.1: resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} engines: {node: '>=18'} @@ -5458,6 +5517,10 @@ packages: delaunator@5.0.1: resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + denque@2.1.0: resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} engines: {node: '>=0.10'} @@ -5499,9 +5562,22 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + dompurify@3.3.1: resolution: {integrity: sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==} + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} @@ -5764,6 +5840,10 @@ packages: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + entities@6.0.1: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} @@ -6147,6 +6227,9 @@ packages: fast-copy@3.0.2: resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==} + fast-deep-equal@2.0.1: + resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -6278,10 +6361,21 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + form-data-encoder@1.7.2: + resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + format@0.2.2: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} + formdata-node@4.4.1: + resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} + engines: {node: '>= 12.20'} + forwarded-parse@2.1.2: resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} @@ -6726,6 +6820,10 @@ packages: html-to-image@1.11.13: resolution: {integrity: sha512-cuOPoI7WApyhBElTTb9oqsawRvZ0rHhaHwghRLlTuffoD1B2aDemlCruLeZrUIIdvG7gs9xeELEPm6PhuASqrg==} + html-to-text@9.0.5: + resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==} + engines: {node: '>=14'} + html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} @@ -6736,6 +6834,9 @@ packages: resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==} engines: {node: '>=8.0.0'} + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + http-errors@2.0.1: resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} @@ -6760,6 +6861,9 @@ packages: resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} engines: {node: '>=18.18.0'} + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + husky@9.1.7: resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} engines: {node: '>=18'} @@ -7231,6 +7335,9 @@ packages: layout-base@2.0.1: resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + leac@0.6.0: + resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==} + leven@4.0.0: resolution: {integrity: sha512-puehA3YKku3osqPlNuzGDUHq8WpwXupUg1V6NXdV38G+gr+gkBwFC8g1b/+YcIvp8gnqVIus+eJCH/eGsRmJNw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -7719,10 +7826,18 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mime-types@3.0.2: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} @@ -7891,6 +8006,11 @@ packages: node-cleanup@2.1.2: resolution: {integrity: sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==} + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + node-emoji@2.2.0: resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} engines: {node: '>=18'} @@ -8086,6 +8206,18 @@ packages: resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} engines: {node: '>=18'} + openai@4.104.0: + resolution: {integrity: sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.23.8 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + openai@5.19.1: resolution: {integrity: sha512-zSqnUF7oR9ksmpusKkpUgkNrj8Sl57U+OyzO8jzc7LUjTMg4DRfR3uCm+EIMA6iw06sRPNp4t7ojp3sCpEUZRQ==} hasBin: true @@ -8257,6 +8389,9 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + parseley@0.12.1: + resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -8308,6 +8443,9 @@ packages: pause-stream@0.0.11: resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + peberminta@0.9.0: + resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==} + performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} @@ -8473,6 +8611,11 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + engines: {node: '>=14'} + hasBin: true + prettier@3.6.2: resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} engines: {node: '>=14'} @@ -8614,6 +8757,9 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-promise-suspense@0.3.4: + resolution: {integrity: sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==} + react-redux@9.2.0: resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==} peerDependencies: @@ -8853,6 +8999,10 @@ packages: reselect@5.1.1: resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} + resend@4.5.1: + resolution: {integrity: sha512-ryhHpZqCBmuVyzM19IO8Egtc2hkWI4JOL5lf5F3P7Dydu3rFeX6lHNpGqG0tjWoZ63rw0l731JEmuJZBdDm3og==} + engines: {node: '>=18'} + resend@6.8.0: resolution: {integrity: sha512-fDOXGqafQfQXl8nXe93wr93pus8tW7YPpowenE3SmG7dJJf0hH3xUWm3xqacnPvhqjCQTJH9xETg07rmUeSuqQ==} engines: {node: '>=20'} @@ -8985,6 +9135,9 @@ packages: secure-json-parse@4.0.0: resolution: {integrity: sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==} + selderee@0.11.0: + resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} + semantic-release-monorepo@8.0.2: resolution: {integrity: sha512-TQC6KKIA0ATjii1OT0ZmQqcVzBJoaetJaJBC8FmKkg1IbDR4wBsuX6gl6UHDdijRDl8YyXqahj2hkJNyV6m9Jg==} peerDependencies: @@ -9192,6 +9345,9 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + sql.js@1.12.0: + resolution: {integrity: sha512-Bi+43yMx/tUFZVYD4AUscmdL6NHn3gYQ+CM+YheFWLftOmrEC/Mz6Yh7E96Y2WDHYz3COSqT+LP6Z79zgrwJlA==} + sql.js@1.13.0: resolution: {integrity: sha512-RJbVP1HRDlUUXahJ7VMTcu9Rm1Nzw+EBpoPr94vnbD4LwR715F3CcxE2G2k45PewcaZ57pjetYa+LoSJLAASgA==} @@ -9708,6 +9864,9 @@ packages: undefsafe@2.0.5: resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -9970,6 +10129,10 @@ packages: web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + web-streams-polyfill@4.0.0-beta.3: + resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} + engines: {node: '>= 14'} + web-vitals@4.2.4: resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} @@ -11087,7 +11250,7 @@ snapshots: dependencies: jsbi: 4.3.2 - '@kubiks/otel-better-auth@2.0.2(@opentelemetry/api@1.9.0)(better-auth@1.3.30)': + '@kubiks/otel-better-auth@2.0.2(@opentelemetry/api@1.9.0)(better-auth@1.3.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: '@opentelemetry/api': 1.9.0 better-auth: 1.3.30(next@16.1.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -12775,6 +12938,14 @@ snapshots: '@radix-ui/rect@1.1.1': {} + '@react-email/render@1.0.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + html-to-text: 9.0.5 + prettier: 3.5.3 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-promise-suspense: 0.3.4 + '@redis/bloom@5.9.0(@redis/client@5.9.0)': dependencies: '@redis/client': 5.9.0 @@ -12927,6 +13098,11 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} + '@selderee/plugin-htmlparser2@0.11.0': + dependencies: + domhandler: 5.0.3 + selderee: 0.11.0 + '@semantic-release/commit-analyzer@13.0.1(semantic-release@24.2.9(typescript@5.9.2))': dependencies: conventional-changelog-angular: 8.1.0 @@ -13520,6 +13696,15 @@ snapshots: dependencies: '@types/node': 24.10.1 + '@types/node-fetch@2.6.13': + dependencies: + '@types/node': 24.10.1 + form-data: 4.0.5 + + '@types/node@18.19.130': + dependencies: + undici-types: 5.26.5 + '@types/node@20.19.14': dependencies: undici-types: 6.21.0 @@ -13899,6 +14084,10 @@ snapshots: agent-base@7.1.4: {} + agentkeepalive@4.6.0: + dependencies: + humanize-ms: 1.2.1 + aggregate-error@3.1.0: dependencies: clean-stack: 2.2.0 @@ -14065,6 +14254,8 @@ snapshots: async-function@1.0.0: {} + asynckit@0.4.0: {} + atomic-sleep@1.0.0: {} autoprefixer@10.4.21(postcss@8.5.6): @@ -14425,6 +14616,10 @@ snapshots: colorette@2.0.20: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + comma-separated-tokens@2.0.3: {} commander@11.1.0: {} @@ -14823,6 +15018,8 @@ snapshots: deep-is@0.1.4: {} + deepmerge@4.3.1: {} + default-browser-id@5.0.1: {} default-browser@5.5.0: @@ -14861,6 +15058,8 @@ snapshots: dependencies: robust-predicates: 3.0.2 + delayed-stream@1.0.0: {} + denque@2.1.0: {} depd@2.0.0: {} @@ -14889,10 +15088,28 @@ snapshots: dependencies: esutils: 2.0.3 + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + dompurify@3.3.1: optionalDependencies: '@types/trusted-types': 2.0.7 + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dot-prop@5.3.0: dependencies: is-obj: 2.0.0 @@ -14990,6 +15207,8 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.3.0 + entities@4.5.0: {} + entities@6.0.1: {} env-ci@11.2.0: @@ -15675,6 +15894,8 @@ snapshots: fast-copy@3.0.2: {} + fast-deep-equal@2.0.1: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.1: @@ -15815,8 +16036,23 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + form-data-encoder@1.7.2: {} + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + format@0.2.2: {} + formdata-node@4.4.1: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 4.0.0-beta.3 + forwarded-parse@2.1.2: {} forwarded@0.2.0: {} @@ -16427,6 +16663,14 @@ snapshots: html-to-image@1.11.13: {} + html-to-text@9.0.5: + dependencies: + '@selderee/plugin-htmlparser2': 0.11.0 + deepmerge: 4.3.1 + dom-serializer: 2.0.0 + htmlparser2: 8.0.2 + selderee: 0.11.0 + html-url-attributes@3.0.1: {} html-void-elements@3.0.0: {} @@ -16437,6 +16681,13 @@ snapshots: text-segmentation: 1.0.3 optional: true + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 4.5.0 + http-errors@2.0.1: dependencies: depd: 2.0.0 @@ -16472,6 +16723,10 @@ snapshots: human-signals@8.0.1: {} + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + husky@9.1.7: {} iconv-lite@0.6.3: @@ -16914,6 +17169,8 @@ snapshots: layout-base@2.0.1: {} + leac@0.6.0: {} + leven@4.0.0: {} levn@0.4.1: @@ -17666,8 +17923,14 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mime-types@3.0.2: dependencies: mime-db: 1.54.0 @@ -17811,6 +18074,8 @@ snapshots: node-cleanup@2.1.2: {} + node-domexception@1.0.0: {} + node-emoji@2.2.0: dependencies: '@sindresorhus/is': 4.6.0 @@ -17952,6 +18217,20 @@ snapshots: is-inside-container: 1.0.0 wsl-utils: 0.1.0 + openai@4.104.0(zod@3.25.75): + dependencies: + '@types/node': 18.19.130 + '@types/node-fetch': 2.6.13 + abort-controller: 3.0.0 + agentkeepalive: 4.6.0 + form-data-encoder: 1.7.2 + formdata-node: 4.4.1 + node-fetch: 2.7.0 + optionalDependencies: + zod: 3.25.75 + transitivePeerDependencies: + - encoding + openai@5.19.1(zod@3.25.75): optionalDependencies: zod: 3.25.75 @@ -18121,6 +18400,11 @@ snapshots: dependencies: entities: 6.0.1 + parseley@0.12.1: + dependencies: + leac: 0.6.0 + peberminta: 0.9.0 + parseurl@1.3.3: {} path-data-parser@0.1.0: {} @@ -18154,6 +18438,8 @@ snapshots: dependencies: through: 2.3.8 + peberminta@0.9.0: {} + performance-now@2.1.0: optional: true @@ -18339,6 +18625,8 @@ snapshots: prelude-ls@1.2.1: {} + prettier@3.5.3: {} + prettier@3.6.2: {} pretty-bytes@7.1.0: {} @@ -18476,6 +18764,10 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) + react-promise-suspense@0.3.4: + dependencies: + fast-deep-equal: 2.0.1 + react-redux@9.2.0(@types/react@19.2.10)(react@19.2.4)(redux@5.0.1): dependencies: '@types/use-sync-external-store': 0.0.6 @@ -18829,9 +19121,18 @@ snapshots: reselect@5.1.1: {} - resend@6.8.0: + resend@4.5.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + '@react-email/render': 1.0.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + transitivePeerDependencies: + - react + - react-dom + + resend@6.8.0(@react-email/render@1.0.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)): dependencies: svix: 1.84.1 + optionalDependencies: + '@react-email/render': 1.0.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) resolve-from@4.0.0: {} @@ -18982,6 +19283,10 @@ snapshots: secure-json-parse@4.0.0: {} + selderee@0.11.0: + dependencies: + parseley: 0.12.1 + semantic-release-monorepo@8.0.2(semantic-release@24.2.9(typescript@5.9.2)): dependencies: debug: 4.4.3(supports-color@5.5.0) @@ -19293,6 +19598,8 @@ snapshots: sprintf-js@1.1.3: {} + sql.js@1.12.0: {} + sql.js@1.13.0: {} stable-hash-x@0.2.0: {} @@ -19848,6 +20155,8 @@ snapshots: undefsafe@2.0.5: {} + undici-types@5.26.5: {} + undici-types@6.21.0: {} undici-types@7.10.0: {} @@ -20140,6 +20449,8 @@ snapshots: web-namespaces@2.0.1: {} + web-streams-polyfill@4.0.0-beta.3: {} + web-vitals@4.2.4: {} web-worker@1.2.0: {}