feat(guild): channel membership + public visibility

- new channel_members table; creator always added, plus selected members
- Channel.isPublic (default false): public channels visible to all guild
  members; non-public only to explicit members
- GET /channels filters to channels visible to the requesting user

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
h z
2026-05-15 09:09:41 +01:00
parent 78d2179e8c
commit 774dff11ba
6 changed files with 101 additions and 28 deletions

View File

@@ -1,18 +1,33 @@
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
import { Body, Controller, Get, Post, Query, Req, UnauthorizedException } from '@nestjs/common';
import { ChannelsService } from './channels.service';
// ApiKeyGuard attaches the introspected Center user id onto the request.
type AuthedRequest = { userId?: string };
@Controller('channels')
export class ChannelsController {
constructor(private readonly channelsService: ChannelsService) {}
@Get()
list(@Query('guildId') guildId?: string) {
if (!guildId) return this.channelsService.listAll();
return this.channelsService.listByGuild(guildId);
list(@Req() req: AuthedRequest, @Query('guildId') guildId?: string) {
const userId = req.userId ?? '';
if (!userId) throw new UnauthorizedException('missing user');
return this.channelsService.listForUser(String(guildId ?? ''), userId);
}
@Post()
create(@Body() body: Record<string, unknown>) {
return this.channelsService.create(body);
create(@Req() req: AuthedRequest, @Body() body: Record<string, unknown>) {
const userId = req.userId ?? '';
if (!userId) throw new UnauthorizedException('missing user');
return this.channelsService.create(
{
guildId: body.guildId as string | undefined,
name: body.name as string | undefined,
kind: body.kind as string | undefined,
isPublic: Boolean(body.isPublic),
memberUserIds: Array.isArray(body.memberUserIds) ? (body.memberUserIds as string[]) : [],
},
userId,
);
}
}