Add internal provision endpoint for rSpace Registry

Auth-free POST /api/internal/provision creates default Notebook + system User
+ OWNER collaborator scoped to workspace slug.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-02-25 00:30:11 -08:00
parent 802091a84f
commit ea88aa180c
1 changed files with 46 additions and 0 deletions

View File

@ -0,0 +1,46 @@
import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
/**
* Internal provision endpoint called by rSpace Registry when activating
* this app for a space. No auth required (only reachable from Docker network).
*
* Creates a default Notebook scoped to the workspace slug + a system collaborator.
*/
export async function POST(request: Request) {
const body = await request.json();
const space: string = body.space?.trim();
if (!space) {
return NextResponse.json({ error: "Missing space name" }, { status: 400 });
}
// Check if a notebook already exists for this workspace
const existing = await prisma.notebook.findFirst({
where: { workspaceSlug: space },
});
if (existing) {
return NextResponse.json({ status: "exists", id: existing.id, slug: existing.slug });
}
const systemDid = `did:system:${space}`;
const user = await prisma.user.upsert({
where: { did: systemDid },
update: {},
create: { did: systemDid, username: `${space}-admin` },
});
const notebook = await prisma.notebook.create({
data: {
title: `${space.charAt(0).toUpperCase() + space.slice(1)} Notes`,
slug: `${space}-notes`,
description: body.description || `Shared notes for ${space}`,
workspaceSlug: space,
isPublic: body.public ?? false,
collaborators: {
create: { userId: user.id, role: "OWNER" },
},
},
});
return NextResponse.json({ status: "created", id: notebook.id, slug: notebook.slug }, { status: 201 });
}