The ALLOW_DEV_TEST_ENDPOINTS short-circuit on create wrote 'dev-stub-<ms>' as the channel ID. boardChannelUpdateSchema requires ^[A-Z0-9]+$, so the very next edit on the same channel hit a 400 from Zod and the table never updated. Use base36-uppercased timestamp with a 'CDEV' prefix so the stub survives a round-trip through the patch route. Live path is unchanged.
71 lines
2.3 KiB
JavaScript
71 lines
2.3 KiB
JavaScript
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
|
|
}
|
|
})
|