import BoardChannel from '../../models/boardChannel.js' import { requireAdmin } from '../../utils/auth.js' import { validateBody } from '../../utils/validateBody.js' import { boardChannelCreateSchema } from '../../utils/schemas.js' import { getSlackAdminService } from '../../utils/slack.ts' export default defineEventHandler(async (event) => { await requireAdmin(event) const body = await validateBody(event, boardChannelCreateSchema) if (body.tagSlugs && body.tagSlugs.length) { const conflict = await BoardChannel.findOne({ tagSlugs: { $in: body.tagSlugs } }).lean() if (conflict) { const taken = (conflict.tagSlugs || []).filter((s) => body.tagSlugs.includes(s)) throw createError({ statusCode: 409, statusMessage: `Tag${taken.length > 1 ? 's' : ''} already mapped to "${conflict.name}": ${taken.join(', ')}`, }) } } let slackChannelId = body.slackChannelId let channelName = body.name if (!slackChannelId) { if (process.env.ALLOW_DEV_TEST_ENDPOINTS === 'true') { // Match the Slack channel ID format (^[A-Z0-9]+$) so the value // round-trips through boardChannelUpdateSchema on subsequent edits. slackChannelId = `CDEV${Date.now().toString(36).toUpperCase()}` console.log('[slack] DEV MODE — skipping createChannel', { name: body.name, slackChannelId }) } else { const slack = getSlackAdminService() if (!slack) { throw createError({ statusCode: 500, statusMessage: 'Slack integration not configured', }) } try { const created = await slack.createChannel(body.name) slackChannelId = created.id channelName = created.name } catch (err) { throw createError({ statusCode: 502, statusMessage: `Failed to create Slack channel: ${err.data?.error || err.message}`, }) } } } try { const channel = await BoardChannel.create({ name: channelName, slackChannelId, tagSlugs: body.tagSlugs || [] }) setResponseStatus(event, 201) return { channel: channel.toObject() } } catch (err) { if (err.code === 11000) { throw createError({ statusCode: 409, statusMessage: 'A channel with that Slack channel ID already exists' }) } throw err } })