Proyecto Final - IngenierΓa de Software II
Universidad Nacional de San AgustΓn de Arequipa
- Equipo de Trabajo
- PropΓ³sito del Proyecto
- Funcionalidades de Alto Nivel
- Modelo de Dominio
- VisiΓ³n General de Arquitectura
- Servicios REST Disponibles
- Pipeline CI/CD
- InstalaciΓ³n y EjecuciΓ³n
- Capturas de Pantalla
- Huayhua Carlos, Lenin
- Lizarve Mamani, Johan
- Mamani Yucra, Edilson
FOROEPCC es una plataforma web tipo foro acadΓ©mico diseΓ±ada especΓficamente para estudiantes de la Escuela Profesional de Ciencia de la ComputaciΓ³n (EPCC) de la UNSA. El sistema permite a los estudiantes:
- Compartir conocimiento mediante publicaciones y respuestas.
- Resolver dudas acadΓ©micas de forma colaborativa.
- Interactuar con otros estudiantes a travΓ©s de comentarios y votos.
- Buscar informaciΓ³n utilizando un motor de bΓΊsqueda integrado.
- Implementar un sistema de autenticaciΓ³n seguro con JWT.
- Desarrollar un CRUD completo para posts, respuestas y comentarios.
- Aplicar prΓ‘cticas de Domain-Driven Design (DDD) y Clean Architecture.
- Establecer un pipeline CI/CD completo con Jenkins.
- Garantizar la calidad del cΓ³digo mediante anΓ‘lisis estΓ‘tico y pruebas automatizadas.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SISTEMA FOROEPCC β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββ β
β β Usuario β β
β β AnΓ³nimo ββββββββ¬βββΊ Registrarse β
β βββββββββββ β β
β ββββΊ Ver Posts PΓΊblicos β
β β
β βββββββββββ β
β β Usuario ββββββββ¬βββΊ Iniciar SesiΓ³n β
β βRegistradoβ ββββΊ Crear Post β
β βββββββββββ ββββΊ Responder Post β
β ββββΊ Comentar Respuesta β
β ββββΊ Buscar Posts β
β ββββΊ Ver Detalles de Post β
β ββββΊ Editar Perfil β
β ββββΊ Cerrar SesiΓ³n β
β β
β βββββββββββ β
β β Admin ββββββββ¬βββΊ Gestionar Usuarios β
β βββββββββββ ββββΊ Moderar Contenido β
β ββββΊ Ver EstadΓsticas β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| MΓ³dulo | Funcionalidad | DescripciΓ³n |
|---|---|---|
| Auth | Registro | CreaciΓ³n de cuenta con validaciΓ³n de datos |
| Auth | Login/Logout | AutenticaciΓ³n mediante JWT |
| Post | CRUD Posts | Crear, leer, actualizar y eliminar publicaciones |
| Post | Respuestas | Sistema de respuestas a posts |
| Post | Comentarios | Comentarios anidados en respuestas |
| Search | BΓΊsqueda | Motor de bΓΊsqueda full-text con Hibernate Search |
| User | Perfil | GestiΓ³n de informaciΓ³n del usuario |
| MΓ³dulo | Responsabilidad | Entidades |
|---|---|---|
| auth | AutenticaciΓ³n y autorizaciΓ³n (JWT) | ForoUser, Role, Person |
| post | GestiΓ³n de publicaciones, respuestas y comentarios | Post, Entry, Answer, Comment |
| user | GestiΓ³n de perfiles de usuario | ForoUser, Person |
| Carpeta | Responsabilidad |
|---|---|
| config | Configuraciones de Spring Security, WebSocket, CORS |
| dto | Data Transfer Objects compartidos |
| exceptions | Manejadores globales de excepciones |
| shared | Utilidades y componentes transversales |
El proyecto sigue los principios de Domain-Driven Design (DDD) combinados con Clean Architecture, organizando el cΓ³digo en capas bien definidas:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CAPA DE PRESENTACIΓN β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Controllers β β DTOs β β Responses β β
β ββββββββ¬βββββββ βββββββββββββββ βββββββββββββββ β
βββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βΌ CAPA DE APLICACIΓN β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Services β β Interfaces β β Mappers β β
β ββββββββ¬βββββββ βββββββββββββββ βββββββββββββββ β
βββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βΌ CAPA DE DOMINIO β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Entities β β Value β β Domain β β
β β (Modelos) β β Objects β β Events β β
β ββββββββ¬βββββββ βββββββββββββββ βββββββββββββββ β
βββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βΌ CAPA DE INFRAESTRUCTURA β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β βRepositories β β Security β β Config β β
β β (JPA) β β (JWT) β β (Spring) β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
backend/
βββ src/main/java/com/app/
β βββ modules/
β β βββ auth/
β β β βββ controller/ # AuthController
β β β βββ dto/ # LoginDTO, SignupDTO, TokenDTO
β β β βββ model/ # ForoUser, Role, Person
β β β βββ repository/ # UserRepository, RoleRepository
β β β βββ service/ # UserService, JwtService
β β β
β β βββ post/
β β β βββ controller/ # PostController, AnswerController, CommentController
β β β βββ dto/ # PostDTO, AnswerDTO, CommentDTO
β β β βββ model/ # Post, Entry, Answer, Comment
β β β βββ repository/ # PostRepository, AnswerRepository
β β β βββ service/ # PostService, AnswerService, CommentService
β β β
β β βββ search/
β β βββ controller/ # SearchController
β β βββ service/ # SearchService (Hibernate Search)
β β
β βββ shared/
β β βββ config/ # SecurityConfig, WebConfig
β β βββ exception/ # GlobalExceptionHandler
β β βββ utils/ # JwtUtils, ValidationUtils
β β
β βββ BackendApplication.java
β
βββ src/test/java/com/app/
β βββ modules/post/
β β βββ controller/ # Tests unitarios de controllers
β β βββ functional/ # Tests funcionales de integraciΓ³n
β β
β βββ security/ # Tests de seguridad y autorizaciΓ³n
β
βββ src/gatling/java/simulations/ # Tests de rendimiento
βββ LoginLoadSimulation.java
βββ PostReadLoadSimulation.java
βββ SearchLoadSimulation.java
PropΓ³sito: GestiΓ³n de registro, inicio de sesiΓ³n y tokens JWT.
| MΓ©todo | Endpoint | DescripciΓ³n | ParΓ‘metros |
|---|---|---|---|
POST |
/auth/signup |
Registrar nuevo usuario | SignupFieldsDTO (body) |
POST |
/auth/signin |
Iniciar sesiΓ³n | LoginRequestDTO (body) |
GET |
/auth/hello |
Verificar estado del servicio | - |
Modelos Involucrados:
// SignupFieldsDTO
{
"username": "string",
"password": "string",
"email": "string",
"firstName": "string",
"lastName": "string"
}
// LoginRequestDTO
{
"username": "string",
"password": "string"
}
// TokenResponseDTO
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6..."
}PropΓ³sito: CRUD completo de publicaciones del foro.
| MΓ©todo | Endpoint | DescripciΓ³n | Auth |
|---|---|---|---|
POST |
/post/create |
Crear nueva publicaciΓ³n | β JWT |
GET |
/post/ultimatePost |
Obtener posts recientes | β PΓΊblico |
GET |
/post/details/{id} |
Ver detalles de un post | β PΓΊblico |
Modelos Involucrados:
// CreatePostDTO
{
"title": "string",
"content": "string",
"image": "string (opcional)"
}
// PostResponseDTO
{
"id": 1,
"title": "string",
"content": "string",
"authorUsername": "string",
"views": 0,
"answers": 0,
"createdAt": "2026-01-14T00:00:00Z"
}PropΓ³sito: GestiΓ³n de respuestas a publicaciones.
| MΓ©todo | Endpoint | DescripciΓ³n | Auth |
|---|---|---|---|
POST |
/answer/create |
Crear respuesta a post | β JWT |
GET |
/answer/post/{postId} |
Obtener respuestas de un post | β PΓΊblico |
PropΓ³sito: GestiΓ³n de comentarios en respuestas.
| MΓ©todo | Endpoint | DescripciΓ³n | Auth |
|---|---|---|---|
POST |
/comment/create |
Crear comentario | β JWT |
GET |
/comment/answer/{answerId} |
Obtener comentarios | β PΓΊblico |
PropΓ³sito: Motor de bΓΊsqueda full-text sobre posts.
| MΓ©todo | Endpoint | DescripciΓ³n | ParΓ‘metros |
|---|---|---|---|
GET |
/search |
Buscar posts | query (string) |
El proyecto implementa un pipeline de IntegraciΓ³n y Entrega Continua utilizando Jenkins, activado automΓ‘ticamente mediante webhooks de GitHub.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PIPELINE CI/CD β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β β Checkout βββββΊβ Build βββββΊβ SonarQubeβββββΊβ Unit β β
β β SCM β β (Gradle) β β Analysis β β Tests β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β βΌ β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β βFunctionalβββββΊβ Security βββββΊβ Perf βββββΊβ Package β β
β β Tests β β Tests β β Tests β β (JAR) β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Herramienta: Gradle 8.11
- Comando:
./gradlew clean assemble -x test - DescripciΓ³n: Compila el cΓ³digo fuente y genera los artefactos sin ejecutar tests.
- Herramienta: SonarQube + sonar-scanner
- Comando:
./gradlew sonar - MΓ©tricas Analizadas:
- Code Smells
- Vulnerabilidades de seguridad
- Cobertura de cΓ³digo
- DuplicaciΓ³n de cΓ³digo
- Complejidad ciclomΓ‘tica
- Framework: JUnit 5 + Mockito
- Comando:
./gradlew unitTest - Cobertura: Controllers, Services, Repositories
- Ejemplos:
AnswerControllerTest.javaCommentControllerTest.javaPostControllerTest.java
- Framework: Spring Boot Test + MockMvc
- Comando:
./gradlew functionalTest - DescripciΓ³n: Pruebas de integraciΓ³n end-to-end.
- Ejemplos:
AuthFunctionalTest.java- Flujo de registro de usuariosPostFunctionalTest.java- Flujo de creaciΓ³n de posts
public class AnswerControllerTest extends BaseIntegrationTest {
@MockBean
private IAnswerService answerService;
@Test
@WithMockUser(username = "user", roles = { "USER" })
void testCreateAnswerSuccess() throws Exception {
CreateAnswerFieldsDTO fields = new CreateAnswerFieldsDTO(1L, "This is an answer");
Person person = Person.builder().firstName("John").lastName("Doe").build();
ForoUser user = ForoUser.builder().id(2L).username("user").person(person).build();
Post post = Post.builder().id(1L).title("Test Post").build();
Entry entry = Entry.builder()
.id(10L)
.content("This is an answer")
.user(user)
.createdAt(LocalDateTime.now())
.upVotes(0)
.downVotes(0)
.build();
Answer answer = Answer.builder()
.id(100L)
.entry(entry)
.post(post)
.build();
when(answerService.createAnswer(anyLong(), anyString())).thenReturn(answer);
mockMvc.perform(post("/answer")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(fields)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.id").value(100))
.andExpect(jsonPath("$.content").value("This is an answer"))
.andExpect(jsonPath("$.postId").value(1));
}
@Test
void testCreateAnswerUnauthorized() throws Exception {
CreateAnswerFieldsDTO fields = new CreateAnswerFieldsDTO(1L, "This is an answer");
mockMvc.perform(post("/answer")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(fields)))
.andExpect(status().isUnauthorized()); // Assuming 401/403 behavior
}
}- Framework: Spring Security Test + OWASP Dependency Check
- Comandos:
./gradlew securityTest- Tests de autorizaciΓ³n./gradlew dependencyCheckAnalyze- AnΓ‘lisis de vulnerabilidades CVE
- Ejemplos:
AuthorizationSecurityTest.java- VerificaciΓ³n de endpoints protegidos
- Framework: Gatling (Java DSL)
- Comando:
./gradlew gatlingRun - Simulaciones:
SimulaciΓ³n DescripciΓ³n Usuarios Virtuales LoginLoadSimulationStress test de login 50 usuarios/seg PostReadLoadSimulationCarga de lectura de posts 100 usuarios/seg SearchLoadSimulationEstrΓ©s del motor de bΓΊsqueda 30 usuarios/seg
- Herramienta: Gradle + Spring Boot
- Comando:
./gradlew bootJar - Artefacto:
backend-0.0.1-SNAPSHOT.jar
El proyecto utiliza GitHub Issues y GitHub Projects para el seguimiento de:
- π Bugs: Errores identificados durante desarrollo y testing.
- β¨ Features: Nuevas funcionalidades solicitadas.
- π Tasks: Tareas tΓ©cnicas y de documentaciΓ³n.
- π§ Improvements: Mejoras de cΓ³digo existente.
- Java 21 (JDK)
- Node.js 18+ (para el frontend)
- PostgreSQL 15
- Docker Desktop (opcional, para contenedores)
- Jenkins (para CI/CD)
cd backend
./gradlew bootRunEl servidor estarΓ‘ disponible en: http://localhost:8080
cd frontend
npm install
npm run devLa aplicaciΓ³n estarΓ‘ disponible en: http://localhost:3000
FOROEPCC Β© 2026 - Todos los derechos reservados
Desarrollado con β€οΈ por el equipo FOROEPCC
