/** * admin.orgs.listSites, admin.orgs.addSite, admin.orgs.removeSite * Site management for organizations */ import { ORPCError } from "@orpc/server"; import { authMiddleware, os, superuserMiddleware } from "../../base.js"; import { toSiteResponse } from "../helpers.js"; export const adminOrgsListSites = os.admin.orgs.listSites .use(authMiddleware) .use(superuserMiddleware) .handler(async ({ input, context }) => { const { slug } = input; const org = await context.db .selectFrom("orgs") .where("slug", "=", slug) .select(["id"]) .executeTakeFirst(); if (!org) { throw new ORPCError("NOT_FOUND", { message: "Organization not found" }); } const sites = await context.db .selectFrom("org_sites") .where("org_id", "=", org.id) .selectAll() .execute(); return sites.map(toSiteResponse); }); export const adminOrgsAddSite = os.admin.orgs.addSite .use(authMiddleware) .use(superuserMiddleware) .handler(async ({ input, context }) => { const { slug, domain } = input; // Use transaction to prevent race condition on site creation await context.db.transaction().execute(async (trx) => { const org = await trx .selectFrom("orgs") .where("slug", "=", slug) .select(["id"]) .executeTakeFirst(); if (!org) { throw new ORPCError("NOT_FOUND", { message: "Organization not found" }); } // Check if site already exists (inside transaction) const existingSite = await trx .selectFrom("org_sites") .where("domain", "=", domain) .select(["id"]) .executeTakeFirst(); if (existingSite) { throw new ORPCError("CONFLICT", { message: "Site with this domain already exists", }); } await trx .insertInto("org_sites") .values({ org_id: org.id, domain, }) .execute(); }); return { success: true }; }); export const adminOrgsRemoveSite = os.admin.orgs.removeSite .use(authMiddleware) .use(superuserMiddleware) .handler(async ({ input, context }) => { const { slug, domain } = input; const org = await context.db .selectFrom("orgs") .where("slug", "=", slug) .select(["id"]) .executeTakeFirst(); if (!org) { throw new ORPCError("NOT_FOUND", { message: "Organization not found" }); } const result = await context.db .deleteFrom("org_sites") .where("org_id", "=", org.id) .where("domain", "=", domain) .executeTakeFirst(); if (!result.numDeletedRows || result.numDeletedRows === 0n) { throw new ORPCError("NOT_FOUND", { message: "Site not found" }); } return { success: true }; });