Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | /** * Admin Postcards API * * GET /api/admin/postcards - List recent postcards with their task trees */ import { NextResponse } from 'next/server' import { desc, eq, inArray } from 'drizzle-orm' import { db, schema } from '@/db' import { withAuth } from '@/lib/auth/withAuth' export const GET = withAuth( async (request) => { const url = new URL(request.url) const statusFilter = url.searchParams.get('status') const limit = Math.min(parseInt(url.searchParams.get('limit') ?? '50', 10), 100) // Fetch postcards let postcards = await db .select() .from(schema.numberLinePostcards) .orderBy(desc(schema.numberLinePostcards.createdAt)) .limit(limit) .all() // Apply status filter if provided if (statusFilter) { postcards = postcards.filter((p) => p.status === statusFilter) } // Collect all task IDs from postcards const taskIds = postcards.map((p) => p.taskId).filter((id): id is string => id !== null) if (taskIds.length === 0) { return NextResponse.json({ postcards: postcards.map((p) => ({ ...p, manifest: p.manifest, parentTask: null, childTasks: [], })), }) } // Fetch parent tasks const parentTasks = await db .select({ id: schema.backgroundTasks.id, type: schema.backgroundTasks.type, status: schema.backgroundTasks.status, progress: schema.backgroundTasks.progress, progressMessage: schema.backgroundTasks.progressMessage, error: schema.backgroundTasks.error, output: schema.backgroundTasks.output, createdAt: schema.backgroundTasks.createdAt, startedAt: schema.backgroundTasks.startedAt, completedAt: schema.backgroundTasks.completedAt, }) .from(schema.backgroundTasks) .where(inArray(schema.backgroundTasks.id, taskIds)) .all() const parentTaskMap = new Map(parentTasks.map((t) => [t.id, t])) // Fetch child tasks for all parent task IDs const childTasks = await db .select({ id: schema.backgroundTasks.id, type: schema.backgroundTasks.type, status: schema.backgroundTasks.status, progress: schema.backgroundTasks.progress, progressMessage: schema.backgroundTasks.progressMessage, error: schema.backgroundTasks.error, output: schema.backgroundTasks.output, createdAt: schema.backgroundTasks.createdAt, startedAt: schema.backgroundTasks.startedAt, completedAt: schema.backgroundTasks.completedAt, parentTaskId: schema.backgroundTasks.parentTaskId, }) .from(schema.backgroundTasks) .where(inArray(schema.backgroundTasks.parentTaskId, taskIds)) .all() // Group child tasks by parent const childTasksByParent = new Map<string, typeof childTasks>() for (const child of childTasks) { if (!child.parentTaskId) continue const existing = childTasksByParent.get(child.parentTaskId) ?? [] existing.push(child) childTasksByParent.set(child.parentTaskId, existing) } // Assemble response const result = postcards.map((p) => ({ ...p, manifest: p.manifest, parentTask: p.taskId ? (parentTaskMap.get(p.taskId) ?? null) : null, childTasks: p.taskId ? (childTasksByParent.get(p.taskId) ?? []) : [], })) return NextResponse.json({ postcards: result }) }, { role: 'admin' } ) |