import { Body, Controller, Delete, Get, HttpCode, Param, Patch, Post, Req } from '@nestjs/common'; import { AddMemberInput, ChangeMemberRoleInput, MemberView, PondMembersView, addMemberInputSchema, changeMemberRoleInputSchema, } from '@dorfteich/shared'; import { AuthedRequest } from '../auth/auth.guard'; import { ZodValidationPipe } from '../common/zod-validation.pipe'; import { RequiresPondRole } from '../permissions/permission.decorators'; import { MembersService } from './members.service'; /** * Pond member management (issue #54). Listing is open to any member so the * membership is transparent (read-only for non-admins); adding, changing a * role, and removing are Pond-Admin-gated by the permission guard. */ @Controller('ponds/:pondId/members') export class MembersController { constructor(private readonly members: MembersService) {} @Get() @RequiresPondRole('reader', { idParam: 'pondId' }) async list( @Param('pondId') pondId: string, @Req() request: AuthedRequest, ): Promise { return this.members.list(request.user ?? null, pondId); } @Post() @RequiresPondRole('pond_admin', { idParam: 'pondId' }) async add( @Param('pondId') pondId: string, @Body(new ZodValidationPipe(addMemberInputSchema)) input: AddMemberInput, @Req() request: AuthedRequest, ): Promise { return this.members.add(request.user!, pondId, input); } @Patch(':userId') @RequiresPondRole('pond_admin', { idParam: 'pondId' }) async changeRole( @Param('pondId') pondId: string, @Param('userId') userId: string, @Body(new ZodValidationPipe(changeMemberRoleInputSchema)) input: ChangeMemberRoleInput, @Req() request: AuthedRequest, ): Promise { return this.members.changeRole(request.user!, pondId, userId, input); } @Delete(':userId') @HttpCode(204) @RequiresPondRole('pond_admin', { idParam: 'pondId' }) async remove( @Param('pondId') pondId: string, @Param('userId') userId: string, @Req() request: AuthedRequest, ): Promise { await this.members.remove(request.user!, pondId, userId); } }