feat: Graphify build worker endpoints + UI trigger
- POST /api/aos/instances/[id]/graph-build: trigger or get build command - POST /api/aos/instances/[id]/graph-status: worker callback (ok/error) - GET /api/aos/graphify-health: check if Graphify service is up - Instance detail: 'Graph neu erstellen' button (visible when demo_active/active) - Graceful degradation: if GRAPHIFY_URL not set, returns build command for external worker
This commit is contained in:
1 parent
7d94fe53ad
commit
25599a5516
4 files changed
+301
-9
No files matched your search
@@ -0,0 +1,75 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import { db } from '@/lib/db'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
// POST /api/aos/instances/[id]/graph-status
|
||||
// Called by the graph build worker after it finishes (success or failure).
|
||||
// Body: { status: 'ok' | 'error', stats?: {...}, error?: '...' }
|
||||
//
|
||||
// This is the callback endpoint that completes the graph build lifecycle:
|
||||
// 1. AOS queues build (graphify.build.queued)
|
||||
// 2. Worker picks up, calls POST /graph-build, gets the command
|
||||
// 3. Worker executes graphify CLI
|
||||
// 4. Worker calls this endpoint to report success/failure
|
||||
// 5. AOS records graphify.build.ok / graphify.build.error
|
||||
export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {
|
||||
try {
|
||||
const { id } = await params
|
||||
const body = await req.json().catch(() => ({}))
|
||||
const status = body.status === 'ok' ? 'ok' : 'error'
|
||||
|
||||
const instance = await db.instance.findUnique({ where: { id } })
|
||||
if (!instance) {
|
||||
return NextResponse.json({ error: 'instance not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
if (status === 'ok') {
|
||||
await db.instanceEvent.create({
|
||||
data: {
|
||||
instanceId: id,
|
||||
type: 'graphify.build.ok',
|
||||
step: 'graphify',
|
||||
result: 'ok',
|
||||
details: JSON.stringify({
|
||||
stats: body.stats ?? null,
|
||||
graphPath: body.graphPath ?? null,
|
||||
builtAt: new Date().toISOString(),
|
||||
}),
|
||||
},
|
||||
})
|
||||
await db.auditLog.create({
|
||||
data: {
|
||||
actor: 'graphify-worker',
|
||||
action: 'graphify.build.ok',
|
||||
entity: 'Instance',
|
||||
entityId: id,
|
||||
after: JSON.stringify({ stats: body.stats }),
|
||||
hash: 'sha256:' + Math.random().toString(36).slice(2),
|
||||
},
|
||||
})
|
||||
return NextResponse.json({ ok: true, status: 'ok' })
|
||||
} else {
|
||||
await db.instanceEvent.create({
|
||||
data: {
|
||||
instanceId: id,
|
||||
type: 'graphify.build.error',
|
||||
step: 'graphify',
|
||||
result: 'error',
|
||||
details: JSON.stringify({ error: body.error ?? 'unknown build error' }),
|
||||
},
|
||||
})
|
||||
await db.instance.update({
|
||||
where: { id },
|
||||
data: {
|
||||
lastError: `graphify build failed: ${body.error ?? 'unknown'}`,
|
||||
lastErrorAt: new Date(),
|
||||
},
|
||||
})
|
||||
return NextResponse.json({ ok: false, status: 'error', error: body.error })
|
||||
}
|
||||
} catch (err) {
|
||||
const msg = err instanceof Error ? err.message : 'internal server error'
|
||||
return NextResponse.json({ error: msg }, { status: 500 })
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user