import { db, mothershipInboxTask, workspace } from '@sim/db' import { createLogger } from '@sim/logger' import { getErrorMessage } from '@sim/utils/errors' import { eq, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { updateInboxConfigContract } from '@/lib/api/contracts/inbox' import { parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { hasWorkspaceInboxAccess } from '@/lib/billing/core/subscription' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { disableInbox, enableInbox, updateInboxAddress } from '@/lib/mothership/inbox/lifecycle' import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' const logger = createLogger('InboxConfigAPI') export const GET = withRouteHandler( async (_req: NextRequest, { params }: { params: Promise<{ id: string }> }) => { const { id: workspaceId } = await params const session = await getSession() if (!session?.user?.id) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } const permission = await getUserEntityPermissions(session.user.id, 'workspace', workspaceId) if (!permission) { return NextResponse.json({ error: 'Not found' }, { status: 404 }) } const [wsResult, statsResult, entitled] = await Promise.all([ db .select({ inboxEnabled: workspace.inboxEnabled, inboxAddress: workspace.inboxAddress, }) .from(workspace) .where(eq(workspace.id, workspaceId)) .limit(1), db .select({ status: mothershipInboxTask.status, count: sql`count(*)::int`, }) .from(mothershipInboxTask) .where(eq(mothershipInboxTask.workspaceId, workspaceId)) .groupBy(mothershipInboxTask.status), hasWorkspaceInboxAccess(workspaceId), ]) const [ws] = wsResult if (!ws) { return NextResponse.json({ error: 'Workspace not found' }, { status: 404 }) } const stats = { total: 0, completed: 0, processing: 0, failed: 0, } for (const row of statsResult) { const count = Number(row.count) stats.total += count if (row.status === 'completed') stats.completed = count else if (row.status === 'processing') stats.processing = count else if (row.status === 'failed') stats.failed = count } return NextResponse.json({ enabled: ws.inboxEnabled, address: ws.inboxAddress, entitled, taskStats: stats, }) } ) export const PATCH = withRouteHandler( async (req: NextRequest, context: { params: Promise<{ id: string }> }) => { const { id: workspaceId } = await context.params const session = await getSession() if (!session?.user?.id) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } const permission = await getUserEntityPermissions(session.user.id, 'workspace', workspaceId) if (permission !== 'admin') { return NextResponse.json({ error: 'Admin access required' }, { status: 403 }) } const parsed = await parseRequest(updateInboxConfigContract, req, context) if (!parsed.success) return parsed.response const body = parsed.data.body try { if (body.enabled === false) { await disableInbox(workspaceId) return NextResponse.json({ enabled: false, address: null }) } if (!(await hasWorkspaceInboxAccess(workspaceId))) { return NextResponse.json({ error: 'Sim Mailer requires a Max plan' }, { status: 403 }) } if (body.enabled === true) { const [current] = await db .select({ inboxEnabled: workspace.inboxEnabled }) .from(workspace) .where(eq(workspace.id, workspaceId)) .limit(1) if (current?.inboxEnabled) { return NextResponse.json({ error: 'Inbox is already enabled' }, { status: 409 }) } const config = await enableInbox(workspaceId, { username: body.username }) return NextResponse.json(config) } if (body.username) { const config = await updateInboxAddress(workspaceId, body.username) return NextResponse.json(config) } return NextResponse.json({ error: 'No valid update provided' }, { status: 400 }) } catch (error) { logger.error('Inbox config update failed', { workspaceId, error: getErrorMessage(error, 'Unknown error'), }) return NextResponse.json( { error: getErrorMessage(error, 'Failed to update inbox') }, { status: 500 } ) } } )