Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6,870 changes: 0 additions & 6,870 deletions pnpm-lock.yaml

This file was deleted.

49 changes: 48 additions & 1 deletion src/comunidad/comunidad.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
import type { Request } from 'express';
import { ComunidadService } from './comunidad.service';
import { JwtAuthGuard } from '../auth';
import { CreateGroupDto, SendMessageBodyDto } from './dto';

// Main controller with root prefix for direct routes like /forums, /chats, etc
@ApiTags('Comunidad - Forums & Chats')
Expand Down Expand Up @@ -181,7 +182,7 @@ export class ComunidadController {
status: 201,
description: 'Chat creado exitosamente',
})
async createChat(@Body() createChatDto: any, @Req() request: Request) {
async createChat(@Body() createChatDto: CreateGroupDto, @Req() request: Request) {
return this.comunidadService.createChat(createChatDto, request);
}

Expand All @@ -199,6 +200,52 @@ export class ComunidadController {
return this.comunidadService.getChatById(chatId, request);
}

@Get('chats/:id/messages')
@ApiOperation({
summary: 'Obtener mensajes de un chat',
description: 'Obtiene todos los mensajes de un grupo de chat específico',
})
@ApiParam({ name: 'id', description: 'ID del chat' })
@ApiResponse({
status: 200,
description: 'Mensajes obtenidos exitosamente',
})
async getChatMessages(@Param('id') chatId: string, @Req() request: Request) {
return this.comunidadService.getChatMessages(chatId, request);
}

@Post('chats/:id/messages')
@ApiOperation({
summary: 'Enviar mensaje a un chat',
description: 'Envía un nuevo mensaje a un grupo de chat',
})
@ApiParam({ name: 'id', description: 'ID del chat' })
@ApiResponse({
status: 201,
description: 'Mensaje enviado exitosamente',
})
async sendChatMessage(
@Param('id') chatId: string,
@Body() sendMessageDto: SendMessageBodyDto,
@Req() request: Request
) {
return this.comunidadService.sendChatMessage(chatId, sendMessageDto, request);
}

@Delete('chats/:id')
@ApiOperation({
summary: 'Eliminar un chat',
description: 'Elimina un grupo de chat',
})
@ApiParam({ name: 'id', description: 'ID del chat' })
@ApiResponse({
status: 200,
description: 'Chat eliminado exitosamente',
})
async deleteChat(@Param('id') chatId: string, @Req() request: Request) {
return this.comunidadService.deleteChat(chatId, request);
}

// ============ THREADS - Direct routes ============

@Get('threads')
Expand Down
60 changes: 59 additions & 1 deletion src/comunidad/comunidad.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { firstValueFrom } from 'rxjs';
import { envs } from '../config';
import type { Request } from 'express';
import { JwtForwardingHelper } from '../common/helpers';
import { CreateGroupDto, SendMessageBodyDto } from './dto';

@Injectable()
export class ComunidadService {
Expand Down Expand Up @@ -196,7 +197,7 @@ export class ComunidadService {
/**
* Proxy para crear un chat/grupo
*/
async createChat(createChatDto: any, request: Request) {
async createChat(createChatDto: CreateGroupDto, request: Request) {
const config = JwtForwardingHelper.getAxiosConfig(request);
const url = `${this.comunidadServiceUrl}/chats`;

Expand Down Expand Up @@ -231,6 +232,63 @@ export class ComunidadService {
}
}

/**
* Proxy para obtener mensajes de un chat
*/
async getChatMessages(chatId: string, request: Request) {
const config = JwtForwardingHelper.getAxiosConfig(request);
const url = `${this.comunidadServiceUrl}/chats/${chatId}/messages`;

try {
this.logger.log(`Forwarding GET request to: ${url}`);
const response = await firstValueFrom(
this.httpService.get(url, config),
);
return response.data;
} catch (error) {
this.logger.error(`Error forwarding request to comunidad service`, error);
throw error;
}
}

/**
* Proxy para enviar un mensaje a un chat
*/
async sendChatMessage(chatId: string, sendMessageDto: SendMessageBodyDto, request: Request) {
const config = JwtForwardingHelper.getAxiosConfig(request);
const url = `${this.comunidadServiceUrl}/chats/${chatId}/messages`;

try {
this.logger.log(`Forwarding POST request to: ${url}`);
const response = await firstValueFrom(
this.httpService.post(url, sendMessageDto, config),
);
return response.data;
} catch (error) {
this.logger.error(`Error forwarding request to comunidad service`, error);
throw error;
}
}

/**
* Proxy para eliminar un chat
*/
async deleteChat(chatId: string, request: Request) {
const config = JwtForwardingHelper.getAxiosConfig(request);
const url = `${this.comunidadServiceUrl}/chats/${chatId}`;

try {
this.logger.log(`Forwarding DELETE request to: ${url}`);
const response = await firstValueFrom(
this.httpService.delete(url, config),
);
return response.data;
} catch (error) {
this.logger.error(`Error forwarding request to comunidad service`, error);
throw error;
}
}

/**
* Proxy para obtener threads
*/
Expand Down
25 changes: 25 additions & 0 deletions src/comunidad/dto/create-group.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { IsArray, IsEmail, IsNotEmpty, IsString, MaxLength, ArrayMinSize } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class CreateGroupDto {
@ApiProperty({
description: 'Nombre del grupo de chat',
example: 'Grupo de Estudio',
maxLength: 30,
})
@IsString()
@IsNotEmpty()
@MaxLength(30)
nombre: string;

@ApiProperty({
description: 'Lista de emails de los miembros del grupo',
example: ['usuario1@example.com', 'usuario2@example.com'],
type: [String],
isArray: true,
})
@IsArray()
@ArrayMinSize(1)
@IsEmail({}, { each: true })
emails: string[];
}
3 changes: 3 additions & 0 deletions src/comunidad/dto/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './create-group.dto';
export * from './send-message.dto';
export * from './send-message-body.dto';
12 changes: 12 additions & 0 deletions src/comunidad/dto/send-message-body.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { IsNotEmpty, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class SendMessageBodyDto {
@ApiProperty({
description: 'Contenido del mensaje',
example: 'Hola a todos!',
})
@IsString()
@IsNotEmpty()
contenido: string;
}
20 changes: 20 additions & 0 deletions src/comunidad/dto/send-message.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { IsNotEmpty, IsString, IsUUID } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class SendMessageDto {
@ApiProperty({
description: 'ID del grupo de chat',
example: '550e8400-e29b-41d4-a716-446655440000',
})
@IsUUID()
@IsNotEmpty()
grupoId: string;

@ApiProperty({
description: 'Contenido del mensaje',
example: 'Hola a todos!',
})
@IsString()
@IsNotEmpty()
contenido: string;
}
6 changes: 2 additions & 4 deletions src/user-management/user-management.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,9 @@ export class UserManagementController {
constructor(private readonly userManagementService: UserManagementService) {}

@Get()
@Roles(Role.ADMIN)
@ApiOperation({
@ApiOperation({
summary: 'Listar todos los usuarios (Paginado)',
description: 'Obtiene una lista paginada de todos los usuarios del sistema. Solo accesible para administradores.'
description: 'Obtiene una lista paginada de todos los usuarios del sistema.'
})
@ApiQuery({ name: 'page', required: false, description: 'Número de página', example: 1 })
@ApiQuery({ name: 'limit', required: false, description: 'Cantidad de registros por página', example: 10 })
Expand Down Expand Up @@ -62,7 +61,6 @@ export class UserManagementController {
}
})
@ApiResponse({ status: 401, description: 'No autorizado - Token JWT inválido o ausente' })
@ApiResponse({ status: 403, description: 'Prohibido - No tienes permisos de administrador' })
findAll(@Query() filter: FilterUsersDto, @Req() request: Request) {
return this.userManagementService.findAllWithFilters(filter, request);
}
Expand Down