Files
Momento/memento-note/app/api/ai/echo/fusion/route.ts
Antigravity 4fe31ebc99
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 6m55s
CI / Deploy production (on server) (push) Successful in 36s
fix(quotas): unifier le décompte IA (BYOK, rollback) et combler les fuites
Centralise la réserve via ai-quota, corrige admin unavailable (-1), brancher les routes sans quota et le host-pays brainstorm, avec usage-meter élargi, noms de clusters, MCP et ajustements dashboard/insights.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 20:42:25 +00:00

112 lines
3.0 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { auth } from '@/auth'
import { getChatProvider } from '@/lib/ai/factory'
import { getSystemConfig } from '@/lib/config'
import prisma from '@/lib/prisma'
import { hasUserAiConsent } from '@/lib/consent/server-consent'
import { withAiQuota, handleQuotaHttpError } from '@/lib/ai-quota'
/**
* POST /api/ai/echo/fusion
* Generate intelligent fusion of multiple notes
*/
export async function POST(req: NextRequest) {
try {
const session = await auth()
if (!session?.user?.id) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
)
}
if (!(await hasUserAiConsent())) {
return NextResponse.json({ error: 'ai_consent_required' }, { status: 403 })
}
const body = await req.json()
const { noteIds, prompt } = body
if (!noteIds || !Array.isArray(noteIds) || noteIds.length < 2) {
return NextResponse.json(
{ error: 'At least 2 note IDs are required' },
{ status: 400 }
)
}
const notes = await prisma.note.findMany({
where: {
id: { in: noteIds },
userId: session.user.id
},
select: {
id: true,
title: true,
content: true,
createdAt: true
}
})
if (notes.length !== noteIds.length) {
return NextResponse.json(
{ error: 'Some notes not found or access denied' },
{ status: 404 }
)
}
const config = await getSystemConfig()
const provider = getChatProvider(config)
const notesDescriptions = notes.map((note, index) => {
return `Note ${index + 1}: "${note.title || 'Untitled'}"
${note.content}`
}).join('\n\n')
const fusionPrompt = `You are an expert at synthesizing and merging information from multiple sources.
TASK: Create a unified, well-structured note by intelligently combining the following notes.
${prompt ? `ADDITIONAL INSTRUCTIONS: ${prompt}\n` : ''}
NOTES TO MERGE:
${notesDescriptions}
REQUIREMENTS:
1. Create a clear, descriptive title that captures the essence of all notes
2. Merge and consolidate related information
3. Remove duplicates while preserving unique details from each note
4. Organize the content logically (use headers, bullet points, etc.)
5. Maintain the important details and context from all notes
6. Keep the tone and style consistent
7. Use markdown formatting for better readability
Output format:
# [Fused Title]
[Merged and organized content...]
Begin:`
const fusedContent = await withAiQuota(
session.user.id,
'reformulate',
() => provider.generateText(fusionPrompt),
{ lane: 'chat' },
)
return NextResponse.json({
fusedNote: fusedContent,
notesCount: notes.length
})
} catch (error) {
const quotaResp = handleQuotaHttpError(error)
if (quotaResp) return quotaResp
console.error('[/api/ai/echo/fusion] Error:', error)
return NextResponse.json(
{ error: 'Failed to process fusion request' },
{ status: 500 }
)
}
}