mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
109 lines
2.8 KiB
TypeScript
109 lines
2.8 KiB
TypeScript
// Functions for accessing the apps table in the database
|
|
|
|
import { getSupabase } from '~/lib/supabase/client';
|
|
import type { Message } from './message';
|
|
|
|
export interface BuildAppOutcome {
|
|
testsPassed?: boolean;
|
|
hasDatabase?: boolean;
|
|
}
|
|
|
|
export interface BuildAppResult {
|
|
id: string;
|
|
title: string | undefined;
|
|
elapsedMinutes: number;
|
|
totalPeanuts: number;
|
|
imageDataURL: string | undefined;
|
|
messages: Message[];
|
|
protocolChatId: string;
|
|
outcome: BuildAppOutcome;
|
|
appId: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
function parseBuildAppOutcome(outcome: string): BuildAppOutcome {
|
|
try {
|
|
const json = JSON.parse(outcome);
|
|
return {
|
|
testsPassed: !!json.testsPassed,
|
|
hasDatabase: !!json.hasDatabase,
|
|
};
|
|
} catch (error) {
|
|
// 2025/04/26: Watch for old formats for outcomes.
|
|
if (outcome === 'success') {
|
|
return {
|
|
testsPassed: true,
|
|
};
|
|
}
|
|
if (outcome === 'error') {
|
|
return {
|
|
testsPassed: false,
|
|
};
|
|
}
|
|
console.error('Failed to parse outcome:', error);
|
|
return {};
|
|
}
|
|
}
|
|
|
|
function databaseRowToBuildAppResult(row: any): BuildAppResult {
|
|
// Determine the outcome based on the result field
|
|
const outcome = parseBuildAppOutcome(row.outcome);
|
|
|
|
return {
|
|
id: row.id,
|
|
title: row.title,
|
|
elapsedMinutes: row.elapsed_minutes || 0,
|
|
totalPeanuts: row.total_peanuts || 0,
|
|
imageDataURL: row.image_url,
|
|
messages: row.messages || [],
|
|
protocolChatId: row.protocol_chat_id,
|
|
outcome,
|
|
appId: row.app_id,
|
|
createdAt: row.created_at,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get all apps created within the last X hours
|
|
* @param hours Number of hours to look back
|
|
* @returns Array of BuildAppResult objects
|
|
*/
|
|
async function getAppsCreatedInLastXHours(hours: number): Promise<BuildAppResult[]> {
|
|
try {
|
|
// Calculate the timestamp for X hours ago
|
|
const hoursAgo = new Date();
|
|
hoursAgo.setHours(hoursAgo.getHours() - hours);
|
|
|
|
const { data, error } = await getSupabase()
|
|
.from('apps')
|
|
.select('*')
|
|
.eq('deleted', false)
|
|
.gte('created_at', hoursAgo.toISOString())
|
|
.order('created_at', { ascending: false });
|
|
|
|
if (error) {
|
|
console.error('Error fetching recent apps:', error);
|
|
throw error;
|
|
}
|
|
|
|
// Ignore apps that don't have a title or image.
|
|
return data.map(databaseRowToBuildAppResult).filter((app) => app.title && app.imageDataURL);
|
|
} catch (error) {
|
|
console.error('Failed to get recent apps:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
const HOUR_RANGES = [1, 2, 3, 6, 12, 24];
|
|
|
|
export async function getRecentApps(numApps: number): Promise<BuildAppResult[]> {
|
|
let apps: BuildAppResult[] = [];
|
|
for (const range of HOUR_RANGES) {
|
|
apps = await getAppsCreatedInLastXHours(range);
|
|
if (apps.length >= numApps) {
|
|
return apps.slice(0, numApps);
|
|
}
|
|
}
|
|
return apps;
|
|
}
|