feat(provisioning): echtes Modell-A-Provisioning via create_studio_for_user
studio-adapter ruft jetzt den neuen service_role-RPC (APP 0011): Auth-User anlegen (oder bei 422 bestehenden holen) → create_studio_for_user → Instanz-URL. MOCK-Modus bleibt für lokalen Test ohne Rapport-Stack. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -41,31 +41,38 @@ export async function provision({ account, plan }) {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
|
||||
// 1. Auth-User anlegen (GoTrue Admin-API), bereits bestätigt.
|
||||
// 1. Auth-User anlegen (GoTrue Admin-API), bereits bestätigt. Existiert die
|
||||
// E-Mail schon (422), holen wir den bestehenden User per Listen-Filter.
|
||||
const tempPassword = randomUUID();
|
||||
const userRes = await fetch(`${base}/auth/v1/admin/users`, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify({ email: account.email, password: tempPassword, email_confirm: true }),
|
||||
});
|
||||
if (!userRes.ok) throw new Error(`GoTrue admin/users: ${userRes.status} ${await userRes.text()}`);
|
||||
const user = await userRes.json();
|
||||
let user;
|
||||
if (userRes.ok) {
|
||||
user = await userRes.json();
|
||||
} else if (userRes.status === 422) {
|
||||
const list = await fetch(`${base}/auth/v1/admin/users?filter=${encodeURIComponent(account.email)}`, { headers });
|
||||
const body = list.ok ? await list.json() : null;
|
||||
user = body?.users?.find((u) => (u.email || "").toLowerCase() === account.email.toLowerCase());
|
||||
if (!user) throw new Error(`Auth-User existiert, aber nicht auffindbar: ${account.email}`);
|
||||
} else {
|
||||
throw new Error(`GoTrue admin/users: ${userRes.status} ${await userRes.text()}`);
|
||||
}
|
||||
|
||||
// 2.+3. Profil + Studio per RPC. Da create_studio_with_admin auth.uid() nutzt,
|
||||
// muss der Aufruf im Kontext des neuen Users laufen — hier vereinfacht über
|
||||
// einen service_role-RPC, der die Ziel-User-ID als Argument nimmt. Diese
|
||||
// server-seitige Variante (create_studio_for_user) ist im Rapport-Schema noch
|
||||
// anzulegen; bis dahin schützt der MOCK-Modus den lokalen Test.
|
||||
const slugForStudio = slug;
|
||||
// 2. Profil + Studio in einem service_role-RPC (create_studio_for_user, 0011).
|
||||
// Studio-Name = lokaler Teil der E-Mail als sinnvoller Default.
|
||||
const studioName = account.email.split("@")[0];
|
||||
const rpcRes = await fetch(`${base}/rest/v1/rpc/create_studio_for_user`, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify({ p_user_id: user.id, p_name: account.email.split("@")[0], p_slug: slugForStudio }),
|
||||
body: JSON.stringify({ p_user_id: user.id, p_name: studioName, p_slug: slug }),
|
||||
});
|
||||
if (!rpcRes.ok) throw new Error(`create_studio_for_user: ${rpcRes.status} ${await rpcRes.text()}`);
|
||||
const studioId = (await rpcRes.json());
|
||||
const studioId = await rpcRes.json();
|
||||
|
||||
return { studioId, slug: slugForStudio, instanceUrl: instanceUrl(slugForStudio) };
|
||||
return { studioId, slug, instanceUrl: instanceUrl(slug) };
|
||||
}
|
||||
|
||||
export async function deprovision({ instance }) {
|
||||
|
||||
Reference in New Issue
Block a user