feat: add audit database and safer image review
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { recordEvent } from '@/lib/auditDb';
|
||||
import { startGenerationLock } from '@/lib/generationLocks';
|
||||
import { regeneratePackAsset } from '@/lib/packGenerator';
|
||||
import { detectProvider } from '@/lib/providers';
|
||||
import { loadSession, saveSession } from '@/lib/storage';
|
||||
import type { RegenerateAssetRequest, RegenerateAssetResponse } from '@/lib/types';
|
||||
|
||||
@@ -8,24 +11,69 @@ export const dynamic = 'force-dynamic';
|
||||
|
||||
export async function POST(req: Request, ctx: { params: Promise<{ assetId: string }> }) {
|
||||
const { assetId } = await ctx.params;
|
||||
const { sessionId, userRefinement } = (await req.json()) as RegenerateAssetRequest;
|
||||
const { sessionId, userRefinement, confirmCost } = (await req.json()) as RegenerateAssetRequest;
|
||||
|
||||
if (!assetId || !sessionId) {
|
||||
return NextResponse.json({ error: 'assetId and sessionId required' }, { status: 400 });
|
||||
}
|
||||
if (confirmCost !== true) {
|
||||
recordEvent({
|
||||
action: 'asset.regenerate_blocked_unconfirmed',
|
||||
sessionId,
|
||||
targetType: 'asset',
|
||||
targetId: assetId,
|
||||
status: 'blocked',
|
||||
provider: detectProvider(),
|
||||
});
|
||||
return NextResponse.json({ error: 'confirmCost required for paid regenerate' }, { status: 400 });
|
||||
}
|
||||
|
||||
const session = await loadSession(sessionId);
|
||||
if (!session) return NextResponse.json({ error: 'session not found' }, { status: 404 });
|
||||
|
||||
const releaseLock = startGenerationLock(`regenerate:${sessionId}:${assetId}`);
|
||||
if (!releaseLock) {
|
||||
recordEvent({
|
||||
action: 'asset.regenerate_blocked_running',
|
||||
sessionId,
|
||||
targetType: 'asset',
|
||||
targetId: assetId,
|
||||
status: 'blocked',
|
||||
provider: detectProvider(),
|
||||
});
|
||||
return NextResponse.json({ error: 'asset regenerate already running' }, { status: 429 });
|
||||
}
|
||||
|
||||
try {
|
||||
recordEvent({
|
||||
action: 'asset.regenerate_started',
|
||||
sessionId,
|
||||
targetType: 'asset',
|
||||
targetId: assetId,
|
||||
status: 'started',
|
||||
provider: detectProvider(),
|
||||
metadata: { refinement: Boolean(userRefinement?.trim()) },
|
||||
});
|
||||
const regenerated = await regeneratePackAsset({ session, assetId, userRefinement });
|
||||
await saveSession(session);
|
||||
recordEvent({
|
||||
action: 'asset.regenerate_completed',
|
||||
sessionId,
|
||||
targetType: 'asset',
|
||||
targetId: assetId,
|
||||
status: 'ok',
|
||||
provider: regenerated.provider,
|
||||
metadata: { packId: regenerated.pack.id, templateId: regenerated.asset.templateId, url: regenerated.asset.url },
|
||||
});
|
||||
return NextResponse.json({
|
||||
asset: regenerated.asset,
|
||||
pack: regenerated.pack,
|
||||
provider: regenerated.provider,
|
||||
} satisfies RegenerateAssetResponse);
|
||||
} catch (error) {
|
||||
recordEvent({ action: 'asset.regenerate_failed', sessionId, targetType: 'asset', targetId: assetId, status: 'error', provider: detectProvider(), message: String(error) });
|
||||
return NextResponse.json({ error: String(error) }, { status: 500 });
|
||||
} finally {
|
||||
releaseLock();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user