feat: módulo de sugerencias (backend) + página pública /sugerencias (admin)

- Backend: POST /suggestions (público) + GET /suggestions (JWT admin)
- Admin: página pública /sugerencias con formulario de sugerencias
- schema.prisma: modelo suggestions
- AuthGuard + Sidebar: /sugerencias como ruta pública

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-06-27 19:05:58 -05:00
co-authored by Claude Sonnet 4.6
parent 4e932c2347
commit 42d41eb199
9 changed files with 176 additions and 2 deletions
+2
View File
@@ -13,6 +13,7 @@ import { ProfessionsModule } from './professions/professions.module';
import { StorageModule } from './storage/storage.module';
import { NotificationsModule } from './notifications/notifications.module';
import { SmsModule } from './sms/sms.module';
import { SuggestionsModule } from './suggestions/suggestions.module';
@Module({
imports: [
@@ -30,6 +31,7 @@ import { SmsModule } from './sms/sms.module';
StorageModule,
NotificationsModule,
SmsModule,
SuggestionsModule,
],
})
export class AppModule {}
@@ -0,0 +1,11 @@
import { IsString, IsOptional, MinLength } from 'class-validator';
export class CreateSuggestionDto {
@IsString()
@IsOptional()
name?: string;
@IsString()
@MinLength(1)
message: string;
}
@@ -0,0 +1,23 @@
import { Controller, Get, Post, Body, UseGuards, Query } from '@nestjs/common';
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
import { SuggestionsService } from './suggestions.service';
import { CreateSuggestionDto } from './dto/suggestion.dto';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
@ApiTags('Suggestions')
@Controller('suggestions')
export class SuggestionsController {
constructor(private suggestions: SuggestionsService) {}
@Post()
create(@Body() dto: CreateSuggestionDto) {
return this.suggestions.create(dto);
}
@Get()
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
findAll(@Query('page') page = '1', @Query('limit') limit = '50') {
return this.suggestions.findAll(+page, +limit);
}
}
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { SuggestionsService } from './suggestions.service';
import { SuggestionsController } from './suggestions.controller';
@Module({
providers: [SuggestionsService],
controllers: [SuggestionsController],
})
export class SuggestionsModule {}
@@ -0,0 +1,26 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
@Injectable()
export class SuggestionsService {
constructor(private prisma: PrismaService) {}
create(data: { name?: string; message: string }) {
return this.prisma.suggestions.create({ data });
}
findAll(page = 1, limit = 50) {
const skip = (page - 1) * limit;
return Promise.all([
this.prisma.suggestions.findMany({
skip,
take: limit,
orderBy: { created_at: 'desc' },
}),
this.prisma.suggestions.count(),
]).then(([data, total]) => ({
data,
meta: { total, page, limit, totalPages: Math.ceil(total / limit) || 1 },
}));
}
}