import { Body, Controller, Delete, Get, Param, Patch, Post, Query } from '@nestjs/common'; import { MyService } from './my.service'; import { SevaService } from '../seva/seva.service'; import { CirclesService } from '../circles/circles.service'; import { AskAIService } from '../ask-ai/ask-ai.service'; import { KnowledgeService } from '../knowledge/knowledge.service'; import { GalleryService } from '../gallery/gallery.service'; import { MemberAuth } from '../auth/member-auth.decorator'; import { CurrentMember } from '../auth/current-member.decorator'; import type { MemberJwtPayload } from '@tower/types'; import { IsArray, IsInt, IsOptional, IsString, Min } from 'class-validator'; import { ConsentScope, MemberOptOutReason } from '@tower/types'; class OptOutDto { @IsString() @IsOptional() groupId?: string; @IsArray() @IsOptional() scopes?: ConsentScope[]; @IsString() @IsOptional() reason?: MemberOptOutReason; @IsString() @IsOptional() notes?: string; } class OptInDto { @IsString() groupId!: string; @IsArray() scopes!: ConsentScope[]; @IsInt() @Min(1) @IsOptional() retentionDays?: number; } @Controller('my') @MemberAuth() export class MyController { constructor( private readonly service: MyService, private readonly seva: SevaService, private readonly circles: CirclesService, private readonly askAI: AskAIService, private readonly knowledge: KnowledgeService, private readonly gallery: GalleryService, ) {} @Get('knowledge') knowledgeList(@CurrentMember() member: MemberJwtPayload, @Query('q') q?: string) { return this.knowledge.listForMember(member.tenantId, q); } @Get('memories') memoriesList(@CurrentMember() member: MemberJwtPayload) { return this.gallery.listForMember(member.tenantId); } @Get('memories/:id') memoriesAlbum(@CurrentMember() member: MemberJwtPayload, @Param('id') id: string) { return this.gallery.getAlbumForMember(member.tenantId, id); } @Get('ask') askHistory(@CurrentMember() member: MemberJwtPayload) { return this.askAI.history(member.sub, member.tenantId); } @Post('ask') ask(@CurrentMember() member: MemberJwtPayload, @Body() body: { question: string }) { return this.askAI.ask(member.sub, member.tenantId, body.question); } @Get('seva') sevaList(@CurrentMember() member: MemberJwtPayload) { return this.seva.listForMember(member.sub, member.tenantId); } @Post('seva/:id/signup') sevaSignup(@CurrentMember() member: MemberJwtPayload, @Param('id') id: string) { return this.seva.signup(member.sub, member.tenantId, id); } @Post('seva/:id/cancel') sevaCancel(@CurrentMember() member: MemberJwtPayload, @Param('id') id: string) { return this.seva.cancel(member.sub, member.tenantId, id); } @Get('directory') directory( @CurrentMember() member: MemberJwtPayload, @Query('q') q?: string, @Query('interest') interest?: string, ) { return this.service.getDirectory(member.sub, member.tenantId, q, interest); } @Get('circles') circlesList(@CurrentMember() member: MemberJwtPayload) { return this.circles.listForMember(member.sub, member.tenantId); } @Post('circles/:id/join') circleJoin(@CurrentMember() member: MemberJwtPayload, @Param('id') id: string) { return this.circles.join(member.sub, member.tenantId, id); } @Post('circles/:id/leave') circleLeave(@CurrentMember() member: MemberJwtPayload, @Param('id') id: string) { return this.circles.leave(member.sub, member.tenantId, id); } @Get('dashboard') dashboard(@CurrentMember() member: MemberJwtPayload) { return this.service.getDashboard(member.sub, member.tenantId); } @Get('digest') digests(@CurrentMember() member: MemberJwtPayload) { return this.service.getDigests(member.tenantId); } @Get('events') listEvents(@CurrentMember() member: MemberJwtPayload) { return this.service.listEvents(member.sub, member.tenantId); } @Post('events/:id/rsvp') rsvp( @CurrentMember() member: MemberJwtPayload, @Param('id') eventId: string, @Body() body: { status: 'GOING' | 'NOT_GOING' | 'MAYBE'; note?: string }, ) { return this.service.upsertRsvp(member.sub, member.tenantId, eventId, body.status, body.note); } @Get('profile') profile(@CurrentMember() member: MemberJwtPayload) { return this.service.getProfile(member.sub, member.tenantId); } @Patch('profile') updateProfile(@CurrentMember() member: MemberJwtPayload, @Body() body: { displayName?: string; hometown?: string; currentLocation?: string; interests?: string[]; language?: string; digestPreference?: string; directoryVisible?: boolean; }) { return this.service.updateProfile(member.sub, member.tenantId, body); } @Get('groups') listGroups(@CurrentMember() member: MemberJwtPayload) { return this.service.listGroups(member.sub, member.tenantId); } @Get('groups/:id') getGroup(@CurrentMember() member: MemberJwtPayload, @Param('id') id: string) { return this.service.getGroup(member.sub, member.tenantId, id); } @Post('opt-out') optOut(@CurrentMember() member: MemberJwtPayload, @Body() body: OptOutDto) { return this.service.optOut(member.sub, member.tenantId, body); } @Post('opt-in') optIn(@CurrentMember() member: MemberJwtPayload, @Body() body: OptInDto) { return this.service.optIn(member.sub, member.tenantId, body); } @Delete('account') deleteAccount(@CurrentMember() member: MemberJwtPayload) { return this.service.deleteAccount(member.sub, member.tenantId); } }