TypeScript 97.5%
SQL 1.4%
Python 0.8%
1import "server-only";2import { getDb, organizations, organizationMembers, projects, eq } from "@fetcha/db";3import { newId } from "@fetcha/core";4import { slugify } from "./utils";56/** Every user gets a personal organization + a default project at signup. */7export async function ensureWorkspace(user: { id: string; name?: string | null; email: string }): Promise<{ organizationId: string; projectId: string }> {8 const db = getDb();9 const [membership] = await db.select().from(organizationMembers).where(eq(organizationMembers.userId, user.id)).limit(1);10 if (membership) {11 const [p] = await db.select().from(projects).where(eq(projects.organizationId, membership.organizationId)).limit(1);12 if (p) return { organizationId: membership.organizationId, projectId: p.id };13 const projectId = newId("proj");14 await db.insert(projects).values({ id: projectId, organizationId: membership.organizationId, name: "Default", slug: "default" });15 return { organizationId: membership.organizationId, projectId };16 }17 const organizationId = newId("org");18 const base = user.name?.trim() || user.email.split("@")[0] || "workspace";19 const slug = `${slugify(base)}-${organizationId.slice(-6)}`;20 await db.insert(organizations).values({ id: organizationId, name: `${base}'s workspace`, slug, ownerUserId: user.id });21 await db.insert(organizationMembers).values({ organizationId, userId: user.id, role: "owner" });22 const projectId = newId("proj");23 await db.insert(projects).values({ id: projectId, organizationId, name: "Default", slug: "default", description: "Your first project. Rename it or create more from the Projects page." });24 return { organizationId, projectId };25}26