192 lines
6.9 KiB
TypeScript
192 lines
6.9 KiB
TypeScript
|
|
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;
|
||
|
|
}
|
||
|
|
}
|