From 9d2a330f698297ee5617d8815ac9f9eda2d16df0 Mon Sep 17 00:00:00 2001 From: nav Date: Tue, 12 May 2026 15:25:26 +0000 Subject: [PATCH] feat(guild): add guild and channel list APIs for frontend browser --- .../src/channels/channels.controller.ts | 13 ++++++-- .../src/channels/channels.module.ts | 6 ++++ .../src/channels/channels.service.ts | 31 +++++++++++++++++++ .../src/guilds/guilds.controller.ts | 12 +++++-- .../src/guilds/guilds.module.ts | 6 ++++ .../src/guilds/guilds.service.ts | 27 ++++++++++++++++ 6 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 Fabric.Backend.Guild/src/channels/channels.service.ts create mode 100644 Fabric.Backend.Guild/src/guilds/guilds.service.ts diff --git a/Fabric.Backend.Guild/src/channels/channels.controller.ts b/Fabric.Backend.Guild/src/channels/channels.controller.ts index c847211..35f47b0 100644 --- a/Fabric.Backend.Guild/src/channels/channels.controller.ts +++ b/Fabric.Backend.Guild/src/channels/channels.controller.ts @@ -1,9 +1,18 @@ -import { Body, Controller, Post } from '@nestjs/common'; +import { Body, Controller, Get, Post, Query } from '@nestjs/common'; +import { ChannelsService } from './channels.service'; @Controller('channels') export class ChannelsController { + constructor(private readonly channelsService: ChannelsService) {} + + @Get() + list(@Query('guildId') guildId?: string) { + if (!guildId) return []; + return this.channelsService.listByGuild(guildId); + } + @Post() create(@Body() body: Record) { - return { status: 'todo', action: 'create-channel', received: body }; + return this.channelsService.create(body); } } diff --git a/Fabric.Backend.Guild/src/channels/channels.module.ts b/Fabric.Backend.Guild/src/channels/channels.module.ts index ab38ce4..48b0624 100644 --- a/Fabric.Backend.Guild/src/channels/channels.module.ts +++ b/Fabric.Backend.Guild/src/channels/channels.module.ts @@ -1,7 +1,13 @@ import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; import { ChannelsController } from './channels.controller'; +import { Channel } from '../entities/channel.entity'; +import { ChannelsService } from './channels.service'; @Module({ + imports: [TypeOrmModule.forFeature([Channel])], controllers: [ChannelsController], + providers: [ChannelsService], + exports: [ChannelsService], }) export class ChannelsModule {} diff --git a/Fabric.Backend.Guild/src/channels/channels.service.ts b/Fabric.Backend.Guild/src/channels/channels.service.ts new file mode 100644 index 0000000..04f228d --- /dev/null +++ b/Fabric.Backend.Guild/src/channels/channels.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { Channel } from '../entities/channel.entity'; + +@Injectable() +export class ChannelsService { + constructor( + @InjectRepository(Channel) + private readonly channelRepo: Repository, + ) {} + + listByGuild(guildId: string) { + return this.channelRepo.find({ + where: { guildId }, + order: { createdAt: 'ASC' }, + take: 200, + }); + } + + create(input: Partial) { + const channel = this.channelRepo.create({ + guildId: String(input.guildId ?? ''), + name: String(input.name ?? ''), + kind: input.kind === 'announcement' ? 'announcement' : 'text', + isPrivate: Boolean(input.isPrivate), + lastSeq: 0, + }); + return this.channelRepo.save(channel); + } +} diff --git a/Fabric.Backend.Guild/src/guilds/guilds.controller.ts b/Fabric.Backend.Guild/src/guilds/guilds.controller.ts index 96f0f71..0878189 100644 --- a/Fabric.Backend.Guild/src/guilds/guilds.controller.ts +++ b/Fabric.Backend.Guild/src/guilds/guilds.controller.ts @@ -1,9 +1,17 @@ -import { Body, Controller, Post } from '@nestjs/common'; +import { Body, Controller, Get, Post } from '@nestjs/common'; +import { GuildsService } from './guilds.service'; @Controller('guilds') export class GuildsController { + constructor(private readonly guildsService: GuildsService) {} + + @Get() + list() { + return this.guildsService.list(); + } + @Post() create(@Body() body: Record) { - return { status: 'todo', action: 'create-guild', received: body }; + return this.guildsService.create(body); } } diff --git a/Fabric.Backend.Guild/src/guilds/guilds.module.ts b/Fabric.Backend.Guild/src/guilds/guilds.module.ts index 6d86b07..234ca23 100644 --- a/Fabric.Backend.Guild/src/guilds/guilds.module.ts +++ b/Fabric.Backend.Guild/src/guilds/guilds.module.ts @@ -1,7 +1,13 @@ import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; import { GuildsController } from './guilds.controller'; +import { Guild } from '../entities/guild.entity'; +import { GuildsService } from './guilds.service'; @Module({ + imports: [TypeOrmModule.forFeature([Guild])], controllers: [GuildsController], + providers: [GuildsService], + exports: [GuildsService], }) export class GuildsModule {} diff --git a/Fabric.Backend.Guild/src/guilds/guilds.service.ts b/Fabric.Backend.Guild/src/guilds/guilds.service.ts new file mode 100644 index 0000000..2f04de7 --- /dev/null +++ b/Fabric.Backend.Guild/src/guilds/guilds.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { Guild } from '../entities/guild.entity'; + +@Injectable() +export class GuildsService { + constructor( + @InjectRepository(Guild) + private readonly guildRepo: Repository, + ) {} + + list() { + return this.guildRepo.find({ + order: { createdAt: 'DESC' }, + take: 100, + }); + } + + create(input: Partial) { + const slug = String(input.slug ?? '').trim(); + const name = String(input.name ?? '').trim(); + const ownerUserId = input.ownerUserId ? String(input.ownerUserId) : null; + const guild = this.guildRepo.create({ slug, name, ownerUserId }); + return this.guildRepo.save(guild); + } +}