Briefing granulaire, pistes rapides puis enrichissement async, layout persisté v5, suggestions agents, intégration Gmail et navigation sidebar alignée sur /home. Co-authored-by: Cursor <cursoragent@cursor.com>
42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import prisma from '@/lib/prisma'
|
|
import { agentSuggestionService } from '@/lib/ai/services/agent-suggestion.service'
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
function authorizeCron(request: NextRequest): boolean {
|
|
const cronSecret = process.env.CRON_SECRET
|
|
if (!cronSecret) return false
|
|
const authHeader = request.headers.get('authorization')
|
|
const bearer = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null
|
|
const querySecret = new URL(request.url).searchParams.get('secret')
|
|
return bearer === cronSecret || querySecret === cronSecret
|
|
}
|
|
|
|
/**
|
|
* POST /api/cron/agent-suggestions
|
|
* Génère des suggestions d'agents à partir des clusters sémantiques existants.
|
|
*/
|
|
export async function POST(request: NextRequest) {
|
|
if (!authorizeCron(request)) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
}
|
|
|
|
const users = await prisma.user.findMany({
|
|
where: { noteClusters: { some: {} } },
|
|
select: { id: true },
|
|
take: 30,
|
|
})
|
|
|
|
let total = 0
|
|
for (const user of users) {
|
|
try {
|
|
total += await agentSuggestionService.generateForUser(user.id)
|
|
} catch (err) {
|
|
console.error('[CronAgentSuggestions] user', user.id, err)
|
|
}
|
|
}
|
|
|
|
return NextResponse.json({ success: true, users: users.length, suggestionsUpserted: total })
|
|
}
|