import { fail, handleOptions, json } from "../_shared/http.ts"; import { createServiceClient, requireUser, slugify, } from "../_shared/supabase.ts"; const allowedTypes = new Set(["text", "voice", "operations"]); Deno.serve(async (req) => { const preflight = handleOptions(req); if (preflight) return preflight; if (req.method !== "POST") return fail("Method not allowed", 405); const { user, error: userError } = await requireUser(req); if (!user) return fail(userError ?? "Unauthorized", 401); const serviceClient = createServiceClient(); let body: { organization_id?: string; name?: string; description?: string; slug?: string; type?: string; topic?: string; position?: number; is_private?: boolean; }; try { body = await req.json(); } catch { return fail("Invalid JSON body"); } const organizationId = body.organization_id; const name = (body.name ?? "").trim(); const description = (body.description ?? "").trim(); const type = body.type ?? "text"; const topic = body.topic?.trim() || null; const isPrivate = Boolean(body.is_private); const position = Number.isInteger(body.position) ? Number(body.position) : 0; if (!organizationId) return fail("organization_id is required"); if (!name) return fail("name is required"); if (!allowedTypes.has(type)) return fail("type is invalid"); const { data: member, error: roleError } = await serviceClient .from("organization_members") .select("role") .eq("organization_id", organizationId) .eq("user_id", user.id) .maybeSingle(); if (roleError) return fail(roleError.message, 400); if (!member || !["owner", "admin"].includes(member.role)) { return fail("forbidden", 403); } const slug = slugify(body.slug?.trim() || name); if (!slug) return fail("slug is invalid"); const { data: channel, error: createError } = await serviceClient .from("channels") .insert({ organization_id: organizationId, name, description, slug, type, topic, is_private: isPrivate, position, created_by: user.id, }) .select( "id, organization_id, name, description, slug, type, topic, is_private, position, created_by, created_at", ) .single(); if (createError) { if (createError.code === "23505") return fail("channel slug already exists", 409); return fail(createError.message, 400); } if (channel.is_private) { const { error: cmError } = await serviceClient.from("channel_members").insert({ channel_id: channel.id, user_id: user.id, }); if (cmError) return fail(cmError.message, 400); } return json({ channel }, 201); });