RPS Digital P3 Intake Archive Api.Prompts source
Imported TypeScript file from ../../app/app/routes/api.prompts.ts.
Source file
../../app/app/routes/api.prompts.ts
TypeScript87 lines
import { json, type ActionFunctionArgs } from '@remix-run/node';import { randomUUID } from 'node:crypto';import path from 'node:path';import { getPromptProvider } from '../ai/provider.server';import { createJob, createPrompt, createProduct, createRelease, updateProductCurrentRelease } from '../db.server';import { buildObjectKeyPrefix } from '../../../shared/pipeline';import { requireInstalledShop } from '../authz.server';export async function action({ request }: ActionFunctionArgs) {if (request.method !== 'POST') {return json({ error: 'Method not allowed' }, { status: 405 });}const contentType = request.headers.get('content-type') || '';let body: Record<string, unknown> = {};try {body = contentType.includes('application/json')? ((await request.json()) as Record<string, unknown>): (Object.fromEntries(await request.formData()) as Record<string, unknown>);} catch {return json({ error: 'Invalid request body' }, { status: 400 });}const access = requireInstalledShop(request, body);if (access instanceof Response) return access;const prompt = String(body.prompt || '');const shopId = access.shopId;const sku = String(body.sku || `sku-${Date.now()}`);const release = String(body.release || 'v1');const prefixBase = String(body.prefixBase || (process.env.GCS_PREFIX || 'products'));if (!prompt.trim()) {return json({ error: 'Prompt is required' }, { status: 400 });}const provider = getPromptProvider();const outputDir = path.resolve(process.cwd(), 'tmp', `prompt-${randomUUID()}`);const generated = await provider.generateFromPrompt(prompt, outputDir);const promptId = createPrompt({shopId,rawPrompt: prompt,provider: generated.provider,model: generated.model,outputSummary: JSON.stringify(generated.metadata),});const productId = createProduct({ shopId, promptId });const releaseId = createRelease({ productId, version: release, status: 'draft' });updateProductCurrentRelease({ productId, releaseId });const objectKeyPrefix = buildObjectKeyPrefix(prefixBase, sku, release);let options = body.options || {};if (typeof options === 'string') {try {options = JSON.parse(options);} catch {options = {};}}const jobId = createJob({shopId,type: 'prompt',inputPayload: JSON.stringify({pipeline: {artPath: generated.imagePath,roomBgPath: body.roomBgPath || null,sku,release,outputDir,objectKeyPrefix,options,},metadata: generated.metadata,releaseId,productId,}),});return json({jobId,productId,releaseId,metadata: generated.metadata,});}