| |
| |
| |
| |
| |
|
|
| import { NextRequest, NextResponse } from 'next/server'; |
| import { requireAuth, verifyInstanceApiKey } from '@/lib/auth/session'; |
| import { |
| listWorkspaces, |
| createWorkspace, |
| grantWorkspaceAccess, |
| getUserByEmail, |
| getSystemDatabase, |
| getWorkspaceProjectCount, |
| } from '@/lib/auth/system-database'; |
|
|
| function getWorkspaceDeploymentCount(workspaceId: string): number { |
| try { |
| const sysDb = getSystemDatabase(); |
| const row = sysDb.prepare('SELECT COUNT(*) as count FROM deployment_routing WHERE workspace_id = ?').get(workspaceId) as { count: number }; |
| return row.count; |
| } catch { return 0; } |
| } |
|
|
| function getWorkspaceMemberCount(workspaceId: string): number { |
| try { |
| const sysDb = getSystemDatabase(); |
| const row = sysDb.prepare('SELECT COUNT(*) as count FROM workspace_access WHERE workspace_id = ?').get(workspaceId) as { count: number }; |
| return row.count; |
| } catch { return 0; } |
| } |
|
|
| function getWorkspaceOwnerEmail(ownerId: string): string | null { |
| try { |
| const sysDb = getSystemDatabase(); |
| const row = sysDb.prepare('SELECT email FROM users WHERE id = ?').get(ownerId) as { email: string } | undefined; |
| return row?.email ?? null; |
| } catch { return null; } |
| } |
|
|
| export async function GET(request: NextRequest) { |
| try { |
| const apiSession = verifyInstanceApiKey(request); |
| const session = apiSession || await requireAuth(); |
| if (!session.isAdmin) { |
| return NextResponse.json({ error: 'Admin access required' }, { status: 403 }); |
| } |
|
|
| const workspaces = listWorkspaces(); |
|
|
| const enriched = workspaces.map(ws => ({ |
| id: ws.id, |
| name: ws.name, |
| ownerId: ws.owner_id, |
| ownerEmail: getWorkspaceOwnerEmail(ws.owner_id), |
| maxProjects: ws.max_projects, |
| maxDeployments: ws.max_deployments, |
| maxStorageMb: ws.max_storage_mb, |
| memberCount: getWorkspaceMemberCount(ws.id), |
| projectCount: getWorkspaceProjectCount(ws.id), |
| deploymentCount: getWorkspaceDeploymentCount(ws.id), |
| createdAt: ws.created_at, |
| updatedAt: ws.updated_at, |
| })); |
|
|
| return NextResponse.json({ workspaces: enriched }); |
| } catch (error) { |
| if (error instanceof Error && error.message === 'Unauthorized') { |
| return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); |
| } |
| return NextResponse.json({ error: 'Failed to list workspaces' }, { status: 500 }); |
| } |
| } |
|
|
| export async function POST(request: NextRequest) { |
| try { |
| const apiSession = verifyInstanceApiKey(request); |
| const session = apiSession || await requireAuth(); |
| if (!session.isAdmin) { |
| return NextResponse.json({ error: 'Admin access required' }, { status: 403 }); |
| } |
|
|
| const body = await request.json(); |
| const { name, ownerId, ownerEmail } = body; |
|
|
| if (!name) { |
| return NextResponse.json({ error: 'Workspace name is required' }, { status: 400 }); |
| } |
|
|
| |
| let resolvedOwnerId = ownerId; |
| if (!resolvedOwnerId && ownerEmail) { |
| const user = getUserByEmail(ownerEmail); |
| if (!user) { |
| return NextResponse.json({ error: `No user found with email: ${ownerEmail}` }, { status: 404 }); |
| } |
| resolvedOwnerId = user.id; |
| } |
|
|
| if (!resolvedOwnerId) { |
| return NextResponse.json({ error: 'Owner is required (provide ownerId or ownerEmail)' }, { status: 400 }); |
| } |
|
|
| const workspaceId = createWorkspace(name, resolvedOwnerId); |
|
|
| |
| |
| grantWorkspaceAccess(resolvedOwnerId, workspaceId, 'owner'); |
|
|
| return NextResponse.json({ id: workspaceId }, { status: 201 }); |
| } catch (error) { |
| if (error instanceof Error && error.message === 'Unauthorized') { |
| return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); |
| } |
| return NextResponse.json({ error: 'Failed to create workspace' }, { status: 500 }); |
| } |
| } |
|
|