feat: implement connection request management including schema, API endpoints, and business logic for users and agents.
This commit is contained in:
191
src/connection-requests/connection-requests.controller.ts
Normal file
191
src/connection-requests/connection-requests.controller.ts
Normal file
@@ -0,0 +1,191 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Patch,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiQuery } from '@nestjs/swagger';
|
||||
import { ConnectionRequestsService } from './connection-requests.service';
|
||||
import { CreateConnectionRequestDto, RespondConnectionRequestDto } from './dto';
|
||||
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
|
||||
import { RolesGuard } from '../auth/guards/roles.guard';
|
||||
import { Roles } from '../auth/decorators/roles.decorator';
|
||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||
import { UserRole, ConnectionStatus } from '@prisma/client';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
|
||||
@ApiTags('Connection Requests')
|
||||
@Controller('connection-requests')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@ApiBearerAuth()
|
||||
export class ConnectionRequestsController {
|
||||
constructor(
|
||||
private readonly connectionRequestsService: ConnectionRequestsService,
|
||||
private readonly prisma: PrismaService,
|
||||
) {}
|
||||
|
||||
@Post()
|
||||
@Roles(UserRole.USER)
|
||||
@ApiOperation({ summary: 'Create a connection request to an agent' })
|
||||
@ApiResponse({ status: 201, description: 'Connection request created successfully' })
|
||||
@ApiResponse({ status: 400, description: 'Agent is not available or invalid request' })
|
||||
@ApiResponse({ status: 409, description: 'Connection request already exists' })
|
||||
async createRequest(
|
||||
@CurrentUser() user: { id: string },
|
||||
@Body() dto: CreateConnectionRequestDto,
|
||||
) {
|
||||
// Return raw data - TransformInterceptor will wrap it
|
||||
return this.connectionRequestsService.createRequest(user.id, dto);
|
||||
}
|
||||
|
||||
@Get('my-requests')
|
||||
@Roles(UserRole.USER)
|
||||
@ApiOperation({ summary: 'Get all connection requests sent by the current user' })
|
||||
@ApiQuery({ name: 'status', enum: ConnectionStatus, required: false })
|
||||
@ApiResponse({ status: 200, description: 'Connection requests retrieved successfully' })
|
||||
async getMyRequests(
|
||||
@CurrentUser() user: { id: string },
|
||||
@Query('status') status?: ConnectionStatus,
|
||||
) {
|
||||
// Return raw data - TransformInterceptor will wrap it
|
||||
return this.connectionRequestsService.getMyRequests(user.id, status);
|
||||
}
|
||||
|
||||
@Get('received')
|
||||
@Roles(UserRole.AGENT)
|
||||
@ApiOperation({ summary: 'Get all connection requests received by the current agent' })
|
||||
@ApiQuery({ name: 'status', enum: ConnectionStatus, required: false })
|
||||
@ApiResponse({ status: 200, description: 'Connection requests retrieved successfully' })
|
||||
async getReceivedRequests(
|
||||
@CurrentUser() user: { id: string },
|
||||
@Query('status') status?: ConnectionStatus,
|
||||
) {
|
||||
// Get agent profile for the current user
|
||||
const agentProfile = await this.prisma.agentProfile.findUnique({
|
||||
where: { userId: user.id },
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
if (!agentProfile) {
|
||||
// Return empty array - TransformInterceptor will wrap it
|
||||
return [];
|
||||
}
|
||||
|
||||
// Return raw data - TransformInterceptor will wrap it
|
||||
return this.connectionRequestsService.getReceivedRequests(
|
||||
agentProfile.id,
|
||||
status,
|
||||
);
|
||||
}
|
||||
|
||||
@Get('received/counts')
|
||||
@Roles(UserRole.AGENT)
|
||||
@ApiOperation({ summary: 'Get connection request counts for the current agent' })
|
||||
@ApiResponse({ status: 200, description: 'Request counts retrieved successfully' })
|
||||
async getRequestCounts(@CurrentUser() user: { id: string }) {
|
||||
const agentProfile = await this.prisma.agentProfile.findUnique({
|
||||
where: { userId: user.id },
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
if (!agentProfile) {
|
||||
// Return default counts - TransformInterceptor will wrap it
|
||||
return { pending: 0, accepted: 0, rejected: 0, total: 0 };
|
||||
}
|
||||
|
||||
// Return raw data - TransformInterceptor will wrap it
|
||||
return this.connectionRequestsService.getRequestCounts(agentProfile.id);
|
||||
}
|
||||
|
||||
@Get('status/:agentProfileId')
|
||||
@Roles(UserRole.USER, UserRole.AGENT)
|
||||
@ApiOperation({ summary: 'Get connection status between current user and an agent' })
|
||||
@ApiResponse({ status: 200, description: 'Connection status retrieved successfully' })
|
||||
async getConnectionStatus(
|
||||
@CurrentUser() user: { id: string },
|
||||
@Param('agentProfileId') agentProfileId: string,
|
||||
) {
|
||||
// Return raw data - TransformInterceptor will wrap it
|
||||
return this.connectionRequestsService.getConnectionStatus(
|
||||
user.id,
|
||||
agentProfileId,
|
||||
);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@ApiOperation({ summary: 'Get a specific connection request by ID' })
|
||||
@ApiResponse({ status: 200, description: 'Connection request retrieved successfully' })
|
||||
@ApiResponse({ status: 404, description: 'Connection request not found' })
|
||||
async getRequestById(
|
||||
@CurrentUser() user: { id: string; role: UserRole },
|
||||
@Param('id') id: string,
|
||||
) {
|
||||
let agentProfileId: string | undefined;
|
||||
|
||||
if (user.role === UserRole.AGENT) {
|
||||
const agentProfile = await this.prisma.agentProfile.findUnique({
|
||||
where: { userId: user.id },
|
||||
select: { id: true },
|
||||
});
|
||||
agentProfileId = agentProfile?.id;
|
||||
}
|
||||
|
||||
// Return raw data - TransformInterceptor will wrap it
|
||||
return this.connectionRequestsService.getRequestById(
|
||||
id,
|
||||
user.id,
|
||||
agentProfileId,
|
||||
);
|
||||
}
|
||||
|
||||
@Patch(':id/respond')
|
||||
@Roles(UserRole.AGENT)
|
||||
@ApiOperation({ summary: 'Respond to a connection request (accept/reject)' })
|
||||
@ApiResponse({ status: 200, description: 'Response recorded successfully' })
|
||||
@ApiResponse({ status: 400, description: 'Request already responded to' })
|
||||
@ApiResponse({ status: 403, description: 'Not authorized to respond to this request' })
|
||||
@ApiResponse({ status: 404, description: 'Connection request not found' })
|
||||
async respondToRequest(
|
||||
@CurrentUser() user: { id: string },
|
||||
@Param('id') id: string,
|
||||
@Body() dto: RespondConnectionRequestDto,
|
||||
) {
|
||||
const agentProfile = await this.prisma.agentProfile.findUnique({
|
||||
where: { userId: user.id },
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
if (!agentProfile) {
|
||||
// Throw an error instead of returning non-standard response
|
||||
throw new Error('Agent profile not found');
|
||||
}
|
||||
|
||||
// Return raw data - TransformInterceptor will wrap it
|
||||
return this.connectionRequestsService.respondToRequest(
|
||||
id,
|
||||
agentProfile.id,
|
||||
dto,
|
||||
);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@Roles(UserRole.USER)
|
||||
@ApiOperation({ summary: 'Cancel a pending connection request' })
|
||||
@ApiResponse({ status: 200, description: 'Connection request cancelled successfully' })
|
||||
@ApiResponse({ status: 400, description: 'Only pending requests can be cancelled' })
|
||||
@ApiResponse({ status: 403, description: 'Not authorized to cancel this request' })
|
||||
@ApiResponse({ status: 404, description: 'Connection request not found' })
|
||||
async cancelRequest(
|
||||
@CurrentUser() user: { id: string },
|
||||
@Param('id') id: string,
|
||||
) {
|
||||
await this.connectionRequestsService.cancelRequest(id, user.id);
|
||||
// Return null/undefined - TransformInterceptor will wrap it as { success: true, data: null }
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user