From 605d3ac09287c6d00e7ddc35be9219471aae9850 Mon Sep 17 00:00:00 2001 From: hzhang Date: Fri, 15 May 2026 09:35:36 +0100 Subject: [PATCH] feat(guild): required channel x_type enum Channel.x_type enum(general|work|report|discuss|triage|custom); required and validated on channel creation (400 if missing/invalid). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/channels/channels.controller.ts | 1 + src/channels/channels.service.ts | 10 ++++++++++ src/entities/channel.entity.ts | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/src/channels/channels.controller.ts b/src/channels/channels.controller.ts index c45adcc..b78b527 100644 --- a/src/channels/channels.controller.ts +++ b/src/channels/channels.controller.ts @@ -24,6 +24,7 @@ export class ChannelsController { guildId: body.guildId as string | undefined, name: body.name as string | undefined, kind: body.kind as string | undefined, + xType: body.xType as string | undefined, isPublic: Boolean(body.isPublic), memberUserIds: Array.isArray(body.memberUserIds) ? (body.memberUserIds as string[]) : [], }, diff --git a/src/channels/channels.service.ts b/src/channels/channels.service.ts index 0051306..68b0ec1 100644 --- a/src/channels/channels.service.ts +++ b/src/channels/channels.service.ts @@ -4,10 +4,14 @@ import { In, Repository } from 'typeorm'; import { Channel } from '../entities/channel.entity'; import { ChannelMember } from '../entities/channel-member.entity'; +const X_TYPES = ['general', 'work', 'report', 'discuss', 'triage', 'custom'] as const; +type XType = (typeof X_TYPES)[number]; + type CreateChannelInput = { guildId?: string; name?: string; kind?: string; + xType?: string; isPublic?: boolean; memberUserIds?: string[]; }; @@ -44,14 +48,20 @@ export class ChannelsService { async create(input: CreateChannelInput, creatorUserId: string) { const guildId = String(input.guildId ?? '').trim(); const name = String(input.name ?? '').trim(); + const xType = String(input.xType ?? '').trim() as XType; if (!guildId) throw new BadRequestException('guildId is required'); if (!name) throw new BadRequestException('name is required'); if (!creatorUserId) throw new BadRequestException('creator is required'); + if (!input.xType) throw new BadRequestException('xType is required'); + if (!X_TYPES.includes(xType)) { + throw new BadRequestException(`xType must be one of: ${X_TYPES.join(', ')}`); + } const channel = await this.channelRepo.save( this.channelRepo.create({ guildId, name, + xType, kind: input.kind === 'announcement' ? 'announcement' : 'text', isPrivate: !input.isPublic, isPublic: Boolean(input.isPublic), diff --git a/src/entities/channel.entity.ts b/src/entities/channel.entity.ts index 2bc0b2a..127a199 100644 --- a/src/entities/channel.entity.ts +++ b/src/entities/channel.entity.ts @@ -13,6 +13,13 @@ export class Channel { @Column({ type: 'varchar', length: 120 }) name!: string; + @Column({ + name: 'x_type', + type: 'enum', + enum: ['general', 'work', 'report', 'discuss', 'triage', 'custom'], + }) + xType!: 'general' | 'work' | 'report' | 'discuss' | 'triage' | 'custom'; + @Column({ type: 'varchar', length: 16, default: 'text' }) kind!: 'text' | 'announcement';