Files
Momento/memento-note/app/api/ai/echo/fusion/route.ts
Antigravity 324bf40658
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 7m20s
CI / Deploy production (on server) (push) Successful in 24s
fix: replace raw ai_consent_required code with translatable message and consent prompt
- Centralize AI consent 403 responses in server-consent helpers
- Return human-readable message + code + i18n errorKey from all AI APIs
- Update dashboard and AI clients to detect code/errorKey and translate
- Add consent.ai.requiredToast i18n keys (fr/en)
2026-07-18 17:32:00 +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, aiConsentForbiddenResponse } 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 aiConsentForbiddenResponse()
}
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 }
)
}
}